From 2b2d45f061a737203583def6907cb139ff553fab Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Tue, 7 Apr 2009 10:56:00 +0200 Subject: Initial commit --- Makefile.am | 0 bootstrap | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ config.ac | 0 3 files changed, 51 insertions(+) create mode 100644 Makefile.am create mode 100755 bootstrap create mode 100644 config.ac diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..e69de29 diff --git a/bootstrap b/bootstrap new file mode 100755 index 0000000..e520834 --- /dev/null +++ b/bootstrap @@ -0,0 +1,51 @@ +#! /bin/bash + +DIE=0 +touch README NEWS CHANGELOG +(autoconf --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "You must have autoconf installed." + DIE=1 +} + +# libtool --version check not done... + +(automake --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "You must have automake installed." + DIE=1 +} + +if test "$DIE" -eq 1; then + exit 1 +fi + +echo Removing old files... +rm -fr config.cache autom4te*.cache config.h config.status aclocal.m4 config.cache config.log + +if test ! -d config; then + mkdir config +fi +echo "aclocal -I config" +aclocal -I config +if test $? -ne 0; then + exit 1 +fi +echo "autoheader" +autoheader +if test $? -ne 0; then + exit 1 +fi + +echo "libtoolize --automake" +libtoolize --automake +automake --foreign --add-missing +if test $? -ne 0; then + exit 1 +fi + +echo "autoconf" +autoconf +echo "BOOTSTRAP complete" + +#(cd gsm-tvoid ; ./bootstrap) \ No newline at end of file diff --git a/config.ac b/config.ac new file mode 100644 index 0000000..e69de29 -- cgit v1.2.3 From 39a50c763240da578a05a6b651776804786d813a Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Tue, 7 Apr 2009 12:47:18 +0200 Subject: Added files from gr-howto-write-a-block --- .gitignore | 22 + Makefile.am | 9 + Makefile.common | 43 + bootstrap | 2 +- config.ac | 0 config/Makefile.am | 68 + config/bnv_have_qt.m4 | 404 ++ config/cppunit.m4 | 80 + config/gr_boost.m4 | 111 + config/gr_check_createfilemapping.m4 | 52 + config/gr_check_mc4020.m4 | 37 + config/gr_check_shm_open.m4 | 29 + config/gr_check_usrp.m4 | 32 + config/gr_doxygen.m4 | 59 + config/gr_gprof.m4 | 72 + config/gr_libgnuradio_core_extra_ldflags.m4 | 40 + config/gr_no_undefined.m4 | 44 + config/gr_omnithread.m4 | 51 + config/gr_pwin32.m4 | 146 + config/gr_python.m4 | 111 + config/gr_require_mc4020.m4 | 33 + config/gr_scripting.m4 | 30 + config/gr_set_md_cpu.m4 | 44 + config/gr_swig.m4 | 85 + config/gr_sysv_shm.m4 | 36 + config/gr_x86_64.m4 | 39 + config/lf_cxx.m4 | 121 + config/lf_warnings.m4 | 128 + config/lf_x11.m4 | 39 + config/libtool.m4 | 7309 +++++++++++++++++++++++++++ config/ltoptions.m4 | 368 ++ config/ltsugar.m4 | 123 + config/ltversion.m4 | 23 + config/lt~obsolete.m4 | 92 + config/mkstemp.m4 | 89 + config/onceonly.m4 | 63 + config/pkg.m4 | 68 + config/usrp_fusb_tech.m4 | 56 + config/usrp_libusb.m4 | 43 + config/usrp_sdcc.m4 | 67 + configure.ac | 106 + src/Makefile.am | 22 + src/lib/Makefile.am | 95 + src/lib/gsm_receiver.h | 78 + src/lib/gsm_receiver.i | 44 + src/lib/gsm_receiver_cf.cc | 93 + src/lib/gsm_receiver_cf.h | 74 + 47 files changed, 10779 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 Makefile.common delete mode 100644 config.ac create mode 100644 config/Makefile.am create mode 100644 config/bnv_have_qt.m4 create mode 100644 config/cppunit.m4 create mode 100644 config/gr_boost.m4 create mode 100644 config/gr_check_createfilemapping.m4 create mode 100644 config/gr_check_mc4020.m4 create mode 100644 config/gr_check_shm_open.m4 create mode 100644 config/gr_check_usrp.m4 create mode 100644 config/gr_doxygen.m4 create mode 100644 config/gr_gprof.m4 create mode 100644 config/gr_libgnuradio_core_extra_ldflags.m4 create mode 100644 config/gr_no_undefined.m4 create mode 100644 config/gr_omnithread.m4 create mode 100644 config/gr_pwin32.m4 create mode 100644 config/gr_python.m4 create mode 100644 config/gr_require_mc4020.m4 create mode 100644 config/gr_scripting.m4 create mode 100644 config/gr_set_md_cpu.m4 create mode 100644 config/gr_swig.m4 create mode 100644 config/gr_sysv_shm.m4 create mode 100644 config/gr_x86_64.m4 create mode 100644 config/lf_cxx.m4 create mode 100644 config/lf_warnings.m4 create mode 100644 config/lf_x11.m4 create mode 100644 config/libtool.m4 create mode 100644 config/ltoptions.m4 create mode 100644 config/ltsugar.m4 create mode 100644 config/ltversion.m4 create mode 100644 config/lt~obsolete.m4 create mode 100644 config/mkstemp.m4 create mode 100644 config/onceonly.m4 create mode 100644 config/pkg.m4 create mode 100644 config/usrp_fusb_tech.m4 create mode 100644 config/usrp_libusb.m4 create mode 100644 config/usrp_sdcc.m4 create mode 100644 configure.ac create mode 100644 src/Makefile.am create mode 100644 src/lib/Makefile.am create mode 100644 src/lib/gsm_receiver.h create mode 100644 src/lib/gsm_receiver.i create mode 100644 src/lib/gsm_receiver_cf.cc create mode 100644 src/lib/gsm_receiver_cf.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..58a5903 --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +configure +Makefile.in +config.log +config.h +config.sub +config.guess +ltmain.sh +Makefile +config.status +stamp-h1 +config.h.in +autom4te.cache +libtool +missing +aclocal.m4 +install-sh +depcomp +compile +build +*~ +autom4te.cache +debug \ No newline at end of file diff --git a/Makefile.am b/Makefile.am index e69de29..e659491 100644 --- a/Makefile.am +++ b/Makefile.am @@ -0,0 +1,9 @@ +include $(top_srcdir)/Makefile.common + +SUBDIRS = src config +DIST_SUBDIRS = src config +EXTRA_DIST = bootstrap configure config.h.in + +#nowe rzeczy +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = diff --git a/Makefile.common b/Makefile.common new file mode 100644 index 0000000..6b62f25 --- /dev/null +++ b/Makefile.common @@ -0,0 +1,43 @@ +# -*- Makefile -*- +# +# Copyright 2004,2006 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. +# + +# includes +grincludedir = $(includedir)/gnuradio + +# swig includes +swigincludedir = $(grincludedir)/swig + +# Install this stuff in the appropriate subdirectory +# This usually ends up at: +# ${prefix}/lib/python${python_version}/site-packages/gnuradio + +grpythondir = $(pythondir)/gnuradio +grpyexecdir = $(pyexecdir)/gnuradio + +# swig flags +SWIGPYTHONFLAGS = -fvirtual -python -modern +SWIGGRFLAGS = -I$(GNURADIO_CORE_INCLUDEDIR)/swig -I$(GNURADIO_CORE_INCLUDEDIR) + +# Don't assume that make predefines $(RM), because BSD make does +# not. We define it now in configure.ac using AM_PATH_PROG, but now +# here have to add a -f to be like GNU make. +RM=$(RM_PROG) -f diff --git a/bootstrap b/bootstrap index e520834..3ef4692 100755 --- a/bootstrap +++ b/bootstrap @@ -39,7 +39,7 @@ fi echo "libtoolize --automake" libtoolize --automake -automake --foreign --add-missing +automake --add-missing -c -f -Wno-portability if test $? -ne 0; then exit 1 fi diff --git a/config.ac b/config.ac deleted file mode 100644 index e69de29..0000000 diff --git a/config/Makefile.am b/config/Makefile.am new file mode 100644 index 0000000..0b82ea3 --- /dev/null +++ b/config/Makefile.am @@ -0,0 +1,68 @@ +# +# Copyright 2001 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 + +# Install m4 macros in this directory +m4datadir = $(datadir)/aclocal + +# List your m4 macros here +m4macros = \ + bnv_have_qt.m4 \ + cppunit.m4 \ + gr_boost.m4 \ + gr_check_createfilemapping.m4 \ + gr_check_usrp.m4 \ + gr_check_mc4020.m4 \ + gr_check_shm_open.m4 \ + gr_doxygen.m4 \ + gr_gprof.m4 \ + gr_libgnuradio_core_extra_ldflags.m4 \ + gr_no_undefined.m4 \ + gr_omnithread.m4 \ + gr_pwin32.m4 \ + gr_python.m4 \ + gr_require_mc4020.m4 \ + gr_scripting.m4 \ + gr_set_md_cpu.m4 \ + gr_swig.m4 \ + gr_sysv_shm.m4 \ + gr_x86_64.m4 \ + lf_cxx.m4 \ + lf_warnings.m4 \ + lf_x11.m4 \ + mkstemp.m4 \ + onceonly.m4 \ + pkg.m4 \ + usrp_fusb_tech.m4 \ + usrp_libusb.m4 \ + usrp_sdcc.m4 + + +# Don't install m4 macros anymore +# m4data_DATA = $(m4macros) + +EXTRA_DIST = $(m4macros) \ + libtool.m4 \ + lt~obsolete.m4 \ + ltsugar.m4 \ + ltversion.m4 \ + ltoptions.m4 diff --git a/config/bnv_have_qt.m4 b/config/bnv_have_qt.m4 new file mode 100644 index 0000000..1469bfb --- /dev/null +++ b/config/bnv_have_qt.m4 @@ -0,0 +1,404 @@ +dnl Available from the GNU Autoconf Macro Archive at: +dnl http://www.gnu.org/software/ac-archive/htmldoc/bnv_have_qt.html +dnl +AC_DEFUN([BNV_HAVE_QT], +[ + dnl THANKS! This code includes bug fixes by: + dnl Tim McClarren. + + AC_REQUIRE([AC_PROG_CXX]) + AC_REQUIRE([AC_PATH_X]) + AC_REQUIRE([AC_PATH_XTRA]) + + AC_MSG_CHECKING(for Qt) + + AC_ARG_WITH([Qt-dir], + [ --with-Qt-dir=DIR DIR is equal to \$QTDIR if you have followed the + installation instructions of Trolltech. Header + files are in DIR/include, binary utilities are + in DIR/bin and the library is in DIR/lib]) + AC_ARG_WITH([Qt-include-dir], + [ --with-Qt-include-dir=DIR + Qt header files are in DIR]) + AC_ARG_WITH([Qt-bin-dir], + [ --with-Qt-bin-dir=DIR Qt utilities such as moc and uic are in DIR]) + AC_ARG_WITH([Qt-lib-dir], + [ --with-Qt-lib-dir=DIR The Qt library is in DIR]) + AC_ARG_WITH([Qt-lib], + [ --with-Qt-lib=LIB Use -lLIB to link with the Qt library]) + if test x"$with_Qt_dir" = x"no" || + test x"$with_Qt_include-dir" = x"no" || + test x"$with_Qt_bin_dir" = x"no" || + test x"$with_Qt_lib_dir" = x"no" || + test x"$with_Qt_lib" = x"no"; then + # user disabled Qt. Leave cache alone. + have_qt="User disabled Qt." + else + # "yes" is a bogus option + if test x"$with_Qt_dir" = xyes; then + with_Qt_dir= + fi + if test x"$with_Qt_include_dir" = xyes; then + with_Qt_include_dir= + fi + if test x"$with_Qt_bin_dir" = xyes; then + with_Qt_bin_dir= + fi + if test x"$with_Qt_lib_dir" = xyes; then + with_Qt_lib_dir= + fi + if test x"$with_Qt_lib" = xyes; then + with_Qt_lib= + fi + # No Qt unless we discover otherwise + have_qt=no + # Check whether we are requested to link with a specific version + if test x"$with_Qt_lib" != x; then + bnv_qt_lib="$with_Qt_lib" + fi + # Check whether we were supplied with an answer already + if test x"$with_Qt_dir" != x; then + have_qt=yes + bnv_qt_dir="$with_Qt_dir" + bnv_qt_include_dir="$with_Qt_dir/include" + bnv_qt_bin_dir="$with_Qt_dir/bin" + bnv_qt_lib_dir="$with_Qt_dir/lib" + # Only search for the lib if the user did not define one already + if test x"$bnv_qt_lib" = x; then + bnv_qt_lib="`ls $bnv_qt_lib_dir/libqt* | sed -n 1p | + sed s@$bnv_qt_lib_dir/lib@@ | [sed s@[.].*@@]`" + fi + bnv_qt_LIBS="-L$bnv_qt_lib_dir -l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" + else + # Use cached value or do search, starting with suggestions from + # the command line + AC_CACHE_VAL(bnv_cv_have_qt, + [ + # We are not given a solution and there is no cached value. + bnv_qt_dir=NO + bnv_qt_include_dir=NO + bnv_qt_lib_dir=NO + if test x"$bnv_qt_lib" = x; then + bnv_qt_lib=NO + fi + BNV_PATH_QT_DIRECT + if test "$bnv_qt_dir" = NO || + test "$bnv_qt_include_dir" = NO || + test "$bnv_qt_lib_dir" = NO || + test "$bnv_qt_lib" = NO; then + # Problem with finding complete Qt. Cache the known absence of Qt. + bnv_cv_have_qt="have_qt=no" + else + # Record where we found Qt for the cache. + bnv_cv_have_qt="have_qt=yes \ + bnv_qt_dir=$bnv_qt_dir \ + bnv_qt_include_dir=$bnv_qt_include_dir \ + bnv_qt_bin_dir=$bnv_qt_bin_dir \ + bnv_qt_LIBS=\"$bnv_qt_LIBS\"" + fi + ])dnl + eval "$bnv_cv_have_qt" + fi # all $bnv_qt_* are set + fi # $have_qt reflects the system status + if test x"$have_qt" = xyes; then + QT_CXXFLAGS="-I$bnv_qt_include_dir" + QT_DIR="$bnv_qt_dir" + QT_LIBS="$bnv_qt_LIBS" + # If bnv_qt_dir is defined, utilities are expected to be in the + # bin subdirectory + if test x"$bnv_qt_dir" != x; then + if test -x "$bnv_qt_dir/bin/uic"; then + QT_UIC="$bnv_qt_dir/bin/uic" + else + # Old versions of Qt don't have uic + QT_UIC= + fi + QT_MOC="$bnv_qt_dir/bin/moc" + else + # Or maybe we are told where to look for the utilities + if test x"$bnv_qt_bin_dir" != x; then + if test -x "$bnv_qt_bin_dir/uic"; then + QT_UIC="$bnv_qt_bin_dir/uic" + else + # Old versions of Qt don't have uic + QT_UIC= + fi + QT_MOC="$bnv_qt_bin_dir/moc" + else + # Last possibility is that they are in $PATH + QT_UIC="`which uic`" + QT_MOC="`which moc`" + fi + fi + # All variables are defined, report the result + AC_MSG_RESULT([$have_qt: + QT_CXXFLAGS=$QT_CXXFLAGS + QT_DIR=$QT_DIR + QT_LIBS=$QT_LIBS + QT_UIC=$QT_UIC + QT_MOC=$QT_MOC]) + else + # Qt was not found + QT_CXXFLAGS= + QT_DIR= + QT_LIBS= + QT_UIC= + QT_MOC= + AC_MSG_RESULT($have_qt) + fi + AC_SUBST(QT_CXXFLAGS) + AC_SUBST(QT_DIR) + AC_SUBST(QT_LIBS) + AC_SUBST(QT_UIC) + AC_SUBST(QT_MOC) + + #### Being paranoid: + if test x"$have_qt" = xyes; then + AC_MSG_CHECKING(correct functioning of Qt installation) + AC_CACHE_VAL(bnv_cv_qt_test_result, + [ + cat > bnv_qt_test.h << EOF +#include +class Test : public QObject +{ +Q_OBJECT +public: + Test() {} + ~Test() {} +public slots: + void receive() {} +signals: + void send(); +}; +EOF + + cat > bnv_qt_main.$ac_ext << EOF +#include "bnv_qt_test.h" +#include +int main( int argc, char **argv ) +{ + QApplication app( argc, argv ); + Test t; + QObject::connect( &t, SIGNAL(send()), &t, SLOT(receive()) ); +} +EOF + + bnv_cv_qt_test_result="failure" + bnv_try_1="$QT_MOC bnv_qt_test.h -o moc_bnv_qt_test.$ac_ext >/dev/null 2>bnv_qt_test_1.out" + AC_TRY_EVAL(bnv_try_1) + bnv_err_1=`grep -v '^ *+' bnv_qt_test_1.out | grep -v "^bnv_qt_test.h\$"` + if test x"$bnv_err_1" != x; then + echo "$bnv_err_1" >&AC_FD_CC + echo "configure: could not run $QT_MOC on:" >&AC_FD_CC + cat bnv_qt_test.h >&AC_FD_CC + else + bnv_try_2="$CXX $QT_CXXFLAGS -c $CXXFLAGS -o moc_bnv_qt_test.o moc_bnv_qt_test.$ac_ext >/dev/null 2>bnv_qt_test_2.out" + AC_TRY_EVAL(bnv_try_2) + bnv_err_2=`grep -v '^ *+' bnv_qt_test_2.out | grep -v "^bnv_qt_test.{$ac_ext}\$"` + if test x"$bnv_err_2" != x; then + echo "$bnv_err_2" >&AC_FD_CC + echo "configure: could not compile:" >&AC_FD_CC + cat bnv_qt_test.$ac_ext >&AC_FD_CC + else + bnv_try_3="$CXX $QT_CXXFLAGS -c $CXXFLAGS -o bnv_qt_main.o bnv_qt_main.$ac_ext >/dev/null 2>bnv_qt_test_3.out" + AC_TRY_EVAL(bnv_try_3) + bnv_err_3=`grep -v '^ *+' bnv_qt_test_3.out | grep -v "^bnv_qt_main.{$ac_ext}\$"` + if test x"$bnv_err_3" != x; then + echo "$bnv_err_3" >&AC_FD_CC + echo "configure: could not compile:" >&AC_FD_CC + cat bnv_qt_main.$ac_ext >&AC_FD_CC + else + bnv_try_4="$CXX $QT_LIBS $LIBS -o bnv_qt_main bnv_qt_main.o moc_bnv_qt_test.o >/dev/null 2>bnv_qt_test_4.out" + AC_TRY_EVAL(bnv_try_4) + bnv_err_4=`grep -v '^ *+' bnv_qt_test_4.out` + if test x"$bnv_err_4" != x; then + echo "$bnv_err_4" >&AC_FD_CC + else + bnv_cv_qt_test_result="success" + fi + fi + fi + fi + ])dnl AC_CACHE_VAL bnv_cv_qt_test_result + AC_MSG_RESULT([$bnv_cv_qt_test_result]); + if test x"$bnv_cv_qt_test_result" = "xfailure"; then + # working Qt was not found + QT_CXXFLAGS= + QT_DIR= + QT_LIBS= + QT_UIC= + QT_MOC= + have_qt=no + AC_MSG_WARN([Failed to find matching components of a complete + Qt installation. Try using more options, + see ./configure --help.]) + fi + + rm -f bnv_qt_test.h moc_bnv_qt_test.$ac_ext moc_bnv_qt_test.o \ + bnv_qt_main.$ac_ext bnv_qt_main.o bnv_qt_main \ + bnv_qt_test_1.out bnv_qt_test_2.out bnv_qt_test_3.out bnv_qt_test_4.out + fi +]) + +dnl Internal subroutine of BNV_HAVE_QT +dnl Set bnv_qt_dir bnv_qt_include_dir bnv_qt_bin_dir bnv_qt_lib_dir bnv_qt_lib +dnl Copyright 2001 Bastiaan N. Veelo +AC_DEFUN([BNV_PATH_QT_DIRECT], +[ + ## Binary utilities ## + if test x"$with_Qt_bin_dir" != x; then + bnv_qt_bin_dir=$with_Qt_bin_dir + fi + ## Look for header files ## + if test x"$with_Qt_include_dir" != x; then + bnv_qt_include_dir="$with_Qt_include_dir" + else + # The following header file is expected to define QT_VERSION. + qt_direct_test_header=qglobal.h + # Look for the header file in a standard set of common directories. + bnv_include_path_list=" + /usr/include + `ls -dr /usr/include/qt* 2>/dev/null` + `ls -dr /usr/lib/qt*/include 2>/dev/null` + `ls -dr /usr/local/qt*/include 2>/dev/null` + `ls -dr /opt/qt*/include 2>/dev/null` + " + for bnv_dir in $bnv_include_path_list; do + if test -r "$bnv_dir/$qt_direct_test_header"; then + bnv_dirs="$bnv_dirs $bnv_dir" + fi + done + # Now look for the newest in this list + bnv_prev_ver=0 + for bnv_dir in $bnv_dirs; do + bnv_this_ver=`egrep -w '#define QT_VERSION' $bnv_dir/$qt_direct_test_header | sed s/'#define QT_VERSION'//` + if expr $bnv_this_ver '>' $bnv_prev_ver > /dev/null; then + bnv_qt_include_dir=$bnv_dir + bnv_prev_ver=$bnv_this_ver + fi + done + fi dnl Found header files. + + # Are these headers located in a traditional Trolltech installation? + # That would be $bnv_qt_include_dir stripped from its last element: + bnv_possible_qt_dir=`dirname $bnv_qt_include_dir` + if test -x $bnv_possible_qt_dir/bin/moc && + ls $bnv_possible_qt_dir/lib/libqt* > /dev/null; then + # Then the rest is a piece of cake + bnv_qt_dir=$bnv_possible_qt_dir + bnv_qt_bin_dir="$bnv_qt_dir/bin" + bnv_qt_lib_dir="$bnv_qt_dir/lib" + # Only look for lib if the user did not supply it already + if test x"$bnv_qt_lib" = xNO; then + bnv_qt_lib="`ls $bnv_qt_lib_dir/libqt* | sed -n 1p | + sed s@$bnv_qt_lib_dir/lib@@ | [sed s@[.].*@@]`" + fi + bnv_qt_LIBS="-L$bnv_qt_lib_dir -l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" + else + # There is no valid definition for $QTDIR as Trolltech likes to see it + bnv_qt_dir= + ## Look for Qt library ## + if test x"$with_Qt_lib_dir" != x; then + bnv_qt_lib_dir="$with_Qt_lib_dir" + # Only look for lib if the user did not supply it already + if test x"$bnv_qt_lib" = xNO; then + bnv_qt_lib="`ls $bnv_qt_lib_dir/libqt* | sed -n 1p | + sed s@$bnv_qt_lib_dir/lib@@ | [sed s@[.].*@@]`" + fi + bnv_qt_LIBS="-L$bnv_qt_lib_dir -l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" + else + # Normally, when there is no traditional Trolltech installation, + # the library is installed in a place where the linker finds it + # automatically. + # If the user did not define the library name, try with qt + if test x"$bnv_qt_lib" = xNO; then + bnv_qt_lib=qt + fi + qt_direct_test_header=qapplication.h + qt_direct_test_main=" + int argc; + char ** argv; + QApplication app(argc,argv); + " + # See if we find the library without any special options. + # Don't add top $LIBS permanently yet + bnv_save_LIBS="$LIBS" + LIBS="-l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" + bnv_qt_LIBS="$LIBS" + bnv_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="-I$bnv_qt_include_dir" + AC_TRY_LINK([#include <$qt_direct_test_header>], + $qt_direct_test_main, + [ + # Success. + # We can link with no special library directory. + bnv_qt_lib_dir= + ], [ + # That did not work. Try the multi-threaded version + echo "Non-critical error, please neglect the above." >&AC_FD_CC + bnv_qt_lib=qt-mt + LIBS="-l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" + AC_TRY_LINK([#include <$qt_direct_test_header>], + $qt_direct_test_main, + [ + # Success. + # We can link with no special library directory. + bnv_qt_lib_dir= + ], [ + # That did not work. Try the OpenGL version + echo "Non-critical error, please neglect the above." >&AC_FD_CC + bnv_qt_lib=qt-gl + LIBS="-l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" + AC_TRY_LINK([#include <$qt_direct_test_header>], + $qt_direct_test_main, + [ + # Succes. + # We can link with no special library directory. + bnv_qt_lib_dir= + ], [ + # That did not work. Maybe a library version I don't know about? + echo "Non-critical error, please neglect the above." >&AC_FD_CC + # Look for some Qt lib in a standard set of common directories. + bnv_dir_list=" + `echo $bnv_qt_includes | sed ss/includess` + /lib + /usr/lib + /usr/local/lib + /opt/lib + `ls -dr /usr/lib/qt* 2>/dev/null` + `ls -dr /usr/local/qt* 2>/dev/null` + `ls -dr /opt/qt* 2>/dev/null` + " + for bnv_dir in $bnv_dir_list; do + if ls $bnv_dir/libqt*; then + # Gamble that it's the first one... + bnv_qt_lib="`ls $bnv_dir/libqt* | sed -n 1p | + sed s@$bnv_dir/lib@@ | sed s/[.].*//`" + bnv_qt_lib_dir="$bnv_dir" + break + fi + done + # Try with that one + LIBS="-l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" + AC_TRY_LINK([#include <$qt_direct_test_header>], + $qt_direct_test_main, + [ + # Succes. + # We can link with no special library directory. + bnv_qt_lib_dir= + ], [ + # Leave bnv_qt_lib_dir defined + ]) + ]) + ]) + ]) + if test x"$bnv_qt_lib_dir" != x; then + bnv_qt_LIBS="-l$bnv_qt_lib_dir $LIBS" + else + bnv_qt_LIBS="$LIBS" + fi + LIBS="$bnv_save_LIBS" + CXXFLAGS="$bnv_save_CXXFLAGS" + fi dnl $with_Qt_lib_dir was not given + fi dnl Done setting up for non-traditional Trolltech installation +]) diff --git a/config/cppunit.m4 b/config/cppunit.m4 new file mode 100644 index 0000000..0991d51 --- /dev/null +++ b/config/cppunit.m4 @@ -0,0 +1,80 @@ +dnl +dnl AM_PATH_CPPUNIT(MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +dnl +AC_DEFUN([AM_PATH_CPPUNIT], +[ + +AC_ARG_WITH(cppunit-prefix,[ --with-cppunit-prefix=PFX Prefix where CppUnit is installed (optional)], + cppunit_config_prefix="$withval", cppunit_config_prefix="") +AC_ARG_WITH(cppunit-exec-prefix,[ --with-cppunit-exec-prefix=PFX Exec prefix where CppUnit is installed (optional)], + cppunit_config_exec_prefix="$withval", cppunit_config_exec_prefix="") + + if test x$cppunit_config_exec_prefix != x ; then + cppunit_config_args="$cppunit_config_args --exec-prefix=$cppunit_config_exec_prefix" + if test x${CPPUNIT_CONFIG+set} != xset ; then + CPPUNIT_CONFIG=$cppunit_config_exec_prefix/bin/cppunit-config + fi + fi + if test x$cppunit_config_prefix != x ; then + cppunit_config_args="$cppunit_config_args --prefix=$cppunit_config_prefix" + if test x${CPPUNIT_CONFIG+set} != xset ; then + CPPUNIT_CONFIG=$cppunit_config_prefix/bin/cppunit-config + fi + fi + + AC_PATH_PROG(CPPUNIT_CONFIG, cppunit-config, no) + cppunit_version_min=$1 + + AC_MSG_CHECKING(for Cppunit - version >= $cppunit_version_min) + no_cppunit="" + if test "$CPPUNIT_CONFIG" = "no" ; then + no_cppunit=yes + else + CPPUNIT_CFLAGS=`$CPPUNIT_CONFIG --cflags` + CPPUNIT_LIBS=`$CPPUNIT_CONFIG --libs` + cppunit_version=`$CPPUNIT_CONFIG --version` + + cppunit_major_version=`echo $cppunit_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + cppunit_minor_version=`echo $cppunit_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + cppunit_micro_version=`echo $cppunit_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + + cppunit_major_min=`echo $cppunit_version_min | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + cppunit_minor_min=`echo $cppunit_version_min | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + cppunit_micro_min=`echo $cppunit_version_min | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + + cppunit_version_proper=`expr \ + $cppunit_major_version \> $cppunit_major_min \| \ + $cppunit_major_version \= $cppunit_major_min \& \ + $cppunit_minor_version \> $cppunit_minor_min \| \ + $cppunit_major_version \= $cppunit_major_min \& \ + $cppunit_minor_version \= $cppunit_minor_min \& \ + $cppunit_micro_version \>= $cppunit_micro_min ` + + if test "$cppunit_version_proper" = "1" ; then + AC_MSG_RESULT([$cppunit_major_version.$cppunit_minor_version.$cppunit_micro_version]) + else + AC_MSG_RESULT(no) + no_cppunit=yes + fi + fi + + if test "x$no_cppunit" = x ; then + ifelse([$2], , :, [$2]) + else + CPPUNIT_CFLAGS="" + CPPUNIT_LIBS="" + ifelse([$3], , :, [$3]) + fi + + AC_SUBST(CPPUNIT_CFLAGS) + AC_SUBST(CPPUNIT_LIBS) +]) + + + diff --git a/config/gr_boost.m4 b/config/gr_boost.m4 new file mode 100644 index 0000000..0664d36 --- /dev/null +++ b/config/gr_boost.m4 @@ -0,0 +1,111 @@ +dnl +dnl Copyright 2004,2005 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +dnl This tries to do the "right thing" to locate the boost include files. +dnl If the user explicitly specified --with-boost-include-dir= +dnl we believe them and use it. Otherwise, +dnl +dnl We look for boost/shared_ptr.hpp in the "normal places". That is, +dnl wherever AC_CHECK_HEADER looks. If the boost includes are in /usr/local/include +dnl this step will find them. +dnl +dnl Otherwise, we check to see if the boost stuff was installed in a version-specific +dnl directory under /usr/local/include. These look like: /usr/local/include/boost-1_33_1 +dnl If there's more than one version installed, we select the +dnl lexicographically greatest one. +dnl +dnl If none of these work, we bail. + +AC_DEFUN([GR_REQUIRE_BOOST_INCLUDES], +[ + AC_LANG_PUSH(C++) + gr_boost_include_dir= + AC_ARG_WITH([boost-include-dir], + AC_HELP_STRING([--with-boost-include-dir=], + [path to boost c++ include files]), + [ + # "yes" and "no" are bogus answers + if test x"$with_boost_include_dir" = xyes || + test x"$with_boost_include_dir" = xno; then + gr_boost_include_dir= + else + gr_boost_include_dir=$with_boost_include_dir + fi + ]) + echo "gr_boost_include_dir = $gr_boost_include_dir" + if test x$gr_boost_include_dir != x; then + # + # If the user specified a directory, then we use it + # + OLD_CPPFLAGS=$CPPFLAGS + CPPFLAGS="$CPPFLAGS -I$gr_boost_include_dir" + AC_CHECK_HEADER([boost/shared_ptr.hpp], + [BOOST_CFLAGS="-I$gr_boost_include_dir"], + [AC_MSG_ERROR( + [Failed to locate boost/shared_ptr.hpp. +Try using --with-boost-include-dir=, +E.g., --with-boost-include-dir=/usr/local/include/boost-1_33_1])]) + CPPFLAGS=$OLD_CPPFLAGS + else + # + # Otherwise we check in the default places + # + AC_CHECK_HEADER([boost/shared_ptr.hpp], + [BOOST_CFLAGS=""], + [ # Nope, look for latest version if any in $prefix/include/boost-* + + # Wipe out cached value. KLUDGE: AC should have API for this + unset AS_TR_SH([ac_cv_header_boost/shared_ptr.hpp]) + + boost_last_match(){ + #echo "boost_last_match: [$]*" + pattern="[$]1" + shift + if test "[$]pattern" = "[$]1" + then + LM='' + else + shift `expr [$]# - 1` + LM=[$]1 + fi + #echo "LM(1)='[$]LM'" + } + + pattern="/usr/local/include/boost-*" + boost_last_match "$pattern" $pattern + #echo "LM(2)='$LM'" + + OLD_CPPFLAGS=$CPP_FLAGS + CPPFLAGS="$CPPFLAGS -I$LM" + AC_CHECK_HEADER([boost/shared_ptr.hpp], + [BOOST_CFLAGS="-I$LM"], + [AC_MSG_ERROR( + [Failed to locate boost/shared_ptr.hpp. +Try using --with-boost-include-dir=, +E.g., --with-boost-include-dir=/usr/local/include/boost-1_33_1])]) + CPPFLAGS=$OLD_CPPFLAGS + ]) + + fi + unset boost_last_match LM + AC_LANG_POP + AC_SUBST(BOOST_CFLAGS) +]) diff --git a/config/gr_check_createfilemapping.m4 b/config/gr_check_createfilemapping.m4 new file mode 100644 index 0000000..5f9b4a4 --- /dev/null +++ b/config/gr_check_createfilemapping.m4 @@ -0,0 +1,52 @@ +dnl +dnl Copyright 2005 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. + +dnl AC_DEFUN([GR_CHECK_CREATEFILEMAPPING], +dnl [ +dnl AC_CHECK_FUNCS([CreateFileMapping]) +dnl ]) + +AC_DEFUN([GR_CHECK_CREATEFILEMAPPING],[ + AC_MSG_CHECKING([for CreateFileMapping function]) + AC_COMPILE_IFELSE([ +#include +int main (int argc, char **argv) +{ + HANDLE handle; + int size; + char seg_name[[1024]]; + handle = CreateFileMapping( + INVALID_HANDLE_VALUE, // use paging file + NULL, // default security + PAGE_READWRITE, // read/write access + 0, // max. object size + size, // buffer size + seg_name); // name of mapping object + return 0; +} +],[HAVE_CREATEFILEMAPPING=yes + AC_DEFINE(HAVE_CREATEFILEMAPPING,[1],[Define if you have the CreateFilemapping function(win32).])], + [HAVE_CREATEFILEMAPPING=no]) + + AC_MSG_RESULT($HAVE_CREATEFILEMAPPING) + AM_CONDITIONAL(HAVE_CREATEFILEMAPPING, test x$HAVE_CREATEFILEMAPPING = xyes) +]) + + diff --git a/config/gr_check_mc4020.m4 b/config/gr_check_mc4020.m4 new file mode 100644 index 0000000..28987c2 --- /dev/null +++ b/config/gr_check_mc4020.m4 @@ -0,0 +1,37 @@ +dnl +dnl Copyright 2003 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +AC_DEFUN([GR_CHECK_MC4020],[ + AC_MSG_CHECKING([for mc4020 A/D driver include file]) + AC_COMPILE_IFELSE([ +#include +int main (int argc, char **argv) +{ + return 0; +} +],[HAVE_MC4020=yes + AC_DEFINE(HAVE_MC4020,[1],[Define if you have a Measurement Computing PCI-DAS4020/12 A/D])], + [HAVE_MC4020=no]) + + AC_MSG_RESULT($HAVE_MC4020) + AM_CONDITIONAL(HAVE_MC4020, test x$HAVE_MC4020 = xyes) +]) + diff --git a/config/gr_check_shm_open.m4 b/config/gr_check_shm_open.m4 new file mode 100644 index 0000000..83d260b --- /dev/null +++ b/config/gr_check_shm_open.m4 @@ -0,0 +1,29 @@ +dnl +dnl Copyright 2003 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. + +AC_DEFUN([GR_CHECK_SHM_OPEN], +[ + SHM_OPEN_LIBS="" + save_LIBS="$LIBS" + AC_SEARCH_LIBS([shm_open], [rt], [SHM_OPEN_LIBS="$LIBS"]) + AC_CHECK_FUNCS([shm_open]) + LIBS="$save_LIBS" + AC_SUBST(SHM_OPEN_LIBS) +]) diff --git a/config/gr_check_usrp.m4 b/config/gr_check_usrp.m4 new file mode 100644 index 0000000..12a5d1c --- /dev/null +++ b/config/gr_check_usrp.m4 @@ -0,0 +1,32 @@ +dnl +dnl Copyright 2003 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +dnl Check for Universal Software Radio Peripheral + +AC_DEFUN([GR_CHECK_USRP],[ + PKG_CHECK_MODULES(USRP, usrp >= 0.2, + [HAVE_USRP=yes + AC_DEFINE(HAVE_USRP,[1],[Define if you have a USRP])], + [HAVE_USRP=no]) + + AM_CONDITIONAL(HAVE_USRP, test x$HAVE_USRP = xyes) +]) + diff --git a/config/gr_doxygen.m4 b/config/gr_doxygen.m4 new file mode 100644 index 0000000..4670c29 --- /dev/null +++ b/config/gr_doxygen.m4 @@ -0,0 +1,59 @@ +dnl +dnl Copyright 2003,2005 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +AC_DEFUN([GR_CHECK_DOXYGEN],[ + AC_ARG_ENABLE(doxygen, [ --enable-doxygen enable documentation generation with doxygen (no)]) + AC_ARG_ENABLE(dot, [ --enable-dot use 'dot' to generate graphs in doxygen (auto)]) + AC_ARG_ENABLE(html-docs, [ --enable-html-docs enable HTML generation with doxygen (yes)], [], [ enable_html_docs=yes]) + AC_ARG_ENABLE(latex-docs, [ --enable-latex-docs enable LaTeX doc generation with doxygen (no)], [], [ enable_latex_docs=no]) + + if test "x$enable_doxygen" = xyes; then + AC_PATH_PROG(DOXYGEN, doxygen, , $PATH) + if test x$DOXYGEN = x; then + if test "x$enable_doxygen" = xyes; then + AC_MSG_ERROR([could not find doxygen]) + fi + enable_doc=no + generate_docs= + else + enable_doc=yes + generate_docs=docs + AC_PATH_PROG(DOT, dot, , $PATH) + fi + else + enable_doc=no + fi + + AM_CONDITIONAL(DOC, test x$enable_doc = xyes) + + if test x$DOT = x; then + if test "x$enable_dot" = xyes; then + AC_MSG_ERROR([could not find dot]) + fi + enable_dot=no + else + enable_dot=yes + fi + AC_SUBST(enable_dot) + AC_SUBST(enable_html_docs) + AC_SUBST(enable_latex_docs) + AC_SUBST(generate_docs) +]) diff --git a/config/gr_gprof.m4 b/config/gr_gprof.m4 new file mode 100644 index 0000000..20bacf3 --- /dev/null +++ b/config/gr_gprof.m4 @@ -0,0 +1,72 @@ +dnl +dnl Copyright 2002 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +dnl FIXME probably need to add linker flag too... + +AC_DEFUN([GR_SET_GPROF],[ + dnl Check for --with-gprof + AC_MSG_CHECKING([whether user wants gprof]) + AC_ARG_WITH(gprof, + [ --with-gprof Turn on gprof profiling], + [], [ with_gprof=no ]) + AC_MSG_RESULT($with_gprof) + + dnl gprof profiling flags for the two main compilers + cc_profiling_flags="-pg" + cxx_profiling_flags="-pg" + ld_profiling_flags="-pg" + if test $with_gprof = yes + then + if test -n "${CC}" + then + LF_CHECK_CC_FLAG($cc_profiling_flags) + fi + if test -n "${CXX}" + then + LF_CHECK_CXX_FLAG($cxx_profiling_flags) + fi + fi +]) + +AC_DEFUN([GR_SET_PROF],[ + dnl Check for --with-prof + AC_MSG_CHECKING([whether user wants prof]) + AC_ARG_WITH(prof, + [ --with-prof Turn on prof profiling], + [], [ with_prof=no ]) + AC_MSG_RESULT($with_prof) + + dnl prof profiling flags for the two main compilers + cc_profiling_flags="-p" + cxx_profiling_flags="-p" + ld_profiling_flags="-p" + if test $with_prof = yes + then + if test -n "${CC}" + then + LF_CHECK_CC_FLAG($cc_profiling_flags) + fi + if test -n "${CXX}" + then + LF_CHECK_CXX_FLAG($cxx_profiling_flags) + fi + fi +]) diff --git a/config/gr_libgnuradio_core_extra_ldflags.m4 b/config/gr_libgnuradio_core_extra_ldflags.m4 new file mode 100644 index 0000000..43f872c --- /dev/null +++ b/config/gr_libgnuradio_core_extra_ldflags.m4 @@ -0,0 +1,40 @@ +# Check for (MinGW)win32 extra ld options. -*- Autoconf -*- + +# Copyright 2003,2004,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 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. + +dnl +AC_DEFUN([GR_LIBGNURADIO_CORE_EXTRA_LDFLAGS], [ +AC_REQUIRE([AC_PROG_LD]) +# on Mingw32 extra LDFLAGS are required to ease global variable linking +LIBGNURADIO_CORE_EXTRA_LDFLAGS="" + +AC_MSG_CHECKING([whether $LD accepts --enable-runtime-pseudo-reloc]) +if ${LD} --enable-runtime-pseudo-reloc --version >/dev/null 2>&1 +then + # libtool requires the quotes + LIBGNURADIO_CORE_EXTRA_LDFLAGS="\"-Wl,--enable-runtime-pseudo-reloc\"" + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +AC_SUBST(LIBGNURADIO_CORE_EXTRA_LDFLAGS) + +]) diff --git a/config/gr_no_undefined.m4 b/config/gr_no_undefined.m4 new file mode 100644 index 0000000..c8d745d --- /dev/null +++ b/config/gr_no_undefined.m4 @@ -0,0 +1,44 @@ +dnl +dnl Copyright 2005 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +# GR_NO_UNDEFINED() +# +# Detemine whether we need to use the -no-undefined linker flag +# when building shared libraries. +# Sets NO_UNDEFINED to "" or "-no-undefined" +# +# As far as I can tell, we need -no-undefined only when building +# windows DLLs. This occurs when using MinGW and Cygwin. +# +# For now, we stub this out. + +AC_DEFUN([GR_NO_UNDEFINED],[ + AC_REQUIRE([AC_CANONICAL_HOST]) + no_undefined="" + case "${host_os}" in + *mingw* | *cygwin*) + + # on MinGW/Cygwin extra LDFLAGS are required + no_undefined="-no-undefined" + ;; + esac + AC_SUBST(NO_UNDEFINED,[$no_undefined]) +]) diff --git a/config/gr_omnithread.m4 b/config/gr_omnithread.m4 new file mode 100644 index 0000000..b5e4090 --- /dev/null +++ b/config/gr_omnithread.m4 @@ -0,0 +1,51 @@ +# Check for Omnithread (pthread/NT) thread support. -*- Autoconf -*- + +# Copyright 2003 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, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Boston, MA +# 02110-1301, USA. + +AC_DEFUN([GR_OMNITHREAD], +[ + # Check first for POSIX + ACX_PTHREAD( + [ ot_posix="yes" + AC_DEFINE(OMNITHREAD_POSIX,[1],[Define to 1 to enable pthread]) + ],[ + # If no POSIX support found, then check for NT threads + AC_MSG_CHECKING([for NT threads]) + + AC_LINK_IFELSE([ + #include + #include + int main() { InitializeCriticalSection(NULL); return 0; } + ], + [ + ot_nt="yes" + AC_DEFINE(OMNITHREAD_NT,[1],[Define to 1 to enable NT thread]) + ], + [AC_MSG_FAILURE([GNU Radio requires POSIX threads. pthreads not found.])] + ) + AC_MSG_RESULT(yes) + ]) + AM_CONDITIONAL(OMNITHREAD_POSIX, test "x$ot_posix" = xyes) + AM_CONDITIONAL(OMNITHREAD_NT, test "x$ot_nt" = xyes) + + save_LIBS="$LIBS" + AC_SEARCH_LIBS([clock_gettime], [rt], [PTHREAD_LIBS="$PTHREAD_LIBS $LIBS"]) + AC_CHECK_FUNCS([clock_gettime gettimeofday nanosleep]) + LIBS="$save_LIBS" +]) + diff --git a/config/gr_pwin32.m4 b/config/gr_pwin32.m4 new file mode 100644 index 0000000..7b99cba --- /dev/null +++ b/config/gr_pwin32.m4 @@ -0,0 +1,146 @@ +# Check for (mingw)win32 POSIX replacements. -*- Autoconf -*- + +# Copyright 2003,2004,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 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. + + +AC_DEFUN([GR_PWIN32], +[ +AC_REQUIRE([AC_HEADER_TIME]) +AC_CHECK_HEADERS([sys/types.h fcntl.h io.h]) +AC_CHECK_HEADERS([windows.h]) +AC_CHECK_HEADERS([winioctl.h winbase.h], [], [], [ + #if HAVE_WINDOWS_H + #include + #endif +]) + +AC_CHECK_FUNCS([getopt usleep gettimeofday nanosleep rand srand random srandom sleep sigaction]) +AC_CHECK_TYPES([struct timezone, struct timespec, ssize_t],[],[],[ + #if HAVE_SYS_TYPES_H + # include + #endif + #if TIME_WITH_SYS_TIME + # include + # include + #else + # if HAVE_SYS_TIME_H + # include + # else + # include + # endif + #endif +]) + +dnl Checks for replacements +AC_REPLACE_FUNCS([getopt usleep gettimeofday]) + + +AC_MSG_CHECKING(for Sleep) +AC_TRY_LINK([ #include + #include + ], [ Sleep(0); ], + [AC_DEFINE(HAVE_SSLEEP,1,[Define to 1 if you have win32 Sleep]) + AC_MSG_RESULT(yes)], + AC_MSG_RESULT(no) + ) + +dnl Under Win32, mkdir prototype in io.h has only one arg +AC_MSG_CHECKING(whether mkdir accepts only one arg) +AC_TRY_COMPILE([#include + #include + #include ], [ + mkdir("") + ], [ AC_MSG_RESULT(yes) + AC_DEFINE(MKDIR_TAKES_ONE_ARG,[],[Define if mkdir accepts only one arg]) ], + [ AC_MSG_RESULT(no) + ]) + +AH_BOTTOM( +[ +/* Define missing prototypes, implemented in replacement lib */ +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef HAVE_GETOPT +int getopt (int argc, char * const argv[], const char * optstring); +extern char * optarg; +extern int optind, opterr, optopt; +#endif + +#ifndef HAVE_USLEEP +int usleep(unsigned long usec); /* SUSv2 */ +#endif + +#ifndef HAVE_NANOSLEEP +#ifndef HAVE_STRUCT_TIMESPEC +#if HAVE_SYS_TYPES_H +# include /* need time_t */ +#endif +struct timespec { + time_t tv_sec; + long tv_nsec; +}; +#endif +static inline int nanosleep(const struct timespec *req, struct timespec *rem) { return usleep(req->tv_sec*1000000+req->tv_nsec/1000); } +#endif + +#if defined(HAVE_SSLEEP) && !defined(HAVE_SLEEP) +#ifdef HAVE_WINBASE_H +#include +#include +#endif +/* TODO: what about SleepEx? */ +static inline unsigned int sleep (unsigned int nb_sec) { Sleep(nb_sec*1000); return 0; } +#endif + +#ifndef HAVE_GETTIMEOFDAY +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifndef HAVE_STRUCT_TIMEZONE +struct timezone { + int tz_minuteswest; + int tz_dsttime; +}; +#endif +int gettimeofday(struct timeval *tv, struct timezone *tz); +#endif + +#if !defined(HAVE_RANDOM) && defined(HAVE_RAND) +#include +static inline long int random (void) { return rand(); } +#endif + +#if !defined(HAVE_SRANDOM) && defined(HAVE_SRAND) +static inline void srandom (unsigned int seed) { srand(seed); } +#endif + +#ifndef HAVE_SSIZE_T +typedef size_t ssize_t; +#endif + +#ifdef __cplusplus +} +#endif +]) + + +]) diff --git a/config/gr_python.m4 b/config/gr_python.m4 new file mode 100644 index 0000000..5816b27 --- /dev/null +++ b/config/gr_python.m4 @@ -0,0 +1,111 @@ +dnl +dnl Copyright 2003,2004,2005 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +# PYTHON_DEVEL() +# +# Checks for Python and tries to get the include path to 'Python.h'. +# It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LDFLAGS) output variables. +# +AC_DEFUN([PYTHON_DEVEL],[ + AC_REQUIRE([AM_PATH_PYTHON]) + AC_REQUIRE([AC_CANONICAL_HOST]) + + # For Fedora Core 5 and 6, see ticket:39 in Trac + if test -f '/etc/redhat-release'; then + if (echo $pyexecdir | grep -q lib64); then + pythondir="$pyexecdir" + fi + fi + + # Check for Python include path + AC_MSG_CHECKING([for Python include path]) + if test -z "$PYTHON" ; then + AC_MSG_ERROR([cannot find Python path]) + fi + + # ask distutils which include path we should use + python_cmd=' +import distutils.sysconfig +import os +path = distutils.sysconfig.get_python_inc(plat_specific=False) +if os.sep == "\\": + path = path.replace("\\", "/") +print path +' + python_path=`$PYTHON -c "$python_cmd"` + AC_MSG_RESULT([$python_path]) + if test -z "$python_path" ; then + AC_MSG_ERROR([cannot find Python include path]) + fi + + AC_SUBST(PYTHON_CPPFLAGS,[-I$python_path]) + + # Check for Python headers usability + python_save_CPPFLAGS=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $PYTHON_CPPFLAGS" + AC_CHECK_HEADERS([Python.h], [], + [AC_MSG_ERROR([cannot find usable Python headers])]) + CPPFLAGS="$python_save_CPPFLAGS" + + # Only set this on mingw and cygwin hosts, (only implemented + # for mingw host, for crosscompiling you need to trick this) + + PYTHON_LDFLAGS="" + case $host_os in + *mingw* | *cygwin* ) + AC_MSG_CHECKING([for Python LDFLAGS]) + + python_cmd=' +import distutils.sysconfig +import os +path = distutils.sysconfig.get_config_var("LIBPL") +if path == None: + path = distutils.sysconfig.PREFIX + "/libs" +if os.sep == "\\": + path = path.replace("\\", "/") +print path +' + python_stdlib_path=`$PYTHON -c "$python_cmd"` + + python_version_nodot=`echo $PYTHON_VERSION | sed "s,\.,,"` + libpython_name="python$PYTHON_VERSION" + + # Standard install of python for win32 has libpython24.a + # instead of libpython2.4.a so we check for the library + # without the dot in the version number. + + python_stdlib_filename=`find $python_stdlib_path -type f -name libpython$python_version_nodot.* -print | sed "1q"` + if test -n "$python_stdlib_filename" ; then + libpython_name="python$python_version_nodot" + fi + + PYTHON_LDFLAGS="-L$python_stdlib_path -l$libpython_name" + AC_MSG_RESULT($PYTHON_LDFLAGS) + # Replace all backslashes in PYTHON Paths with forward slashes + pythondir=`echo $pythondir |sed 's,\\\\,/,g'` + pkgpythondir=`echo $pkgpythondir |sed 's,\\\\,/,g'` + pyexecdir=`echo $pyexecdir |sed 's,\\\\,/,g'` + pkgpyexecdir=`echo $pkgpyexecdir |sed 's,\\\\,/,g'` + ;; + esac + + AC_SUBST([PYTHON_LDFLAGS]) +]) diff --git a/config/gr_require_mc4020.m4 b/config/gr_require_mc4020.m4 new file mode 100644 index 0000000..90774fd --- /dev/null +++ b/config/gr_require_mc4020.m4 @@ -0,0 +1,33 @@ +dnl +dnl Copyright 2003,2004 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +AC_DEFUN([GR_REQUIRE_MC4020],[ + AC_MSG_CHECKING([for mc4020 A/D driver include file]) + AC_COMPILE_IFELSE([ +#include +int main (int argc, char **argv) +{ + return 0; +} +],[AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + AC_MSG_ERROR([mc4020.h not found.])]) +]) diff --git a/config/gr_scripting.m4 b/config/gr_scripting.m4 new file mode 100644 index 0000000..86870e7 --- /dev/null +++ b/config/gr_scripting.m4 @@ -0,0 +1,30 @@ +dnl +dnl Copyright 2003 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +AC_DEFUN([GR_SCRIPTING],[ + AC_REQUIRE([AC_PROG_LN_S]) + AC_REQUIRE([AC_PROG_CXX]) + AC_REQUIRE([AC_PROG_LIBTOOL]) + + SWIG_PROG(1.3.23) + SWIG_ENABLE_CXX + SWIG_PYTHON +]) diff --git a/config/gr_set_md_cpu.m4 b/config/gr_set_md_cpu.m4 new file mode 100644 index 0000000..ebc1fad --- /dev/null +++ b/config/gr_set_md_cpu.m4 @@ -0,0 +1,44 @@ +dnl +dnl Copyright 2003 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +AC_DEFUN([GR_SET_MD_CPU],[ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_ARG_WITH(md-cpu, + [ --with-md-cpu=ARCH set machine dependent speedups (auto)], + [cf_with_md_cpu="$withval"], + [cf_with_md_cpu="$host_cpu"]) + + AC_MSG_CHECKING([for machine dependent speedups]) + case "$cf_with_md_cpu" in + x86 | i[[3-7]]86) MD_CPU=x86 MD_SUBCPU=x86 ;; + x86_64) MD_CPU=x86 MD_SUBCPU=x86_64 ;; +# sparc) MD_CPU=sparc ;; + *) MD_CPU=generic ;; + esac + AC_MSG_RESULT($MD_CPU) + AC_SUBST(MD_CPU) + AC_SUBST(MD_SUBCPU) + + AM_CONDITIONAL(MD_CPU_x86, test $MD_CPU = x86) + AM_CONDITIONAL(MD_SUBCPU_x86_64, test $MD_SUBCPU = x86_64) + AM_CONDITIONAL(MD_CPU_generic, test $MD_CPU = generic) +]) + diff --git a/config/gr_swig.m4 b/config/gr_swig.m4 new file mode 100644 index 0000000..cdb2805 --- /dev/null +++ b/config/gr_swig.m4 @@ -0,0 +1,85 @@ +dnl +dnl Copyright 2003 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +# SWIG_PROG([required-version]) +# +# Checks for the SWIG program. If found you can (and should) call SWIG via $(SWIG). +# You can use the optional first argument to check if the version of the available SWIG +# is greater or equal to the value of the argument. It should have the format: +# N[.N[.N]] (N is a number between 0 and 999. Only the first N is mandatory.) +AC_DEFUN([SWIG_PROG],[ + AC_REQUIRE([AC_PROG_MAKE_SET]) + AC_CHECK_PROG(SWIG,swig,[`which swig`]) + if test -z "$SWIG" ; then + AC_MSG_ERROR([Cannot find 'swig' program. SWIG version >= $1 required]) + SWIG=false + elif test -n "$1" ; then + AC_MSG_CHECKING([for SWIG version]) + swig_version=`$SWIG -version 2>&1 | \ + awk '/^SWIG Version [[0-9]+\.[0-9]+\.[0-9]]+.*$/ { split($[3],a,"[[^.0-9]]"); print a[[1]] }'` + AC_MSG_RESULT([$swig_version]) + if test -n "$swig_version" ; then + swig_version=`echo $swig_version | \ + awk '{ split($[1],a,"\."); print [a[1]*1000000+a[2]*1000+a[3]] }' 2>/dev/null` + swig_required_version=`echo $1 | \ + awk '{ split($[1],a,"\."); print [a[1]*1000000+a[2]*1000+a[3]] }' 2>/dev/null` + if test $swig_required_version -gt $swig_version ; then + AC_MSG_ERROR([SWIG version >= $1 required]) + fi + else + AC_MSG_ERROR([cannot determine SWIG version]) + fi + fi +]) + +# SWIG_ENABLE_CXX() +# +# Enable swig C++ support. This effects all invocations of $(SWIG). +AC_DEFUN([SWIG_ENABLE_CXX],[ + AC_REQUIRE([SWIG_PROG]) + AC_REQUIRE([AC_PROG_CXX]) + if test "$SWIG" != "false" ; then + SWIG="$SWIG -c++" + fi +]) + +# SWIG_PYTHON([use-shadow-classes]) +# +# Checks for Python and provides the $(SWIG_PYTHON_CPPFLAGS), +# $(SWIG_PYTHON_LIB) and $(SWIG_PYTHON_OPT) output variables. +# $(SWIG_PYTHON_OPT) contains all necessary swig options to generate +# code for Python. If you need multi module support use +# $(SWIG_PYTHON_LIB) (provided by the SWIG_MULTI_MODULE_SUPPORT() +# macro) to link against the appropriate library. It contains the +# SWIG Python runtime library that is needed by the type check system +# for example. + +AC_DEFUN([SWIG_PYTHON],[ + AC_REQUIRE([SWIG_PROG]) + AC_REQUIRE([PYTHON_DEVEL]) + if test "$SWIG" != "false" ; then + AC_SUBST(SWIG_PYTHON_LIB,[-lswigpy]) +dnl test ! "x$1" = "xno" && swig_shadow=" -shadow" || swig_shadow="" +dnl AC_SUBST(SWIG_PYTHON_OPT,[-python$swig_shadow]) + AC_SUBST(SWIG_PYTHON_OPT,[-python]) + fi + AC_SUBST(SWIG_PYTHON_CPPFLAGS,[$PYTHON_CPPFLAGS]) +]) diff --git a/config/gr_sysv_shm.m4 b/config/gr_sysv_shm.m4 new file mode 100644 index 0000000..db5c835 --- /dev/null +++ b/config/gr_sysv_shm.m4 @@ -0,0 +1,36 @@ +# Check for IPC System V shm support. -*- Autoconf -*- + +# Copyright 2003 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, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Boston, MA +# 02110-1301, USA. + +AC_DEFUN([GR_SYSV_SHM], +[ + AC_LANG_SAVE + AC_LANG_C + + AC_CHECK_HEADERS([sys/ipc.h sys/shm.h]) + + save_LIBS="$LIBS" + AC_SEARCH_LIBS(shmat, [cygipc ipc], + [ IPC_LIBS="$LIBS" ], + [ AC_MSG_WARN([SystemV IPC support not found. ]) ] + ) + LIBS="$save_LIBS" + + AC_LANG_RESTORE + AC_SUBST(IPC_LIBS) +]) diff --git a/config/gr_x86_64.m4 b/config/gr_x86_64.m4 new file mode 100644 index 0000000..3f56c06 --- /dev/null +++ b/config/gr_x86_64.m4 @@ -0,0 +1,39 @@ +dnl +dnl Copyright 2005 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +# GR_X86_64() +# +# Checks to see if we're on a x86_64 machine, and if so, ensure +# that libdir ends in "64" +# +AC_DEFUN([GR_X86_64],[ + AC_REQUIRE([AC_CANONICAL_HOST]) + if test "$host_cpu" = "x86_64"; then + AC_MSG_CHECKING([libdir for lib64 suffix]) + t=${libdir##*/lib} + if test "$t" != 64 && test -d /lib64 && ! test -L /lib64; then + libdir=${libdir}64 + AC_MSG_RESULT([no. Setting libdir to $libdir]) + else + AC_MSG_RESULT([yes]) + fi + fi +]) diff --git a/config/lf_cxx.m4 b/config/lf_cxx.m4 new file mode 100644 index 0000000..c581c9b --- /dev/null +++ b/config/lf_cxx.m4 @@ -0,0 +1,121 @@ +dnl Autoconf support for C++ +dnl Copyright (C) 1988 Eleftherios Gkioulekas +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301, USA. +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a configuration +dnl script generated by Autoconf, you may include it under the same +dnl distribution terms that you use for the rest of that program. + +# ----------------------------------------------------------------- +# This macro should be called to configure your C++ compiler. +# When called, the macro does the following things: +# 1. It finds an appropriate C++ compiler +# If you passed the flag --with-cxx=foo, then it uses that +# particular compiler +# 2. Checks whether the compiler accepts the -g +# ------------------------------------------------------------------ + +AC_DEFUN([LF_CONFIGURE_CXX],[ + AC_REQUIRE([AC_PROG_CXX])dnl + AC_REQUIRE([AC_PROG_CXXCPP])dnl + LF_CXX_PORTABILITY +]) + +# ----------------------------------------------------------------------- +# This macro tests the C++ compiler for various portability problem. +# 1. Defines CXX_HAS_NO_BOOL if the compiler does not support the bool +# data type +# 2. Defines CXX_HAS_BUGGY_FOR_LOOPS if the compiler has buggy +# scoping for the for-loop +# 3. Defines USE_ASSERT if the user wants to use assertions +# ----------------------------------------------------------------------- + + +AC_DEFUN([LF_CXX_PORTABILITY],[ + + dnl + dnl Check for common C++ portability problems + dnl + + dnl AC_LANG_PUSH + dnl AC_LANG_CPLUSPLUS + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + + dnl Check whether we have bool + AC_MSG_CHECKING(whether C++ has bool) + AC_TRY_RUN([main() { bool b1=true; bool b2=false; }], + [ AC_MSG_RESULT(yes) ], + [ AC_MSG_RESULT(no) + AC_DEFINE(CXX_HAS_NO_BOOL,[],[Define if C++ is missing bool type]) ], + [ AC_MSG_WARN(Don't cross-compile)] + ) + + dnl Test whether C++ has buggy for-loops + AC_MSG_CHECKING(whether C++ has buggy scoping in for-loops) + AC_TRY_COMPILE([#include ], [ + for (int i=0;i<10;i++) { } + for (int i=0;i<10;i++) { } +], [ AC_MSG_RESULT(no) ], + [ AC_MSG_RESULT(yes) + AC_DEFINE(CXX_HAS_BUGGY_FOR_LOOPS,[],[Define if for loop scoping is broken]) ]) + + dnl Test whether the user wants to enable assertions + AC_MSG_CHECKING(whether user wants assertions) + AC_ARG_ENABLE(assert, + [ --disable-assert don't use cpp.h assert], + [ AC_DEFINE(NDEBUG,[],[Define to disable asserts (don't doit!)]) + AC_MSG_RESULT(no) ], + [ AC_MSG_RESULT(yes) ], + ) + + dnl Test whether C++ has std::isnan + AC_MSG_CHECKING(whether C++ has std::isnan) + AC_TRY_COMPILE([#include ], [ + std::isnan(0); +], [ AC_MSG_RESULT(yes) + AC_DEFINE(CXX_HAS_STD_ISNAN,[],[Define if has std::isnan]) ], + [ AC_MSG_RESULT(no) ]) + + dnl Done with the portability checks + dnl AC_LANG_POP([C++]) + AC_LANG_RESTORE +]) + +AH_BOTTOM([// Workaround for compilers with buggy for-loop scoping +// That's quite a few compilers actually including recent versions of +// Dec Alpha cxx, HP-UX CC and SGI CC. +// The trivial "if" statement provides the correct scoping to the +// for loop + +#ifdef CXX_HAS_BUGGY_FOR_LOOPS +#undef for +#define for if(1) for +#endif +]) + +AH_BOTTOM([// If the C++ compiler we use doesn't have bool, then +// the following is a near-perfect work-around. +// You must make sure your code does not depend on "int" and "bool" +// being two different types, in overloading for instance. + +#ifdef CXX_HAS_NO_BOOL +#define bool int +#define true 1 +#define false 0 +#endif +]) diff --git a/config/lf_warnings.m4 b/config/lf_warnings.m4 new file mode 100644 index 0000000..4e2ca91 --- /dev/null +++ b/config/lf_warnings.m4 @@ -0,0 +1,128 @@ +dnl Copyright (C) 1988 Eleftherios Gkioulekas +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301, USA. +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a configuration +dnl script generated by Autoconf, you may include it under the same +dnl distribution terms that you use for the rest of that program. + +# -------------------------------------------------------------------------- +# Check whether the C++ compiler accepts a certain flag +# If it does it adds the flag to CXXFLAGS +# If it does not then it returns an error to lf_ok +# Usage: +# LF_CHECK_CXX_FLAG(-flag1 -flag2 -flag3 ...) +# ------------------------------------------------------------------------- + +AC_DEFUN([LF_CHECK_CXX_FLAG],[ + echo 'void f(){}' > conftest.cc + for i in $1 + do + AC_MSG_CHECKING([whether $CXX accepts $i]) + if test -z "`${CXX} $i -c conftest.cc 2>&1`" + then + CXXFLAGS="${CXXFLAGS} $i" + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + done + rm -f conftest.cc conftest.o +]) + +# -------------------------------------------------------------------------- +# Check whether the C compiler accepts a certain flag +# If it does it adds the flag to CFLAGS +# If it does not then it returns an error to lf_ok +# Usage: +# LF_CHECK_CC_FLAG(-flag1 -flag2 -flag3 ...) +# ------------------------------------------------------------------------- + +AC_DEFUN([LF_CHECK_CC_FLAG],[ + echo 'void f(){}' > conftest.c + for i in $1 + do + AC_MSG_CHECKING([whether $CC accepts $i]) + if test -z "`${CC} $i -c conftest.c 2>&1`" + then + CFLAGS="${CFLAGS} $i" + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + done + rm -f conftest.c conftest.o +]) + +# -------------------------------------------------------------------------- +# Check whether the Fortran compiler accepts a certain flag +# If it does it adds the flag to FFLAGS +# If it does not then it returns an error to lf_ok +# Usage: +# LF_CHECK_F77_FLAG(-flag1 -flag2 -flag3 ...) +# ------------------------------------------------------------------------- + +AC_DEFUN([LF_CHECK_F77_FLAG],[ + cat << EOF > conftest.f +c....:++++++++++++++++++++++++ + PROGRAM MAIN + PRINT*,'Hello World!' + END +EOF + for i in $1 + do + AC_MSG_CHECKING([whether $F77 accepts $i]) + if test -z "`${F77} $i -c conftest.f 2>&1`" + then + FFLAGS="${FFLAGS} $i" + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + done + rm -f conftest.f conftest.o +]) + +# ---------------------------------------------------------------------- +# Provide the configure script with an --with-warnings option that +# turns on warnings. Call this command AFTER you have configured ALL your +# compilers. +# ---------------------------------------------------------------------- + +AC_DEFUN([LF_SET_WARNINGS],[ + dnl Check for --with-warnings + AC_MSG_CHECKING([whether user wants warnings]) + AC_ARG_WITH(warnings, + [ --with-warnings Turn on warnings], + [ lf_warnings=yes ], [ lf_warnings=no ]) + lf_warnings=yes # hard code for now -eb + AC_MSG_RESULT($lf_warnings) + + dnl Warnings for the two main compilers + cc_warning_flags="-Wall" + cxx_warning_flags="-Wall -Woverloaded-virtual" + if test $lf_warnings = yes + then + if test -n "${CC}" + then + LF_CHECK_CC_FLAG($cc_warning_flags) + fi + if test -n "${CXX}" + then + LF_CHECK_CXX_FLAG($cxx_warning_flags) + fi + fi +]) diff --git a/config/lf_x11.m4 b/config/lf_x11.m4 new file mode 100644 index 0000000..460cd60 --- /dev/null +++ b/config/lf_x11.m4 @@ -0,0 +1,39 @@ +dnl Copyright (C) 1988 Eleftherios Gkioulekas +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301, USA. +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a configuration +dnl script generated by Autoconf, you may include it under the same +dnl distribution terms that you use for the rest of that program. + + +#----------------------------------------------------------------------- +# This macro searches for Xlib and when it finds it it adds the +# appropriate flags to CXXFLAGS and export the link sequence to +# the variable XLIB. +# In your configure.in file add: +# LF_PATH_XLIB +# In your Makefile.am add +# program_LDADD = .... $(XLIB) +#------------------------------------------------------------------------ + +AC_DEFUN([LF_PATH_XLIB],[ + AC_PATH_XTRA + CXXFLAGS="$CXXFLAGS $X_CFLAGS" + XLIB="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS" + AC_SUBST(XLIB) +]) + diff --git a/config/libtool.m4 b/config/libtool.m4 new file mode 100644 index 0000000..4ceb7f1 --- /dev/null +++ b/config/libtool.m4 @@ -0,0 +1,7309 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +]) + +# serial 56 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +m4_defun([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl +_LT_PROG_ECHO_BACKSLASH + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from `configure', and `config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# `config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain="$ac_aux_dir/ltmain.sh" +])# _LT_PROG_LTMAIN + + +## ------------------------------------- ## +## Accumulate code for creating libtool. ## +## ------------------------------------- ## + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the `libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + +## ------------------------ ## +## FIXME: Eliminate VARNAME ## +## ------------------------ ## + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_quote(m4_if([$2], [], + m4_quote(lt_decl_tag_varnames), + m4_quote(m4_shift($@)))), + m4_split(m4_normalize(m4_quote(_LT_TAGS))))]) +m4_define([_lt_decl_varnames_tagged], [lt_combine([$1], [$2], [_], $3)]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to `config.status' so that its +# declaration there will have the same value as in `configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "X$][$1" | $Xsed -e "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# ='`$ECHO "X$" | $Xsed -e "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags="_LT_TAGS"dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into `config.status', and then the shell code to quote escape them in +# for loops in `config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Fix-up fallback echo if it was mangled by the above quoting rules. +case \$lt_ECHO in +*'\\\[$]0 --fallback-echo"')dnl " + lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 --fallback-echo"\[$]/\[$]0 --fallback-echo"/'\` + ;; +esac + +_LT_OUTPUT_LIBTOOL_INIT +]) + + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +cat >"$CONFIG_LT" <<_LTEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate a libtool stub with the current configuration. + +lt_cl_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AS_SHELL_SANITIZE +_AS_PREPARE + +exec AS_MESSAGE_FD>&1 +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +\`$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to ." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2008 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test $[#] != 0 +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try \`$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try \`$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +if test "$no_create" != yes; then + lt_cl_success=: + test "$silent" = yes && + lt_config_lt_args="$lt_config_lt_args --quiet" + exec AS_MESSAGE_LOG_FD>/dev/null + $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false + exec AS_MESSAGE_LOG_FD>>config.log + $lt_cl_success || AS_EXIT(1) +fi +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +_LT_COPYING +_LT_LIBTOOL_TAGS + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + _LT_PROG_XSI_SHELLFNS + + sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS="$save_LDFLAGS" + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[[012]]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES +# -------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" + if test "$GCC" = "yes"; then + output_verbose_link_cmd=echo + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + m4_if([$1], [CXX], +[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX +# ----------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +AC_LINK_IFELSE(AC_LANG_PROGRAM,[ +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi],[]) +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[ifdef([AC_DIVERSION_NOTICE], + [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], + [AC_DIVERT_PUSH(NOTICE)]) +$1 +AC_DIVERT_POP +])# _LT_SHELL_INIT + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Add some code to the start of the generated configure script which +# will find an echo command which doesn't interpret backslashes. +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[_LT_SHELL_INIT([ +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$lt_ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` + ;; +esac + +ECHO=${lt_ECHO-echo} +if test "X[$]1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X[$]1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then + # Yippee, $ECHO works! + : +else + # Restart under the correct shell. + exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} +fi + +if test "X[$]1" = X--fallback-echo; then + # used as fallback echo + shift + cat <<_LT_EOF +[$]* +_LT_EOF + exit 0 +fi + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test -z "$lt_ECHO"; then + if test "X${echo_test_string+set}" != Xset; then + # find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if { echo_test_string=`eval $cmd`; } 2>/dev/null && + { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null + then + break + fi + done + fi + + if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : + else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + ECHO="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$ECHO" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + ECHO='print -r' + elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} + else + # Try using printf. + ECHO='printf %s\n' + if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + ECHO="$CONFIG_SHELL [$]0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + ECHO="$CONFIG_SHELL [$]0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do + if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "[$]0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} + else + # Oops. We lost completely, so just stick with echo. + ECHO=echo + fi + fi + fi + fi + fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +lt_ECHO=$ECHO +if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then + lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" +fi + +AC_SUBST(lt_ECHO) +]) +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], + [An echo program that does not interpret backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" +])# _LT_ENABLE_LOCK + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[AC_CHECK_TOOL(AR, ar, false) +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1]) + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test x"[$]$2" = xyes; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ + = "XX$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line __oline__ "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + exit (status); +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links="nottested" +if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", + [Define to the sub-directory in which libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || + test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` + else + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[[4-9]]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[123]]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix[[3-9]]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # Some binutils ld are patched to set DT_RUNPATH + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_name_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], + [Run-time system search path for libraries]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program which can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program which can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method == "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi]) +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :) + AC_SUBST([DUMPBIN]) + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:__oline__: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:__oline__: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:__oline__: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +AC_MSG_CHECKING([for $compiler option to produce PIC]) +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + icpc* | ecpc* ) + # Intel C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC*) + # IBM XL 8.0 on PPC + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu) + case $cc_basename in + icc* | ecc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl*) + # IBM XL C 8.0/Fortran 10.1 on PPC + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Sun\ F*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac +AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw*) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag= + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + xl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + freebsd1*) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + AC_LINK_IFELSE(int foo(void) {}, + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + ) + LDFLAGS="$save_LDFLAGS" + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_MSG_CHECKING([whether -lc should be explicitly linked in]) + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + AC_MSG_RESULT([$_LT_TAGVAR(archive_cmds_need_lc, $1)]) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1], + [[If ld is used when linking, flag to hardcode $libdir into a binary + during linking. This must work even if $libdir does not exist]]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting ${shlibpath_var} if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [fix_srcfile_path], [1], + [Fix the shell variable $srcfile for the compiler]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report which library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC="$lt_save_CC" +])# _LT_LANG_C_CONFIG + + +# _LT_PROG_CXX +# ------------ +# Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++ +# compiler, we have our own version here. +m4_defun([_LT_PROG_CXX], +[ +pushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes]) +AC_PROG_CXX +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi +popdef([AC_MSG_ERROR]) +])# _LT_PROG_CXX + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([_LT_PROG_CXX], []) + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[AC_REQUIRE([_LT_PROG_CXX])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd[[12]]*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + gnu*) + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + *) + if test "$GXX" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]]* | *pgcpp\ [[1-5]]*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 will use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + xl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=echo + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + + _LT_TAGVAR(GCC, $1)="$GXX" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +]) +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + else + prev= + fi + + if test "$pre_test_object_deps_done" = no; then + case $p in + -L* | -R*) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)="${prev}${p}" + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" + fi + fi + ;; + + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)="$p" + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)="$p" + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_PROG_F77 +# ------------ +# Since AC_PROG_F77 is broken, in that it returns the empty string +# if there is no fortran compiler, we have our own version here. +m4_defun([_LT_PROG_F77], +[ +pushdef([AC_MSG_ERROR], [_lt_disable_F77=yes]) +AC_PROG_F77 +if test -z "$F77" || test "X$F77" = "Xno"; then + _lt_disable_F77=yes +fi +popdef([AC_MSG_ERROR]) +])# _LT_PROG_F77 + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([_LT_PROG_F77], []) + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_REQUIRE([_LT_PROG_F77])dnl +AC_LANG_PUSH(Fortran 77) + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_F77" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + CC=${F77-"f77"} + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$G77" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC="$lt_save_CC" +fi # test "$_lt_disable_F77" != yes + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_PROG_FC +# ----------- +# Since AC_PROG_FC is broken, in that it returns the empty string +# if there is no fortran compiler, we have our own version here. +m4_defun([_LT_PROG_FC], +[ +pushdef([AC_MSG_ERROR], [_lt_disable_FC=yes]) +AC_PROG_FC +if test -z "$FC" || test "X$FC" = "Xno"; then + _lt_disable_FC=yes +fi +popdef([AC_MSG_ERROR]) +])# _LT_PROG_FC + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([_LT_PROG_FC], []) + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_REQUIRE([_LT_PROG_FC])dnl +AC_LANG_PUSH(Fortran) + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_FC" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + CC=${FC-"f95"} + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC="$lt_save_CC" +fi # test "$_lt_disable_FC" != yes + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC="$lt_save_CC" +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC="$lt_save_CC" +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +AC_MSG_RESULT([$xsi_shell]) +_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) + +AC_MSG_CHECKING([whether the shell understands "+="]) +lt_shell_append=no +( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +AC_MSG_RESULT([$lt_shell_append]) +_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PROG_XSI_SHELLFNS +# --------------------- +# Bourne and XSI compatible variants of some useful shell functions. +m4_defun([_LT_PROG_XSI_SHELLFNS], +[case $xsi_shell in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac +} + +# func_basename file +func_basename () +{ + func_basename_result="${1##*/}" +} + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}" +} + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +func_stripname () +{ + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"} +} + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=${1%%=*} + func_opt_split_arg=${1#*=} +} + +# func_lo2o object +func_lo2o () +{ + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=${1%.*}.lo +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=$(( $[*] )) +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=${#1} +} + +_LT_EOF + ;; + *) # Bourne compatible functions. + cat << \_LT_EOF >> "$cfgfile" + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi +} + +# func_basename file +func_basename () +{ + func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` +} + +dnl func_dirname_and_basename +dnl A portable version of this function is already defined in general.m4sh +dnl so there is no need for it here. + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# func_strip_suffix prefix name +func_stripname () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "X${3}" \ + | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "X${3}" \ + | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; + esac +} + +# sed scripts: +my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q' +my_sed_long_arg='1s/^-[[^=]]*=//' + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` + func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` +} + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'` +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "$[@]"` +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len` +} + +_LT_EOF +esac + +case $lt_shell_append in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$[1]+=\$[2]" +} +_LT_EOF + ;; + *) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$[1]=\$$[1]\$[2]" +} + +_LT_EOF + ;; + esac +]) diff --git a/config/ltoptions.m4 b/config/ltoptions.m4 new file mode 100644 index 0000000..e970119 --- /dev/null +++ b/config/ltoptions.m4 @@ -0,0 +1,368 @@ +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option `$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl `shared' nor `disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + ]) +])# _LT_SET_OPTIONS + + +## --------------------------------- ## +## Macros to handle LT_INIT options. ## +## --------------------------------- ## + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [0], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the `shared' and +# `disable-shared' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the `static' and +# `disable-static' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the `fast-install' +# and `disable-fast-install' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the `pic-only' and `no-pic' +# LT_INIT options. +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [pic_mode="$withval"], + [pic_mode=default]) + +test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + +## ----------------- ## +## LTDL_INIT Options ## +## ----------------- ## + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/config/ltsugar.m4 b/config/ltsugar.m4 new file mode 100644 index 0000000..0d258e0 --- /dev/null +++ b/config/ltsugar.m4 @@ -0,0 +1,123 @@ +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 5 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59 which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +m4_define([lt_combine], +[m4_if([$2], [], [], + [m4_if([$4], [], [], + [lt_join(m4_quote(m4_default([$1], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_prefix, [$2], + [m4_foreach(_Lt_suffix, lt_car([m4_shiftn(3, $@)]), + [_Lt_prefix[]$3[]_Lt_suffix ])])))))])])dnl +]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) diff --git a/config/ltversion.m4 b/config/ltversion.m4 new file mode 100644 index 0000000..45cb155 --- /dev/null +++ b/config/ltversion.m4 @@ -0,0 +1,23 @@ +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# Generated from ltversion.in. + +# serial 2976 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.2.4]) +m4_define([LT_PACKAGE_REVISION], [1.2976]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.2.4' +macro_revision='1.2976' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) diff --git a/config/lt~obsolete.m4 b/config/lt~obsolete.m4 new file mode 100644 index 0000000..637bb20 --- /dev/null +++ b/config/lt~obsolete.m4 @@ -0,0 +1,92 @@ +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 4 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_RC], [AC_DEFUN([AC_LIBTOOL_RC])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) diff --git a/config/mkstemp.m4 b/config/mkstemp.m4 new file mode 100644 index 0000000..4af0f0a --- /dev/null +++ b/config/mkstemp.m4 @@ -0,0 +1,89 @@ +#serial 4 + +# On some hosts (e.g., HP-UX 10.20, SunOS 4.1.4, Solaris 2.5.1), mkstemp has a +# silly limit that it can create no more than 26 files from a given template. +# Other systems lack mkstemp altogether. +# On OSF1/Tru64 V4.0F, the system-provided mkstemp function can create +# only 32 files per process. +# On systems like the above, arrange to use the replacement function. +AC_DEFUN([UTILS_FUNC_MKSTEMP], +[dnl + AC_REPLACE_FUNCS(mkstemp) + if test $ac_cv_func_mkstemp = no; then + utils_cv_func_mkstemp_limitations=yes + else + AC_CACHE_CHECK([for mkstemp limitations], + utils_cv_func_mkstemp_limitations, + [ + AC_TRY_RUN([ +# include + int main () + { + int i; + for (i = 0; i < 70; i++) + { + char template[] = "conftestXXXXXX"; + int fd = mkstemp (template); + if (fd == -1) + exit (1); + close (fd); + } + exit (0); + } + ], + utils_cv_func_mkstemp_limitations=no, + utils_cv_func_mkstemp_limitations=yes, + utils_cv_func_mkstemp_limitations=yes + ) + ] + ) + fi + + if test $utils_cv_func_mkstemp_limitations = yes; then + AC_LIBOBJ(mkstemp) + AC_LIBOBJ(tempname) + AC_DEFINE(mkstemp, rpl_mkstemp, + [Define to rpl_mkstemp if the replacement function should be used.]) + gl_PREREQ_MKSTEMP + jm_PREREQ_TEMPNAME + fi +]) + +# Prerequisites of lib/mkstemp.c. +AC_DEFUN([gl_PREREQ_MKSTEMP], +[ + AH_BOTTOM( + [ + #ifndef HAVE_MKSTEMP + #ifdef __cplusplus + extern "C" { + #endif + int rpl_mkstemp (char *templ); + #ifdef __cplusplus + } + #endif + #endif + ]) +]) + +# Prerequisites of lib/tempname.c. +AC_DEFUN([jm_PREREQ_TEMPNAME], +[ + AC_REQUIRE([AC_HEADER_STAT]) + AC_CHECK_HEADERS_ONCE(fcntl.h sys/time.h unistd.h) + AC_CHECK_HEADERS(stdint.h) + AC_CHECK_FUNCS(__secure_getenv gettimeofday lstat) + AC_CHECK_DECLS_ONCE(getenv) + # AC_REQUIRE([jm_AC_TYPE_UINTMAX_T]) + + dnl Under Win32, mkdir prototype in io.h has only one arg + AC_MSG_CHECKING(whether mkdir accepts only one arg) + AC_TRY_COMPILE([#include + #include + #include ], [ + mkdir("") + ], [ AC_MSG_RESULT(yes) + AC_DEFINE(MKDIR_TAKES_ONE_ARG,[],[Define if mkdir accepts only one arg]) ], + [ AC_MSG_RESULT(no) + ]) +]) diff --git a/config/onceonly.m4 b/config/onceonly.m4 new file mode 100644 index 0000000..f6fec37 --- /dev/null +++ b/config/onceonly.m4 @@ -0,0 +1,63 @@ +# onceonly.m4 serial 3 +dnl Copyright (C) 2002, 2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl This file defines some "once only" variants of standard autoconf macros. +dnl AC_CHECK_HEADERS_ONCE like AC_CHECK_HEADERS +dnl AC_CHECK_FUNCS_ONCE like AC_CHECK_FUNCS +dnl AC_CHECK_DECLS_ONCE like AC_CHECK_DECLS +dnl AC_REQUIRE([AC_HEADER_STDC]) like AC_HEADER_STDC +dnl The advantage is that the check for each of the headers/functions/decls +dnl will be put only once into the 'configure' file. It keeps the size of +dnl the 'configure' file down, and avoids redundant output when 'configure' +dnl is run. +dnl The drawback is that the checks cannot be conditionalized. If you write +dnl if some_condition; then gl_CHECK_HEADERS(stdlib.h); fi +dnl inside an AC_DEFUNed function, the gl_CHECK_HEADERS macro call expands to +dnl empty, and the check will be inserted before the body of the AC_DEFUNed +dnl function. + +dnl Autoconf version 2.57 or newer is recommended. +AC_PREREQ(2.54) + +# AC_CHECK_HEADERS_ONCE(HEADER1 HEADER2 ...) is a once-only variant of +# AC_CHECK_HEADERS(HEADER1 HEADER2 ...). +AC_DEFUN([AC_CHECK_HEADERS_ONCE], [ + : + AC_FOREACH([gl_HEADER_NAME], [$1], [ + AC_DEFUN([gl_CHECK_HEADER_]m4_quote(translit(defn([gl_HEADER_NAME]), + [-./], [___])), [ + AC_CHECK_HEADERS(gl_HEADER_NAME) + ]) + AC_REQUIRE([gl_CHECK_HEADER_]m4_quote(translit(gl_HEADER_NAME, + [-./], [___]))) + ]) +]) + +# AC_CHECK_FUNCS_ONCE(FUNC1 FUNC2 ...) is a once-only variant of +# AC_CHECK_FUNCS(FUNC1 FUNC2 ...). +AC_DEFUN([AC_CHECK_FUNCS_ONCE], [ + : + AC_FOREACH([gl_FUNC_NAME], [$1], [ + AC_DEFUN([gl_CHECK_FUNC_]defn([gl_FUNC_NAME]), [ + AC_CHECK_FUNCS(defn([gl_FUNC_NAME])) + ]) + AC_REQUIRE([gl_CHECK_FUNC_]defn([gl_FUNC_NAME])) + ]) +]) + +# AC_CHECK_DECLS_ONCE(DECL1 DECL2 ...) is a once-only variant of +# AC_CHECK_DECLS(DECL1, DECL2, ...). +AC_DEFUN([AC_CHECK_DECLS_ONCE], [ + : + AC_FOREACH([gl_DECL_NAME], [$1], [ + AC_DEFUN([gl_CHECK_DECL_]defn([gl_DECL_NAME]), [ + AC_CHECK_DECLS(defn([gl_DECL_NAME])) + ]) + AC_REQUIRE([gl_CHECK_DECL_]defn([gl_DECL_NAME])) + ]) +]) diff --git a/config/pkg.m4 b/config/pkg.m4 new file mode 100644 index 0000000..770f062 --- /dev/null +++ b/config/pkg.m4 @@ -0,0 +1,68 @@ +dnl PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not) +dnl defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page +dnl also defines GSTUFF_PKG_ERRORS on error +AC_DEFUN([PKG_CHECK_MODULES], [ + succeeded=no + + if test -z "$PKG_CONFIG"; then + AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + fi + + if test "$PKG_CONFIG" = "no" ; then + echo "*** The pkg-config script could not be found. Make sure it is" + echo "*** in your path, or set the PKG_CONFIG environment variable" + echo "*** to the full path to pkg-config." + echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." + else + dnl If PKG_CONFIG_PATH is not already set, add /usr/local/lib/pkgconfig. + dnl If it's set, assume the user knows what they're doing. + dnl This should help avoid failures while looking for fftw3f + if test -z "$PKG_CONFIG_PATH"; then + export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig" + fi + + PKG_CONFIG_MIN_VERSION=0.9.0 + if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then + AC_MSG_CHECKING(for $2) + + if $PKG_CONFIG --exists "$2" ; then + AC_MSG_RESULT(yes) + succeeded=yes + + AC_MSG_CHECKING($1_CFLAGS) + $1_CFLAGS=`$PKG_CONFIG --cflags "$2"` + AC_MSG_RESULT($$1_CFLAGS) + + AC_MSG_CHECKING($1_LIBS) + $1_LIBS=`$PKG_CONFIG --libs "$2"` + AC_MSG_RESULT($$1_LIBS) + + AC_MSG_CHECKING($1_INCLUDEDIR) + $1_INCLUDEDIR=`$PKG_CONFIG --variable=includedir "$2"` + AC_MSG_RESULT($$1_INCLUDEDIR) + else + $1_CFLAGS="" + $1_LIBS="" + ## If we have a custom action on failure, don't print errors, but + ## do set a variable so people can do so. + $1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` + ifelse([$4], ,echo $$1_PKG_ERRORS,) + fi + + AC_SUBST($1_CFLAGS) + AC_SUBST($1_LIBS) + AC_SUBST($1_INCLUDEDIR) + else + echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." + echo "*** See http://www.freedesktop.org/software/pkgconfig" + fi + fi + + if test $succeeded = yes; then + ifelse([$3], , :, [$3]) + else + ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4]) + fi +]) + + diff --git a/config/usrp_fusb_tech.m4 b/config/usrp_fusb_tech.m4 new file mode 100644 index 0000000..b5a930b --- /dev/null +++ b/config/usrp_fusb_tech.m4 @@ -0,0 +1,56 @@ +dnl +dnl Copyright 2003 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +AC_DEFUN([USRP_SET_FUSB_TECHNIQUE],[ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_ARG_WITH(fusb-tech, + [ --with-fusb-tech=OS set fast usb technique (auto)], + [cf_with_fusb_tech="$withval"], + [cf_with_fusb_tech="$host_os"]) + + + AC_CHECK_HEADER([linux/usbdevice_fs.h], + [x_have_usbdevice_fs_h=yes], + [x_have_usbdevice_fs_h=no]) + + AC_MSG_CHECKING([for fast usb technique to use]) + case "$cf_with_fusb_tech" in + linux*) if test x${x_have_usbdevice_fs_h} = xyes; + then + FUSB_TECH=linux + else + FUSB_TECH=generic + fi ;; + + darwin*) FUSB_TECH=darwin ;; + cygwin*|win*|mingw*) FUSB_TECH=win32 ;; + *) FUSB_TECH=generic ;; + esac + + AC_MSG_RESULT($FUSB_TECH) + AC_SUBST(FUSB_TECH) + + AM_CONDITIONAL(FUSB_TECH_darwin, test $FUSB_TECH = darwin) + AM_CONDITIONAL(FUSB_TECH_win32, test $FUSB_TECH = win32) + AM_CONDITIONAL(FUSB_TECH_generic, test $FUSB_TECH = generic) + AM_CONDITIONAL(FUSB_TECH_linux, test $FUSB_TECH = linux) +]) + diff --git a/config/usrp_libusb.m4 b/config/usrp_libusb.m4 new file mode 100644 index 0000000..9fe4753 --- /dev/null +++ b/config/usrp_libusb.m4 @@ -0,0 +1,43 @@ +# Check for libusb support. -*- Autoconf -*- + +# Copyright 2003 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, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Boston, MA +# 02110-1301, USA. + +AC_DEFUN([USRP_LIBUSB], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_LANG_PUSH(C) + + AC_CHECK_HEADERS([usb.h], + [], + [ AC_MSG_ERROR([USRP requires libusb. usb.h not found, stop. See http://libusb.sf.net]) ] + ) + + save_LIBS="$LIBS" + case "$host_os" in + darwin*) LIBS="$LIBS -lIOKit" ;; + *) ;; + esac + AC_SEARCH_LIBS(usb_bulk_write, [usb], + [ USB_LIBS="$LIBS" ], + [ AC_MSG_ERROR([USRP requires libusb. usb_bulk_write not found, stop. See http://libusb.sf.net]) ] + ) + LIBS="$save_LIBS" + + AC_LANG_POP + AC_SUBST(USB_LIBS) +]) diff --git a/config/usrp_sdcc.m4 b/config/usrp_sdcc.m4 new file mode 100644 index 0000000..37ce7c3 --- /dev/null +++ b/config/usrp_sdcc.m4 @@ -0,0 +1,67 @@ +# Check for sdcc support. -*- Autoconf -*- + +# Copyright 2004 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, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Boston, MA +# 02110-1301, USA. + +AC_DEFUN([USRP_SDCC], +[ + AC_CHECK_PROG(XCC, sdcc, sdcc -mmcs51 --no-xinit-opt,no) + AC_CHECK_PROG(XAS, asx8051, asx8051 -plosgff,no) + + if test "$XCC" = "no" -o "$XAS" = "no" ; then + AC_MSG_ERROR([USRP requires sdcc. sdcc not found, stop. See http://sdcc.sf.net]) + fi + + sdcc_version_min=$1 + + sdcc_version=`sdcc --version 2>&1 | \ + sed 's/\(SDCC.* \)\([[0-9]]*\.[[0-9]]*\.[[0-9]]*\)\( .*$\)/\2/'` + + AC_MSG_CHECKING([sdcc_version "$sdcc_version"]) + + sdcc_major_version=`echo $sdcc_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + sdcc_minor_version=`echo $sdcc_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + sdcc_micro_version=`echo $sdcc_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + + sdcc_major_min=`echo $sdcc_version_min | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + sdcc_minor_min=`echo $sdcc_version_min | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + sdcc_micro_min=`echo $sdcc_version_min | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + + sdcc_version_proper=`expr \ + "$sdcc_major_version" \> "$sdcc_major_min" \| \ + "$sdcc_major_version" \= "$sdcc_major_min" \& \ + "$sdcc_minor_version" \> "$sdcc_minor_min" \| \ + "$sdcc_major_version" \= "$sdcc_major_min" \& \ + "$sdcc_minor_version" \= "$sdcc_minor_min" \& \ + "$sdcc_micro_version" \>= "$sdcc_micro_min" ` + + if test "$sdcc_version_proper" = "1" ; then + AC_MSG_RESULT([$sdcc_major_version.$sdcc_minor_version.$sdcc_micro_version]) + else + AC_MSG_ERROR([USRP requires sdcc >= $sdcc_version_min. sdcc not found, stop. See http://sdcc.sf.net]) + fi + + AC_SUBST(XCC) + AC_SUBST(XAS) + +]) diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..1eef1e4 --- /dev/null +++ b/configure.ac @@ -0,0 +1,106 @@ +dnl +dnl Copyright 2004,2005,2006,2007,2008 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +AC_INIT +AC_PREREQ(2.61) +AC_CONFIG_SRCDIR([src/lib/gsm_receiver.i]) +AM_CONFIG_HEADER(config.h) +AC_CANONICAL_TARGET([]) +AC_CONFIG_AUX_DIR([.]) +AM_INIT_AUTOMAKE(gsm-receiver,0.0.1) + +GR_X86_64 +dnl LF_CONFIGURE_CC +LF_CONFIGURE_CXX +LF_SET_WARNINGS +GR_SET_GPROF +GR_SET_PROF +AM_PROG_AS +AC_PROG_LN_S +AC_PROG_MAKE_SET +AC_PROG_INSTALL +AC_PATH_PROG([RM_PROG], [rm]) + +AC_LIBTOOL_WIN32_DLL +AC_ENABLE_SHARED dnl do build shared libraries +AC_DISABLE_STATIC dnl don't build static libraries +m4_ifdef([LT_INIT],[LT_INIT],[AC_PROG_LIBTOOL]) + +dnl Locate python, SWIG, etc +GR_NO_UNDEFINED +GR_SCRIPTING + +dnl Checks for libraries. + +dnl check for threads (mandatory) +GR_OMNITHREAD + +CFLAGS="${CFLAGS} $PTHREAD_CFLAGS" +CXXFLAGS="${CXXFLAGS} $PTHREAD_CFLAGS" + +if test "x$CXX_FOR_BUILD" = x +then + CXX_FOR_BUILD=${CXX} +fi +AC_SUBST(CXX_FOR_BUILD) + +dnl Checks for header files. +AC_HEADER_STDC +AC_HEADER_SYS_WAIT +AC_CHECK_HEADERS(fcntl.h limits.h strings.h sys/ioctl.h sys/time.h unistd.h) +AC_CHECK_HEADERS(sys/mman.h) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_INLINE +AC_TYPE_SIZE_T +AC_HEADER_TIME + +dnl Checks for library functions. +AC_CHECK_FUNCS([]) + +dnl Check for Mingw support +GR_PWIN32 + +PKG_CHECK_MODULES(GNURADIO_CORE, gnuradio-core >= 3) +dnl LIBS="$LIBS $GNURADIO_CORE_LIBS" + +dnl Define where to find boost includes +dnl defines BOOST_CFLAGS +GR_REQUIRE_BOOST_INCLUDES + +STD_DEFINES_AND_INCLUDES="$GNURADIO_CORE_CFLAGS $BOOST_CFLAGS" +AC_SUBST(STD_DEFINES_AND_INCLUDES) + +AC_CONFIG_FILES([\ + Makefile \ + config/Makefile \ + doc/Makefile \ + src/Makefile \ + src/lib/Makefile \ + src/python/Makefile \ + src/python/run_tests \ + ]) + +dnl run_tests is created from run_tests.in. Make it executable. +AC_CONFIG_COMMANDS([run_tests], [chmod +x src/python/run_tests]) + +AC_OUTPUT diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..e3f0399 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,22 @@ +# +# Copyright 2004 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. +# + +SUBDIRS = lib python diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am new file mode 100644 index 0000000..c6aa929 --- /dev/null +++ b/src/lib/Makefile.am @@ -0,0 +1,95 @@ +# +# 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 + +# 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) + +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_receiver.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_receiver.cc \ + gsm_receiver.py + +# This gets howto.py installed in the right place +ourpython_PYTHON = \ + gsm_receiver.py + +ourlib_LTLIBRARIES = _gsm_receiver.la + +# These are the source files that go into the shared library +_howto_la_SOURCES = \ + gsm_receiver.cc \ + gsm_receiver_cf.cc \ + gsm_receiver_cf.cc + +# magic flags +_gsm_receiver_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version + +# link the library against some comon swig runtime code and the +# c++ standard library +_gsm_receiver_la_LIBADD = \ + $(PYTHON_LDFLAGS) \ + -lstdc++ + +gsm_receiver.cc gsm_receiver.py: $(LOCAL_IFILES) $(ALL_IFILES) + $(SWIG) $(SWIGPYTHONARGS) -module howto -o gsm_receiver.cc $(LOCAL_IFILES) + +# These headers get installed in ${prefix}/include/gnuradio +grinclude_HEADERS = \ + gsm_receiver_cf.h \ + gsm_receiver_cf.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/gsm_receiver.h b/src/lib/gsm_receiver.h new file mode 100644 index 0000000..092b936 --- /dev/null +++ b/src/lib/gsm_receiver.h @@ -0,0 +1,78 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004 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. + */ +#ifndef INCLUDED_HOWTO_SQUARE_FF_H +#define INCLUDED_HOWTO_SQUARE_FF_H + +#include + +class howto_square_ff; + +/* + * We use boost::shared_ptr's instead of raw pointers for all access + * to gr_blocks (and many other data structures). The shared_ptr gets + * us transparent reference counting, which greatly simplifies storage + * management issues. This is especially helpful in our hybrid + * C++ / Python system. + * + * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm + * + * As a convention, the _sptr suffix indicates a boost::shared_ptr + */ +typedef boost::shared_ptr howto_square_ff_sptr; + +/*! + * \brief Return a shared_ptr to a new instance of howto_square_ff. + * + * To avoid accidental use of raw pointers, howto_square_ff's + * constructor is private. howto_make_square_ff is the public + * interface for creating new instances. + */ +howto_square_ff_sptr howto_make_square_ff (); + +/*! + * \brief square a stream of floats. + * \ingroup block + * + * \sa howto_square2_ff for a version that subclasses gr_sync_block. + */ +class howto_square_ff : public gr_block +{ +private: + // The friend declaration allows howto_make_square_ff to + // access the private constructor. + + friend howto_square_ff_sptr howto_make_square_ff (); + + howto_square_ff (); // private constructor + + public: + ~howto_square_ff (); // public destructor + + // Where all the action really happens + + 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_HOWTO_SQUARE_FF_H */ diff --git a/src/lib/gsm_receiver.i b/src/lib/gsm_receiver.i new file mode 100644 index 0000000..3d46ab4 --- /dev/null +++ b/src/lib/gsm_receiver.i @@ -0,0 +1,44 @@ +/* -*- c++ -*- */ + +%feature("autodoc", "1"); // generate python docstrings + +%include "exception.i" +%import "gnuradio.i" // the common stuff + +%{ +#include "gnuradio_swig_bug_workaround.h" // mandatory bug fix +#include "howto_square_ff.h" +#include "howto_square2_ff.h" +#include +%} + +// ---------------------------------------------------------------- + +/* + * First arg is the package prefix. + * Second arg is the name of the class minus the prefix. + * + * This does some behind-the-scenes magic so we can + * access howto_square_ff from python as howto.square_ff + */ +GR_SWIG_BLOCK_MAGIC(howto,square_ff); + +howto_square_ff_sptr howto_make_square_ff (); + +class howto_square_ff : public gr_block +{ +private: + howto_square_ff (); +}; + +// ---------------------------------------------------------------- + +GR_SWIG_BLOCK_MAGIC(howto,square2_ff); + +howto_square2_ff_sptr howto_make_square2_ff (); + +class howto_square2_ff : public gr_sync_block +{ +private: + howto_square2_ff (); +}; diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc new file mode 100644 index 0000000..7001b91 --- /dev/null +++ b/src/lib/gsm_receiver_cf.cc @@ -0,0 +1,93 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +/* + * Create a new instance of gsm_receiver and return + * a boost shared_ptr. This is effectively the public constructor. + */ +gsm_receiver_cf_sptr +gsm_receiver_make_cf () +{ + return gsm_receiver_cf_sptr (new gsm_receiver_cf ()); +} + +/* + * Specify constraints on number of input and output streams. + * This info is used to construct the input and output signatures + * (2nd & 3rd args to gr_block's constructor). The input and + * output signatures are used by the runtime system to + * check that a valid number and type of inputs and outputs + * are connected to this block. In this case, we accept + * only 1 input and 1 output. + */ +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 = 1; // 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_block ("gsm_receiver", + gr_make_io_signature (MIN_IN, MAX_IN, sizeof (gr_complex)), + gr_make_io_signature (MIN_OUT, MAX_OUT, sizeof (float))) +{ + // nothing else required in this example +} + +/* + * Our virtual destructor. + */ +gsm_receiver_square_ff::~gsm_receiver_cf () +{ + // nothing else required in this example +} + +int +gsm_receiver_cf::general_work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const float *in = (const float *) input_items[0]; + float *out = (float *) output_items[0]; + + for (int i = 0; i < noutput_items; i++){ + out[i] = in[i] * in[i]; + } + + // Tell runtime system how many input items we consumed on + // each input stream. + + consume_each (noutput_items); + + // Tell runtime system how many output items we produced. + return noutput_items; +} diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h new file mode 100644 index 0000000..c56a2f0 --- /dev/null +++ b/src/lib/gsm_receiver_cf.h @@ -0,0 +1,74 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004 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. + */ +#ifndef INCLUDED_GSM_RECEIVER_CF_H +#define INCLUDED_GSM_RECEIVER_CF_H + +#include +#include + +class gsm_receiver_cf.h; + +/* + * We use boost::shared_ptr's instead of raw pointers for all access + * to gr_blocks (and many other data structures). The shared_ptr gets + * us transparent reference counting, which greatly simplifies storage + * management issues. This is especially helpful in our hybrid + * C++ / Python system. + * + * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm + * + * As a convention, the _sptr suffix indicates a boost::shared_ptr + */ +typedef boost::shared_ptr gsm_receiver_cf_sptr; + +/*! + * \brief Return a shared_ptr to a new instance of gsm_receiver_cf. + * + * To avoid accidental use of raw pointers, gsm_receiver_cf's + * constructor is private. howto_make_square_ff is the public + * interface for creating new instances. + */ +gsm_receiver_cf_sptr gsm_receiver_make_square_cf (); + +/*! + * \brief square a stream of floats. + * \ingroup block + * + * \sa howto_square2_ff for a version that subclasses gr_sync_block. + */ +class gsm_receiver_cf : public gr_block +{ +private: + friend gsm_receiver_cf_sptr gsm_receiver_make_square_cf (); + + gsm_receiver_cf (); + + public: + ~gsm_receiver_cf (); + + 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 */ -- cgit v1.2.3 From f0457b0b5888fd4d652531b987c9d113e8d1234a Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Tue, 7 Apr 2009 17:25:12 +0200 Subject: New empty gsm-receiver signal block with its own library - compiles --- AUTHORS | 1 + CHANGELOG | 0 COPYING | 340 +++++++++++++++++++++++++++++++++++++++++++++ ChangeLog | 0 INSTALL | 236 +++++++++++++++++++++++++++++++ Makefile.am | 17 ++- NEWS | 0 README | 0 bootstrap | 72 ++++------ config/Makefile.am | 2 + config/acx_pthread.m4 | 190 +++++++++++++++++++++++++ config/lf_cc.m4 | 42 ++++++ configure.ac | 19 ++- py-compile | 146 +++++++++++++++++++ src/Makefile.am | 3 +- src/lib/Makefile.am | 16 ++- src/lib/gsm_receiver.h | 78 ----------- src/lib/gsm_receiver.i | 21 +-- src/lib/gsm_receiver_cf.cc | 8 +- src/lib/gsm_receiver_cf.h | 6 +- 20 files changed, 1034 insertions(+), 163 deletions(-) create mode 100644 AUTHORS create mode 100644 CHANGELOG create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 NEWS create mode 100644 README create mode 100644 config/acx_pthread.m4 create mode 100644 config/lf_cc.m4 create mode 100755 py-compile delete mode 100644 src/lib/gsm_receiver.h diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..944ad20 --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Piotr Krysik \ No newline at end of file diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..e69de29 diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..623b625 --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..23e5f25 --- /dev/null +++ b/INSTALL @@ -0,0 +1,236 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free +Software Foundation, Inc. + +This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + +These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + +Some systems require unusual options for compilation or linking that the +`configure' script does not know about. Run `./configure --help' for +details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + +You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + +By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + +Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + +There may be some features `configure' cannot figure out automatically, +but needs to determine by the type of machine the package will run on. +Usually, assuming the package is built to be run on the _same_ +architectures, `configure' can figure that out, but if it prints a +message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + +If you want to set default values for `configure' scripts to share, you +can create a site shell script called `config.site' that gives default +values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + +Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). Here is a another example: + + /bin/bash ./configure CONFIG_SHELL=/bin/bash + +Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent +configuration-related scripts to be executed by `/bin/bash'. + +`configure' Invocation +====================== + +`configure' recognizes the following options to control how it operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/Makefile.am b/Makefile.am index e659491..f940fe8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,8 +2,19 @@ include $(top_srcdir)/Makefile.common SUBDIRS = src config DIST_SUBDIRS = src config -EXTRA_DIST = bootstrap configure config.h.in -#nowe rzeczy +#EXTRA_DIST = \ +# bootstrap \ +# configure \ +# config.h.in +# gsm-receiver.pc.in + +#pkgconfigdir = $(libdir)/pkgconfig +#pkgconfig_DATA = gsm-receiver.pc + +EXTRA_DIST = \ + gsm-receiver.pc.in + pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = +pkgconfig_DATA = gsm-receiver.pc + \ No newline at end of file diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/README b/README new file mode 100644 index 0000000..e69de29 diff --git a/bootstrap b/bootstrap index 3ef4692..525a6b0 100755 --- a/bootstrap +++ b/bootstrap @@ -1,51 +1,29 @@ -#! /bin/bash +#!/bin/sh + +# Copyright 2001,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 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. + + +rm -fr config.cache autom4te*.cache -DIE=0 -touch README NEWS CHANGELOG -(autoconf --version) < /dev/null > /dev/null 2>&1 || { - echo - echo "You must have autoconf installed." - DIE=1 -} - -# libtool --version check not done... - -(automake --version) < /dev/null > /dev/null 2>&1 || { - echo - echo "You must have automake installed." - DIE=1 -} - -if test "$DIE" -eq 1; then - exit 1 -fi - -echo Removing old files... -rm -fr config.cache autom4te*.cache config.h config.status aclocal.m4 config.cache config.log - -if test ! -d config; then - mkdir config -fi -echo "aclocal -I config" aclocal -I config -if test $? -ne 0; then - exit 1 -fi -echo "autoheader" +autoconf autoheader -if test $? -ne 0; then - exit 1 -fi - -echo "libtoolize --automake" libtoolize --automake -automake --add-missing -c -f -Wno-portability -if test $? -ne 0; then - exit 1 -fi - -echo "autoconf" -autoconf -echo "BOOTSTRAP complete" - -#(cd gsm-tvoid ; ./bootstrap) \ No newline at end of file +automake --add-missing diff --git a/config/Makefile.am b/config/Makefile.am index 0b82ea3..1c99d68 100644 --- a/config/Makefile.am +++ b/config/Makefile.am @@ -26,6 +26,7 @@ m4datadir = $(datadir)/aclocal # List your m4 macros here m4macros = \ + acx_pthread.m4 \ bnv_have_qt.m4 \ cppunit.m4 \ gr_boost.m4 \ @@ -46,6 +47,7 @@ m4macros = \ gr_swig.m4 \ gr_sysv_shm.m4 \ gr_x86_64.m4 \ + lf_cc.m4 \ lf_cxx.m4 \ lf_warnings.m4 \ lf_x11.m4 \ diff --git a/config/acx_pthread.m4 b/config/acx_pthread.m4 new file mode 100644 index 0000000..d318ab0 --- /dev/null +++ b/config/acx_pthread.m4 @@ -0,0 +1,190 @@ +dnl Available from the GNU Autoconf Macro Archive at: +dnl http://www.gnu.org/software/ac-archive/htmldoc/acx_pthread.html +dnl +AC_DEFUN([ACX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_SAVE +AC_LANG_C +acx_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) + AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) + AC_MSG_RESULT($acx_pthread_ok) + if test x"$acx_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all. + +acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# pthread: Linux, etcetera +# --thread-safe: KAI C++ + +case "${host_cpu}-${host_os}" in + *solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthread or + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags" + ;; +esac + +if test x"$acx_pthread_ok" = xno; then +for flag in $acx_pthread_flags; do + + case $flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $flag]) + PTHREAD_CFLAGS="$flag" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$flag]) + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + AC_TRY_LINK([#include ], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], + [acx_pthread_ok=yes]) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + AC_MSG_RESULT($acx_pthread_ok) + if test "x$acx_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$acx_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: threads are created detached by default + # and the JOINABLE attribute has a nonstandard name (UNDETACHED). + AC_MSG_CHECKING([for joinable pthread attribute]) + AC_TRY_LINK([#include ], + [int attr=PTHREAD_CREATE_JOINABLE;], + ok=PTHREAD_CREATE_JOINABLE, ok=unknown) + if test x"$ok" = xunknown; then + AC_TRY_LINK([#include ], + [int attr=PTHREAD_CREATE_UNDETACHED;], + ok=PTHREAD_CREATE_UNDETACHED, ok=unknown) + fi + if test x"$ok" != xPTHREAD_CREATE_JOINABLE; then + AC_DEFINE(PTHREAD_CREATE_JOINABLE, $ok, + [Define to the necessary symbol if this constant + uses a non-standard name on your system.]) + fi + AC_MSG_RESULT(${ok}) + if test x"$ok" = xunknown; then + AC_MSG_WARN([we do not know how to create joinable pthreads]) + fi + + AC_MSG_CHECKING([if more special flags are required for pthreads]) + flag=no + case "${host_cpu}-${host_os}" in + *-aix* | *-freebsd*) flag="-D_THREAD_SAFE";; + *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; + esac + AC_MSG_RESULT(${flag}) + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + # More AIX lossage: must compile with cc_r + AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC}) +else + PTHREAD_CC="$CC" +fi + +AC_SUBST(PTHREAD_LIBS) +AC_SUBST(PTHREAD_CFLAGS) +AC_SUBST(PTHREAD_CC) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$acx_pthread_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) + : +else + acx_pthread_ok=no + $2 +fi +AC_LANG_RESTORE +])dnl ACX_PTHREAD diff --git a/config/lf_cc.m4 b/config/lf_cc.m4 new file mode 100644 index 0000000..b9d1c9c --- /dev/null +++ b/config/lf_cc.m4 @@ -0,0 +1,42 @@ +dnl Autoconf support for C++ +dnl Copyright (C) 1988 Eleftherios Gkioulekas +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301, USA. +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a configuration +dnl script generated by Autoconf, you may include it under the same +dnl distribution terms that you use for the rest of that program. + +# ------------------------------------------------------------------------- +# Use this macro to configure your C compiler +# When called the macro does the following things: +# 1. It finds an appropriate C compiler. +# If you passed the flag --with-cc=foo then it uses that +# particular compiler +# 2. Check whether the compiler works. +# 3. Checks whether the compiler accepts the -g +# ------------------------------------------------------------------------- + +AC_DEFUN([LF_CONFIGURE_CC],[ + dnl Sing the song + AC_REQUIRE([AC_PROG_CC])dnl + AC_REQUIRE([AC_PROG_CPP])dnl + AC_REQUIRE([AC_AIX])dnl + AC_REQUIRE([AC_ISC_POSIX])dnl + AC_REQUIRE([AC_MINIX])dnl + AC_REQUIRE([AC_HEADER_STDC])dnl +]) + diff --git a/configure.ac b/configure.ac index 1eef1e4..f7a2f6d 100644 --- a/configure.ac +++ b/configure.ac @@ -31,6 +31,16 @@ GR_X86_64 dnl LF_CONFIGURE_CC LF_CONFIGURE_CXX LF_SET_WARNINGS + +dnl add ${prefix}/lib${gr_libdir_suffix}/pkgconfig to the head of the PKG_CONFIG_PATH +if test x${PKG_CONFIG_PATH} = x; then + PKG_CONFIG_PATH=${prefix}/lib${gr_libdir_suffix}/pkgconfig +else + PKG_CONFIG_PATH=${prefix}/lib${gr_libdir_suffix}/pkgconfig:${PKG_CONFIG_PATH} +fi +export PKG_CONFIG_PATH + + GR_SET_GPROF GR_SET_PROF AM_PROG_AS @@ -93,14 +103,15 @@ AC_SUBST(STD_DEFINES_AND_INCLUDES) AC_CONFIG_FILES([\ Makefile \ config/Makefile \ - doc/Makefile \ src/Makefile \ src/lib/Makefile \ - src/python/Makefile \ - src/python/run_tests \ + gsm-receiver.pc \ ]) +# doc/Makefile \ +# src/python/Makefile \ +# src/python/run_tests \ dnl run_tests is created from run_tests.in. Make it executable. -AC_CONFIG_COMMANDS([run_tests], [chmod +x src/python/run_tests]) +#AC_CONFIG_COMMANDS([run_tests], [chmod +x src/python/run_tests]) AC_OUTPUT diff --git a/py-compile b/py-compile new file mode 100755 index 0000000..d6e900b --- /dev/null +++ b/py-compile @@ -0,0 +1,146 @@ +#!/bin/sh +# py-compile - Compile a Python program + +scriptversion=2005-05-14.22 + +# Copyright (C) 2000, 2001, 2003, 2004, 2005 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 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +if [ -z "$PYTHON" ]; then + PYTHON=python +fi + +basedir= +destdir= +files= +while test $# -ne 0; do + case "$1" in + --basedir) + basedir=$2 + if test -z "$basedir"; then + echo "$0: Missing argument to --basedir." 1>&2 + exit 1 + fi + shift + ;; + --destdir) + destdir=$2 + if test -z "$destdir"; then + echo "$0: Missing argument to --destdir." 1>&2 + exit 1 + fi + shift + ;; + -h|--h*) + cat <<\EOF +Usage: py-compile [--help] [--version] [--basedir DIR] [--destdir DIR] FILES..." + +Byte compile some python scripts FILES. Use --destdir to specify any +leading directory path to the FILES that you don't want to include in the +byte compiled file. Specify --basedir for any additional path information you +do want to be shown in the byte compiled file. + +Example: + py-compile --destdir /tmp/pkg-root --basedir /usr/share/test test.py test2.py + +Report bugs to . +EOF + exit $? + ;; + -v|--v*) + echo "py-compile $scriptversion" + exit $? + ;; + *) + files="$files $1" + ;; + esac + shift +done + +if test -z "$files"; then + echo "$0: No files given. Try \`$0 --help' for more information." 1>&2 + exit 1 +fi + +# if basedir was given, then it should be prepended to filenames before +# byte compilation. +if [ -z "$basedir" ]; then + pathtrans="path = file" +else + pathtrans="path = os.path.join('$basedir', file)" +fi + +# if destdir was given, then it needs to be prepended to the filename to +# byte compile but not go into the compiled file. +if [ -z "$destdir" ]; then + filetrans="filepath = path" +else + filetrans="filepath = os.path.normpath('$destdir' + os.sep + path)" +fi + +$PYTHON -c " +import sys, os, string, py_compile + +files = '''$files''' + +print 'Byte-compiling python modules...' +for file in string.split(files): + $pathtrans + $filetrans + if not os.path.exists(filepath) or not (len(filepath) >= 3 + and filepath[-3:] == '.py'): + continue + print file, + sys.stdout.flush() + py_compile.compile(filepath, filepath + 'c', path) +print" || exit $? + +# this will fail for python < 1.5, but that doesn't matter ... +$PYTHON -O -c " +import sys, os, string, py_compile + +files = '''$files''' +print 'Byte-compiling python modules (optimized versions) ...' +for file in string.split(files): + $pathtrans + $filetrans + if not os.path.exists(filepath) or not (len(filepath) >= 3 + and filepath[-3:] == '.py'): + continue + print file, + sys.stdout.flush() + py_compile.compile(filepath, filepath + 'o', path) +print" 2>/dev/null || : + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/src/Makefile.am b/src/Makefile.am index e3f0399..3ff9849 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,4 +19,5 @@ # Boston, MA 02110-1301, USA. # -SUBDIRS = lib python +SUBDIRS = lib + diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index c6aa929..fb63599 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -58,10 +58,13 @@ ourpython_PYTHON = \ ourlib_LTLIBRARIES = _gsm_receiver.la +lib_LTLIBRARIES = libgsm-receiver.la + # These are the source files that go into the shared library -_howto_la_SOURCES = \ - gsm_receiver.cc \ - gsm_receiver_cf.cc \ +_gsm_receiver_la_SOURCES = \ + gsm_receiver.cc + +libgsm_receiver_la_SOURCES = \ gsm_receiver_cf.cc # magic flags @@ -71,17 +74,18 @@ _gsm_receiver_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version # c++ standard library _gsm_receiver_la_LIBADD = \ $(PYTHON_LDFLAGS) \ + libgsm-receiver.la \ -lstdc++ +#libgsm_receiver_la_LIBADD = + gsm_receiver.cc gsm_receiver.py: $(LOCAL_IFILES) $(ALL_IFILES) - $(SWIG) $(SWIGPYTHONARGS) -module howto -o gsm_receiver.cc $(LOCAL_IFILES) + $(SWIG) $(SWIGPYTHONARGS) -module gsm_receiver -o gsm_receiver.cc $(LOCAL_IFILES) # These headers get installed in ${prefix}/include/gnuradio grinclude_HEADERS = \ - gsm_receiver_cf.h \ gsm_receiver_cf.h - # These swig headers get installed in ${prefix}/include/gnuradio/swig swiginclude_HEADERS = \ $(LOCAL_IFILES) diff --git a/src/lib/gsm_receiver.h b/src/lib/gsm_receiver.h deleted file mode 100644 index 092b936..0000000 --- a/src/lib/gsm_receiver.h +++ /dev/null @@ -1,78 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 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. - */ -#ifndef INCLUDED_HOWTO_SQUARE_FF_H -#define INCLUDED_HOWTO_SQUARE_FF_H - -#include - -class howto_square_ff; - -/* - * We use boost::shared_ptr's instead of raw pointers for all access - * to gr_blocks (and many other data structures). The shared_ptr gets - * us transparent reference counting, which greatly simplifies storage - * management issues. This is especially helpful in our hybrid - * C++ / Python system. - * - * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm - * - * As a convention, the _sptr suffix indicates a boost::shared_ptr - */ -typedef boost::shared_ptr howto_square_ff_sptr; - -/*! - * \brief Return a shared_ptr to a new instance of howto_square_ff. - * - * To avoid accidental use of raw pointers, howto_square_ff's - * constructor is private. howto_make_square_ff is the public - * interface for creating new instances. - */ -howto_square_ff_sptr howto_make_square_ff (); - -/*! - * \brief square a stream of floats. - * \ingroup block - * - * \sa howto_square2_ff for a version that subclasses gr_sync_block. - */ -class howto_square_ff : public gr_block -{ -private: - // The friend declaration allows howto_make_square_ff to - // access the private constructor. - - friend howto_square_ff_sptr howto_make_square_ff (); - - howto_square_ff (); // private constructor - - public: - ~howto_square_ff (); // public destructor - - // Where all the action really happens - - 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_HOWTO_SQUARE_FF_H */ diff --git a/src/lib/gsm_receiver.i b/src/lib/gsm_receiver.i index 3d46ab4..d5ca598 100644 --- a/src/lib/gsm_receiver.i +++ b/src/lib/gsm_receiver.i @@ -7,8 +7,7 @@ %{ #include "gnuradio_swig_bug_workaround.h" // mandatory bug fix -#include "howto_square_ff.h" -#include "howto_square2_ff.h" +#include "gsm_receiver_cf.h" #include %} @@ -21,24 +20,14 @@ * This does some behind-the-scenes magic so we can * access howto_square_ff from python as howto.square_ff */ -GR_SWIG_BLOCK_MAGIC(howto,square_ff); +GR_SWIG_BLOCK_MAGIC(gsm,receiver_cf); -howto_square_ff_sptr howto_make_square_ff (); +gsm_receiver_cf_sptr gsm_make_receiver_cf (); -class howto_square_ff : public gr_block +class gsm_receiver_cf : public gr_block { private: - howto_square_ff (); + gsm_receiver_cf (); }; // ---------------------------------------------------------------- - -GR_SWIG_BLOCK_MAGIC(howto,square2_ff); - -howto_square2_ff_sptr howto_make_square2_ff (); - -class howto_square2_ff : public gr_sync_block -{ -private: - howto_square2_ff (); -}; diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 7001b91..6ea2ba7 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -32,7 +32,7 @@ * a boost shared_ptr. This is effectively the public constructor. */ gsm_receiver_cf_sptr -gsm_receiver_make_cf () +gsm_make_receiver_cf () { return gsm_receiver_cf_sptr (new gsm_receiver_cf ()); } @@ -59,15 +59,13 @@ gsm_receiver_cf::gsm_receiver_cf () gr_make_io_signature (MIN_IN, MAX_IN, sizeof (gr_complex)), gr_make_io_signature (MIN_OUT, MAX_OUT, sizeof (float))) { - // nothing else required in this example } /* - * Our virtual destructor. + * Virtual destructor. */ -gsm_receiver_square_ff::~gsm_receiver_cf () +gsm_receiver_cf::~gsm_receiver_cf () { - // nothing else required in this example } int diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index c56a2f0..f45e47a 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -25,7 +25,7 @@ #include #include -class gsm_receiver_cf.h; +class gsm_receiver_cf; /* * We use boost::shared_ptr's instead of raw pointers for all access @@ -47,7 +47,7 @@ typedef boost::shared_ptr gsm_receiver_cf_sptr; * constructor is private. howto_make_square_ff is the public * interface for creating new instances. */ -gsm_receiver_cf_sptr gsm_receiver_make_square_cf (); +gsm_receiver_cf_sptr gsm_make_receiver_cf (); /*! * \brief square a stream of floats. @@ -58,7 +58,7 @@ gsm_receiver_cf_sptr gsm_receiver_make_square_cf (); class gsm_receiver_cf : public gr_block { private: - friend gsm_receiver_cf_sptr gsm_receiver_make_square_cf (); + friend gsm_receiver_cf_sptr gsm_make_receiver_cf (); gsm_receiver_cf (); -- cgit v1.2.3 From e62955ea001505afbce29d9beb41c137a0979529 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Tue, 7 Apr 2009 22:00:47 +0200 Subject: Changes to buildsystem --- configure.ac | 2 +- src/lib/Makefile.am | 30 +++++++++++++++--------------- src/lib/gsm_receiver.i | 33 --------------------------------- 3 files changed, 16 insertions(+), 49 deletions(-) delete mode 100644 src/lib/gsm_receiver.i diff --git a/configure.ac b/configure.ac index f7a2f6d..b3b1f16 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ dnl AC_INIT AC_PREREQ(2.61) -AC_CONFIG_SRCDIR([src/lib/gsm_receiver.i]) +AC_CONFIG_SRCDIR([src/lib/gsm.i]) AM_CONFIG_HEADER(config.h) AC_CANONICAL_TARGET([]) AC_CONFIG_AUX_DIR([.]) diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index fb63599..bec9b80 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -42,45 +42,45 @@ NON_LOCAL_IFILES = \ LOCAL_IFILES = \ - $(top_srcdir)/src/lib/gsm_receiver.i + $(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_receiver.cc \ - gsm_receiver.py + gsm.cc \ + gsm.py # This gets howto.py installed in the right place ourpython_PYTHON = \ - gsm_receiver.py + gsm.py -ourlib_LTLIBRARIES = _gsm_receiver.la +ourlib_LTLIBRARIES = _gsm.la -lib_LTLIBRARIES = libgsm-receiver.la +lib_LTLIBRARIES = libgsmdemod.la # These are the source files that go into the shared library -_gsm_receiver_la_SOURCES = \ - gsm_receiver.cc +_gsm_la_SOURCES = \ + gsm.cc -libgsm_receiver_la_SOURCES = \ +libgsmdemod_la_SOURCES = \ gsm_receiver_cf.cc # magic flags -_gsm_receiver_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version +_gsm_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version # link the library against some comon swig runtime code and the # c++ standard library -_gsm_receiver_la_LIBADD = \ +_gsm_la_LIBADD = \ $(PYTHON_LDFLAGS) \ - libgsm-receiver.la \ + libgsmdemod.la \ -lstdc++ -#libgsm_receiver_la_LIBADD = +#libgsmdemod_la_LIBADD = -gsm_receiver.cc gsm_receiver.py: $(LOCAL_IFILES) $(ALL_IFILES) - $(SWIG) $(SWIGPYTHONARGS) -module gsm_receiver -o gsm_receiver.cc $(LOCAL_IFILES) +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 = \ diff --git a/src/lib/gsm_receiver.i b/src/lib/gsm_receiver.i deleted file mode 100644 index d5ca598..0000000 --- a/src/lib/gsm_receiver.i +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- c++ -*- */ - -%feature("autodoc", "1"); // generate python docstrings - -%include "exception.i" -%import "gnuradio.i" // the common stuff - -%{ -#include "gnuradio_swig_bug_workaround.h" // mandatory bug fix -#include "gsm_receiver_cf.h" -#include -%} - -// ---------------------------------------------------------------- - -/* - * First arg is the package prefix. - * Second arg is the name of the class minus the prefix. - * - * This does some behind-the-scenes magic so we can - * access howto_square_ff from python as howto.square_ff - */ -GR_SWIG_BLOCK_MAGIC(gsm,receiver_cf); - -gsm_receiver_cf_sptr gsm_make_receiver_cf (); - -class gsm_receiver_cf : public gr_block -{ -private: - gsm_receiver_cf (); -}; - -// ---------------------------------------------------------------- -- cgit v1.2.3 From ab5cd655f7ca398e9d92fde4faf291b0d7e6fb0d Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Wed, 8 Apr 2009 16:35:13 +0200 Subject: removed unneded comments --- src/lib/gsm_receiver_cf.cc | 13 ------------- src/lib/gsm_receiver_cf.h | 8 ++++---- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 6ea2ba7..821c929 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -27,25 +27,12 @@ #include #include -/* - * Create a new instance of gsm_receiver and return - * a boost shared_ptr. This is effectively the public constructor. - */ gsm_receiver_cf_sptr gsm_make_receiver_cf () { return gsm_receiver_cf_sptr (new gsm_receiver_cf ()); } -/* - * Specify constraints on number of input and output streams. - * This info is used to construct the input and output signatures - * (2nd & 3rd args to gr_block's constructor). The input and - * output signatures are used by the runtime system to - * check that a valid number and type of inputs and outputs - * are connected to this block. In this case, we accept - * only 1 input and 1 output. - */ 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 = 1; // minimum number of output streams diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index f45e47a..3b4ffc6 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -1,19 +1,19 @@ /* -*- c++ -*- */ /* * Copyright 2004 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, -- cgit v1.2.3 From deb7ffac0f3d8af59fddae0c9d08a3b0654206d1 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Wed, 8 Apr 2009 16:35:59 +0200 Subject: Added FCCH search function from tvoid --- src/lib/gsm_receiver_cf.cc | 49 ++++++++++++++++++++++++++++++++++++++++++---- src/lib/gsm_receiver_cf.h | 28 ++++++++++++++------------ 2 files changed, 60 insertions(+), 17 deletions(-) diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 821c929..e478c66 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -68,11 +68,52 @@ gsm_receiver_cf::general_work (int noutput_items, out[i] = in[i] * in[i]; } - // Tell runtime system how many input items we consumed on - // each input stream. - consume_each (noutput_items); - // Tell runtime system how many output items we produced. return noutput_items; } + + +bool gsm_receiver_cf::get_fcch_burst() +{ + int hit_count = 0; + int miss_count = 0; + int start_pos = -1; +/* + for ( int i=0; i < BBUF_SIZE; i++ ) { + if ( d_burst_buffer[i] > 0 ) { + if ( ! hit_count++ ) + start_pos = i; + } else { + if ( hit_count >= FCCH_HITS_NEEDED ) { + break; + } else + if ( ++miss_count > FCCH_MAX_MISSES ) { + start_pos = -1; + hit_count = miss_count = 0; + } + } + } + + //Do we have a match? + if ( start_pos >= 0 ) { + //Is it within range? (we know it's long enough then too) + if ( start_pos < 2*MAX_CORR_DIST ) { + d_burst_start = start_pos; + d_bbuf_pos = 0; //load buffer from start + return FCCH; + + } else { + //TODO: don't shift a tiny amount + shift_burst( start_pos - MAX_CORR_DIST ); + } + } else { + //Didn't find anything + d_burst_start = MAX_CORR_DIST; + d_bbuf_pos = 0; //load buffer from start + } + + return UNKNOWN; +*/ +} + diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index 3b4ffc6..7067fb2 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -47,28 +47,30 @@ typedef boost::shared_ptr gsm_receiver_cf_sptr; * constructor is private. howto_make_square_ff is the public * interface for creating new instances. */ -gsm_receiver_cf_sptr gsm_make_receiver_cf (); +gsm_receiver_cf_sptr gsm_make_receiver_cf(); /*! - * \brief square a stream of floats. + * \brief Receives fcch * \ingroup block - * - * \sa howto_square2_ff for a version that subclasses gr_sync_block. + * \sa */ + class gsm_receiver_cf : public gr_block { -private: - friend gsm_receiver_cf_sptr gsm_make_receiver_cf (); - gsm_receiver_cf (); + private: + friend gsm_receiver_cf_sptr gsm_make_receiver_cf(); + + gsm_receiver_cf(); + bool get_fcch_burst(); - public: - ~gsm_receiver_cf (); + public: + ~gsm_receiver_cf(); - int general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); + 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 */ -- cgit v1.2.3 From 04c193d15192d926c7349ca4a9362d721fe0db6c Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Fri, 10 Apr 2009 17:22:31 +0200 Subject: added frequency burst detection, but not yet finished --- configure.ac | 3 +- src/Makefile.am | 2 +- src/lib/gsm_receiver_cf.cc | 141 +++++++++++++++++++++++++++------------------ src/lib/gsm_receiver_cf.h | 19 +++--- 4 files changed, 100 insertions(+), 65 deletions(-) diff --git a/configure.ac b/configure.ac index b3b1f16..556d5c5 100644 --- a/configure.ac +++ b/configure.ac @@ -105,10 +105,11 @@ AC_CONFIG_FILES([\ config/Makefile \ src/Makefile \ src/lib/Makefile \ + src/python/Makefile \ gsm-receiver.pc \ + ]) # doc/Makefile \ -# src/python/Makefile \ # src/python/run_tests \ dnl run_tests is created from run_tests.in. Make it executable. diff --git a/src/Makefile.am b/src/Makefile.am index 3ff9849..79cfa3e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,5 +19,5 @@ # Boston, MA 02110-1301, USA. # -SUBDIRS = lib +SUBDIRS = lib python diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index e478c66..206bd5e 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -1,19 +1,19 @@ /* -*- c++ -*- */ /* * Copyright 2004 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, @@ -26,94 +26,123 @@ #include #include +#include +#include +#include -gsm_receiver_cf_sptr -gsm_make_receiver_cf () + +gsm_receiver_cf_sptr +gsm_make_receiver_cf(int osr) { - return gsm_receiver_cf_sptr (new gsm_receiver_cf ()); + return gsm_receiver_cf_sptr(new gsm_receiver_cf(osr)); } -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 = 1; // minimum number of output streams -static const int MAX_OUT = 1; // maximum number of output streams +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_block ("gsm_receiver", - gr_make_io_signature (MIN_IN, MAX_IN, sizeof (gr_complex)), - gr_make_io_signature (MIN_OUT, MAX_OUT, sizeof (float))) +gsm_receiver_cf::gsm_receiver_cf(int osr) + : 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_counter(0) { } /* * Virtual destructor. */ -gsm_receiver_cf::~gsm_receiver_cf () +gsm_receiver_cf::~gsm_receiver_cf() +{ +} + +void gsm_receiver_cf::forecast(int noutput_items, gr_vector_int &ninput_items_required) { + ninput_items_required[0] = noutput_items * TS_BITS; //TODO include oversampling ratio here } -int -gsm_receiver_cf::general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) +int +gsm_receiver_cf::general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { - const float *in = (const float *) input_items[0]; + const gr_complex *in = (const gr_complex *) input_items[0]; float *out = (float *) output_items[0]; - for (int i = 0; i < noutput_items; i++){ - out[i] = in[i] * in[i]; - } +// DCOUT(ninput_items[0]); +// DCOUT(noutput_items); - consume_each (noutput_items); - return noutput_items; + d_return = 0; //! + int start_pos = find_fcch_burst(in, ninput_items[0]); + for (int i = 0; i < TS_BITS; i++) { + out[i] = d_phase_diff_buffer[i+start_pos-USEFUL_BITS]; + } + consume_each(start_pos); + d_counter += start_pos; + return d_return; } - -bool gsm_receiver_cf::get_fcch_burst() +int gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) { + for (int i = 0; (i < nitems - 1) && (i < BUFFER_SIZE); i++) { + gr_complex conjprod = in[i+1] * conj(in[i]); + float diff_angle = gr_fast_atan2f(imag(conjprod), real(conjprod)); + d_phase_diff_buffer[i] = diff_angle; + } + int hit_count = 0; int miss_count = 0; int start_pos = -1; -/* - for ( int i=0; i < BBUF_SIZE; i++ ) { - if ( d_burst_buffer[i] > 0 ) { - if ( ! hit_count++ ) - start_pos = i; - } else { - if ( hit_count >= FCCH_HITS_NEEDED ) { - break; - } else - if ( ++miss_count > FCCH_MAX_MISSES ) { - start_pos = -1; - hit_count = miss_count = 0; - } - } + + d_return = 0;//! + + for (int i = 0; ; i++) { + if (i > nitems - USEFUL_BITS - 1) { + start_pos = nitems - USEFUL_BITS - 1; + break; } - //Do we have a match? - if ( start_pos >= 0 ) { + if (d_phase_diff_buffer[i] > 0) { + if (! hit_count) { + start_pos = i+USEFUL_BITS; + } + hit_count++; + } else if (hit_count >= FCCH_HITS_NEEDED) { + DCOUT("znalezione fcch na pozycji" << d_counter+start_pos-USEFUL_BITS); + d_return = 1;//! + break; + } else if (++miss_count > FCCH_MAX_MISSES) { + start_pos = -1; + hit_count = miss_count = 0; + } + } + + /* + //Do we have a match? + if (start_pos >= 0) { //Is it within range? (we know it's long enough then too) - if ( start_pos < 2*MAX_CORR_DIST ) { - d_burst_start = start_pos; - d_bbuf_pos = 0; //load buffer from start - return FCCH; - - } else { - //TODO: don't shift a tiny amount - shift_burst( start_pos - MAX_CORR_DIST ); - } + if (start_pos < 2*MAX_CORR_DIST) { + d_burst_start = start_pos; + d_bbuf_pos = 0; //load buffer from start + return FCCH; + } else { + //TODO: don't shift a tiny amount + shift_burst(start_pos - MAX_CORR_DIST); + } } else { //Didn't find anything d_burst_start = MAX_CORR_DIST; d_bbuf_pos = 0; //load buffer from start } + */ + //DCOUT("start_pos: " << start_pos); - return UNKNOWN; -*/ + return start_pos; } diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index 7067fb2..5bc7617 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -25,6 +25,8 @@ #include #include +#define BUFFER_SIZE 4096 + class gsm_receiver_cf; /* @@ -47,26 +49,29 @@ typedef boost::shared_ptr gsm_receiver_cf_sptr; * constructor is private. howto_make_square_ff is the public * interface for creating new instances. */ -gsm_receiver_cf_sptr gsm_make_receiver_cf(); +gsm_receiver_cf_sptr gsm_make_receiver_cf( int osr ); /*! * \brief Receives fcch * \ingroup block - * \sa + * \sa */ class gsm_receiver_cf : public gr_block { private: - friend gsm_receiver_cf_sptr gsm_make_receiver_cf(); - - gsm_receiver_cf(); - bool get_fcch_burst(); + int d_counter; + int d_return; + float d_phase_diff_buffer[BUFFER_SIZE]; + + friend gsm_receiver_cf_sptr gsm_make_receiver_cf( int osr ); + gsm_receiver_cf( int osr ); + int find_fcch_burst( const gr_complex *in, const int items ); 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, -- cgit v1.2.3 From 00cf03a40f5ddee09aadec5a45d6bb311d170bbd Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Mon, 20 Apr 2009 19:49:01 +0200 Subject: Corrected precision of FCCH search function --- src/lib/gsm_receiver_cf.cc | 257 ++++++++++++++++++++++++++++++---------- src/lib/gsm_receiver_cf.h | 32 +++-- src/python/cfile | Bin 0 -> 640000 bytes src/python/gsm_findfcch.py | 108 +++++++++++++++++ src/python/gsm_findfcch_usrp.py | 122 +++++++++++++++++++ 5 files changed, 450 insertions(+), 69 deletions(-) create mode 100644 src/python/cfile create mode 100755 src/python/gsm_findfcch.py create mode 100755 src/python/gsm_findfcch_usrp.py diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 206bd5e..4f43f2b 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -27,14 +27,18 @@ #include #include #include +#include #include #include +#include +#define SAFETY_MARGIN 50 +#define BUFFER_SIZE (FCCH_HITS_NEEDED) gsm_receiver_cf_sptr -gsm_make_receiver_cf(int osr) +gsm_make_receiver_cf(gr_feval_dd *tuner, int osr) { - return gsm_receiver_cf_sptr(new gsm_receiver_cf(osr)); + return gsm_receiver_cf_sptr(new gsm_receiver_cf(tuner, osr)); } static const int MIN_IN = 1; // mininum number of input streams @@ -45,11 +49,19 @@ static const int MAX_OUT = 1; // maximum number of output streams /* * The private constructor */ -gsm_receiver_cf::gsm_receiver_cf(int osr) +gsm_receiver_cf::gsm_receiver_cf(gr_feval_dd *tuner, int osr) : 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_counter(0) + d_osr(osr), + d_tuner(tuner), + d_prev_freq_offset(0), + d_phase_diff_buffer(BUFFER_SIZE), + d_counter(0), + d_x_temp(0), + d_x2_temp(0), + d_fcch_count(0), + d_state(fcch_search) { } @@ -73,76 +85,199 @@ gsm_receiver_cf::general_work(int noutput_items, { const gr_complex *in = (const gr_complex *) input_items[0]; float *out = (float *) output_items[0]; + int produced_out; -// DCOUT(ninput_items[0]); -// DCOUT(noutput_items); + switch (d_state) { + case fcch_search: - d_return = 0; //! - int start_pos = find_fcch_burst(in, ninput_items[0]); - for (int i = 0; i < TS_BITS; i++) { - out[i] = d_phase_diff_buffer[i+start_pos-USEFUL_BITS]; + if (find_fcch_burst(in, ninput_items[0])) { + produced_out = 1; + d_state = fcch_search; + } else { + produced_out = 0; + d_state = fcch_search; + } + + break; + + case sch_search: + break; } - consume_each(start_pos); - d_counter += start_pos; - return d_return; + +// for (int i = 0; i < TS_BITS; i++) { +// out[i] = d_phase_diff_buffer[i+start_pos-USEFUL_BITS]; +// } + + return produced_out; } -int gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) +bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) { - for (int i = 0; (i < nitems - 1) && (i < BUFFER_SIZE); i++) { - gr_complex conjprod = in[i+1] * conj(in[i]); - float diff_angle = gr_fast_atan2f(imag(conjprod), real(conjprod)); - d_phase_diff_buffer[i] = diff_angle; - } + float phase_diff = 0; + gr_complex conjprod; + int hit_count, miss_count, start_pos; + float min_phase_diff, max_phase_diff, lowest_max_min_diff; + float sum, best_sum; - int hit_count = 0; - int miss_count = 0; - int start_pos = -1; + int to_consume = 0; + int i = 0; + bool end = false; + bool result; - d_return = 0;//! - - for (int i = 0; ; i++) { - if (i > nitems - USEFUL_BITS - 1) { - start_pos = nitems - USEFUL_BITS - 1; - break; - } + circular_buffer_float::iterator buffer_iter; - if (d_phase_diff_buffer[i] > 0) { - if (! hit_count) { - start_pos = i+USEFUL_BITS; - } - hit_count++; - } else if (hit_count >= FCCH_HITS_NEEDED) { - DCOUT("znalezione fcch na pozycji" << d_counter+start_pos-USEFUL_BITS); - d_return = 1;//! - break; - } else if (++miss_count > FCCH_MAX_MISSES) { - start_pos = -1; - hit_count = miss_count = 0; + enum states { + init, search, found_something, fcch_found, search_fail + } fcch_search_state; + + fcch_search_state = init; + + while ((!end) && (i < nitems)) { + switch (fcch_search_state) { + + case init: + hit_count = 0; + miss_count = 0; + start_pos = -1; + lowest_max_min_diff = 99999; + d_phase_diff_buffer.clear(); + fcch_search_state = search; + + break; + + case search: + i++; + + if (i > nitems - BUFFER_SIZE) { + to_consume = i; + fcch_search_state = search_fail; + } + + conjprod = in[i] * conj(in[i-1]); + + phase_diff = gr_fast_atan2f(imag(conjprod), real(conjprod)); + + if (phase_diff > 0) { +// start_pos = i - 1; + to_consume = i; + fcch_search_state = found_something; + } else { + fcch_search_state = search; + } + + break; + + case found_something: + + if (phase_diff > 0) { + hit_count++; + } else { + miss_count++; + } + + //DCOUT("d_phase_diff_buffer.size(): " << d_phase_diff_buffer.size() << " hit_count: " << hit_count); + + if ((miss_count >= FCCH_MAX_MISSES) && (hit_count <= FCCH_HITS_NEEDED)) { + fcch_search_state = init; + continue; + } else if ((miss_count >= FCCH_MAX_MISSES) && (hit_count > FCCH_HITS_NEEDED)) { + fcch_search_state = fcch_found; + continue; + } else if ((miss_count < FCCH_MAX_MISSES) && (hit_count > FCCH_HITS_NEEDED)) { + //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(d_phase_diff_buffer.begin(), d_phase_diff_buffer.end())); + max_phase_diff = *(max_element(d_phase_diff_buffer.begin(), d_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 = i - FCCH_HITS_NEEDED; + d_best_sum = 0; + for (buffer_iter = (d_phase_diff_buffer.begin()); + buffer_iter != (d_phase_diff_buffer.end()); + buffer_iter++) { + d_best_sum += *buffer_iter; + } + DCOUT(d_best_sum); + } + } + + i++; + + if (i >= nitems) { + fcch_search_state = search_fail; + continue; + } + + conjprod = in[i] * conj(in[i-1]); + phase_diff = gr_fast_atan2f(imag(conjprod), real(conjprod)); + d_phase_diff_buffer.push_back(phase_diff); + + fcch_search_state = found_something; + + break; + + case fcch_found: + DCOUT("znalezione fcch na pozycji" << d_counter + start_pos); + to_consume = start_pos + FCCH_HITS_NEEDED + 1; + /* mean = d_best_sum / FCCH_HITS_NEEDED; + phase_offset = mean - (M_PI / 2); + freq_offset = phase_offset * 1625000.0 / (12.0 * M_PI);*/ + compute_freq_offset(); + end = true; + result = true; + break; + + case search_fail: + end = true; + result = false; + break; } } - /* - //Do we have a match? - if (start_pos >= 0) { - //Is it within range? (we know it's long enough then too) - if (start_pos < 2*MAX_CORR_DIST) { - d_burst_start = start_pos; - d_bbuf_pos = 0; //load buffer from start - return FCCH; - } else { - //TODO: don't shift a tiny amount - shift_burst(start_pos - MAX_CORR_DIST); - } - } else { - //Didn't find anything - d_burst_start = MAX_CORR_DIST; - d_bbuf_pos = 0; //load buffer from start - } - */ - //DCOUT("start_pos: " << start_pos); + d_counter += to_consume; + consume_each(to_consume); + + return result; +} + +bool find_sch_burst( const gr_complex *in, const int nitems , gr_complex *out); + + +double gsm_receiver_cf::compute_freq_offset() +{ + float mean, phase_offset, freq_offset; + + DCOUT(" d_phase_diff_buffer.size(): " << d_phase_diff_buffer.size()); + + mean = d_best_sum / FCCH_HITS_NEEDED; + phase_offset = mean - (M_PI / 2); + freq_offset = phase_offset * 1625000.0 / (12.0 * M_PI); + DCOUT("freq_offset: " << freq_offset); + d_fcch_count++; + d_x_temp += freq_offset; + d_x2_temp += freq_offset * freq_offset; + d_mean = d_x_temp / d_fcch_count; + //d_mean = 0.9 * freq_offset + 0.1 * d_mean; + + + //d_tuner->calleval(freq_offset); + + d_prev_freq_offset -= freq_offset; + + DCOUT("wariancja: " << sqrt((d_x2_temp / d_fcch_count - d_mean * d_mean)) << " fcch_count:" << d_fcch_count << " d_mean: " << d_mean); - return start_pos; + return freq_offset; } +void gsm_receiver_cf::set_frequency() +{ + +} + +bool gsm_receiver_cf::find_sch_burst( const gr_complex *in, const int nitems , gr_complex *out) +{ + +} diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index 5bc7617..2012325 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -24,8 +24,8 @@ #include #include - -#define BUFFER_SIZE 4096 +#include +#include class gsm_receiver_cf; @@ -42,6 +42,8 @@ class gsm_receiver_cf; */ typedef boost::shared_ptr gsm_receiver_cf_sptr; +typedef boost::circular_buffer circular_buffer_float; + /*! * \brief Return a shared_ptr to a new instance of gsm_receiver_cf. * @@ -49,7 +51,7 @@ typedef boost::shared_ptr gsm_receiver_cf_sptr; * constructor is private. howto_make_square_ff is the public * interface for creating new instances. */ -gsm_receiver_cf_sptr gsm_make_receiver_cf( int osr ); +gsm_receiver_cf_sptr gsm_make_receiver_cf( gr_feval_dd *tuner, int osr ); /*! * \brief Receives fcch @@ -61,13 +63,27 @@ class gsm_receiver_cf : public gr_block { private: + gr_feval_dd *d_tuner; + const int d_osr; int d_counter; - int d_return; - float d_phase_diff_buffer[BUFFER_SIZE]; + float d_prev_freq_offset; + circular_buffer_float d_phase_diff_buffer; + double d_x_temp, d_x2_temp, d_mean; + int d_fcch_count; + double d_best_sum; - friend gsm_receiver_cf_sptr gsm_make_receiver_cf( int osr ); - gsm_receiver_cf( int osr ); - int find_fcch_burst( const gr_complex *in, const int items ); + enum states + { + fcch_search, sch_search + } d_state; + + friend gsm_receiver_cf_sptr gsm_make_receiver_cf( gr_feval_dd *tuner, int osr ); + gsm_receiver_cf( gr_feval_dd *tuner, int osr ); + + bool find_fcch_burst( const gr_complex *in, const int nitems ); + bool find_sch_burst( const gr_complex *in, const int nitems , gr_complex *out); + double compute_freq_offset ( ); + void set_frequency ( ); public: ~gsm_receiver_cf(); diff --git a/src/python/cfile b/src/python/cfile new file mode 100644 index 0000000..943e35f Binary files /dev/null and b/src/python/cfile differ diff --git a/src/python/gsm_findfcch.py b/src/python/gsm_findfcch.py new file mode 100755 index 0000000..7ab9c18 --- /dev/null +++ b/src/python/gsm_findfcch.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python +#!/usr/bin/env python + +from gnuradio import gr, gru, blks2 +#, gsm +from gnuradio.eng_option import eng_option +from optparse import OptionParser +from os import sys + +for extdir in ['../../debug/src/lib','../../debug/src/lib/.libs']: + if extdir not in sys.path: + sys.path.append(extdir) +import gsm + +class tune(gr.feval_dd): + def __init__(self, top_block): + gr.feval_dd.__init__(self) + self.top_block = top_block + self.center_freq = 0 + def eval(self, freq_offet): + self.center_freq = self.center_freq - freq_offet + self.top_block.set_frequency(self.center_freq) + return self.center_freq + + +class gsm_receiver_first_blood(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + (options, args) = self._przetworz_opcje() + self.tune_callback = tune(self) + self.options = options + self.args = args + self._ustaw_taktowanie() + self.zrodlo = self._ustaw_zrodlo() + self.filtr = self._ustaw_filtr() + self.interpolator = self._ustaw_interpolator() + self.odbiornik = self._ustaw_odbiornik() + self.konwerter = self._ustaw_konwerter() + self.ujscie = self._ustaw_ujscie() + + self.connect(self.zrodlo, self.filtr, self.interpolator, self.odbiornik, self.konwerter, self.ujscie) +# self.connect(self.zrodlo, self.ujscie) + + def _ustaw_ujscie(self): + nazwa_pliku_wy = self.options.outputfile + ujscie = gr.file_sink(gr.sizeof_float, nazwa_pliku_wy) + return ujscie + + def _ustaw_zrodlo(self): + nazwa_pliku = self.options.inputfile + zrodlo = gr.file_source(gr.sizeof_gr_complex, nazwa_pliku, False) + return zrodlo + + def _ustaw_taktowanie(self): + options = self.options + clock_rate = 64e6 + self.clock_rate = clock_rate + self.input_rate = clock_rate / options.decim + self.gsm_symb_rate = 1625000.0 / 6.0 + self.sps = self.input_rate / self.gsm_symb_rate + + def _ustaw_filtr(self): + filter_cutoff = 145e3 + filter_t_width = 10e3 + offset = 0 + print "input_rate:", self.input_rate, "sample rate:", self.sps, " filter_cutoff:", filter_cutoff, " filter_t_width:", filter_t_width + filter_taps = gr.firdes.low_pass(1.0, self.input_rate, filter_cutoff, filter_t_width, gr.firdes.WIN_HAMMING) + filtr = gr.freq_xlating_fir_filter_ccf(1, filter_taps, offset, self.input_rate) + return filtr + + def _ustaw_konwerter(self): + v2s = gr.vector_to_stream(gr.sizeof_float, 142) + return v2s + + def _ustaw_interpolator(self): + interpolator = gr.fractional_interpolator_cc(0, self.sps) + return interpolator + + def _ustaw_odbiornik(self): + odbiornik = gsm.receiver_cf(self.tune_callback, self.options.osr) + return odbiornik + + def _przetworz_opcje(self): + parser = OptionParser(option_class=eng_option) + parser.add_option("-d", "--decim", type="int", default=128, + help="Set USRP decimation rate to DECIM [default=%default]") + parser.add_option("-r", "--osr", type="int", default=1, + help="Oversampling ratio [default=%default]") + parser.add_option("-I", "--inputfile", type="string", default="cfile", + help="Input filename") + parser.add_option("-O", "--outputfile", type="string", default="cfile2.out", + help="Output filename") + (options, args) = parser.parse_args () + return (options, args) + + def set_frequency(self, center_freq): + self.filtr.set_center_freq(center_freq) + +def main(): + try: + gsm_receiver_first_blood().run() + except KeyboardInterrupt: + pass + +if __name__ == '__main__': + main() + + diff --git a/src/python/gsm_findfcch_usrp.py b/src/python/gsm_findfcch_usrp.py new file mode 100755 index 0000000..7bf81f3 --- /dev/null +++ b/src/python/gsm_findfcch_usrp.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python +#!/usr/bin/env python + +from gnuradio import gr, gru, blks2 +from gnuradio import usrp +#from gnuradio import gsm +from gnuradio.eng_option import eng_option +from optparse import OptionParser +from os import sys +#""" +for extdir in ['../../debug/src/lib','../../debug/src/lib/.libs']: + if extdir not in sys.path: + sys.path.append(extdir) +import gsm +#""" +def pick_subdevice(u): + if u.db[0][0].dbid() >= 0: + return (0, 0) + if u.db[1][0].dbid() >= 0: + return (1, 0) + return (0, 0) + +class gsm_receiver_first_blood(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + ( self.options, self.args) = self._przetworz_opcje() + self._ustaw_taktowanie() + self.zrodlo = self._ustaw_zrodlo() + self.filtr = self._ustaw_filtr() + self.interpolator = self._ustaw_interpolator() + self.odbiornik = self._ustaw_odbiornik() + self.konwerter = self._ustaw_konwerter() + self.ujscie = self._ustaw_ujscie() + + self.connect(self.zrodlo, self.filtr, self.interpolator, self.odbiornik, self.konwerter, self.ujscie) +# self.connect(self.zrodlo, self.ujscie) + + def _ustaw_ujscie(self): + nazwa_pliku_wy = self.options.outputfile + ujscie = gr.file_sink(gr.sizeof_float, nazwa_pliku_wy) + return ujscie + + def _ustaw_zrodlo(self): + options = self.options + fusb_block_size = gr.prefs().get_long('fusb', 'block_size', 4096) + fusb_nblocks = gr.prefs().get_long('fusb', 'nblocks', 16) + self.usrp = usrp.source_c(decim_rate=options.decim, fusb_block_size=fusb_block_size, fusb_nblocks=fusb_nblocks) + + if options.rx_subdev_spec is None: + options.rx_subdev_spec = pick_subdevice(self.usrp) + + self.usrp.set_mux(usrp.determine_rx_mux_value(self.usrp, options.rx_subdev_spec)) + # determine the daughterboard subdevice + self.subdev = usrp.selected_subdev(self.usrp, options.rx_subdev_spec) + input_rate = self.usrp.adc_freq() / self.usrp.decim_rate() + + # set initial values + if options.gain is None: + # if no gain was specified, use the mid-point in dB + g = self.subdev.gain_range() + options.gain = float(g[0]+g[1])/2 + + r = self.usrp.tune(0, self.subdev, options.freq) + self.subdev.set_gain(options.gain) + return self.usrp + + def _ustaw_taktowanie(self): + options = self.options + clock_rate = 64e6 + self.clock_rate = clock_rate + self.input_rate = clock_rate / options.decim + self.gsm_symb_rate = 1625000.0 / 6.0 + self.sps = self.input_rate / self.gsm_symb_rate + + def _ustaw_filtr(self): + filter_cutoff = 145e3 + filter_t_width = 10e3 + offset = 0 + print "input_rate:", self.input_rate, "sample rate:", self.sps, " filter_cutoff:", filter_cutoff, " filter_t_width:", filter_t_width + filter_taps = gr.firdes.low_pass(1.0, self.input_rate, filter_cutoff, filter_t_width, gr.firdes.WIN_HAMMING) + filtr = gr.freq_xlating_fir_filter_ccf(1, filter_taps, offset, self.input_rate) + return filtr + + def _ustaw_konwerter(self): + v2s = gr.vector_to_stream(gr.sizeof_float, 142) + return v2s + + def _ustaw_interpolator(self): + interpolator = gr.fractional_interpolator_cc(0, self.sps) + return interpolator + + def _ustaw_odbiornik(self): + odbiornik = gsm.receiver_cf(1) + return odbiornik + + def _przetworz_opcje(self): + parser = OptionParser(option_class=eng_option) + parser.add_option("-d", "--decim", type="int", default=128, + help="Set USRP decimation rate to DECIM [default=%default]") + parser.add_option("-I", "--inputfile", type="string", default="cfile", + help="Input filename") + parser.add_option("-O", "--outputfile", type="string", default="cfile2.out", + help="Output filename") + parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, + help="Select USRP Rx side A or B (default=first one with a daughterboard)") + parser.add_option("-f", "--freq", type="eng_float", default="950.4M", + help="set frequency to FREQ", metavar="FREQ") + parser.add_option("-g", "--gain", type="eng_float", default=None, + help="Set gain in dB (default is midpoint)") + (options, args) = parser.parse_args () + return (options, args) + +def main(): + try: + gsm_receiver_first_blood().run() + except KeyboardInterrupt: + pass + +if __name__ == '__main__': + main() + + -- cgit v1.2.3 From 59ea3a8a82e6f166b80fc489945c43fdc8764ea0 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Mon, 20 Apr 2009 19:56:50 +0200 Subject: added non-traced files --- src/lib/Assert.h | 65 ++++++++++++++++++++++++++++++++++ src/lib/gsm.i | 36 +++++++++++++++++++ src/lib/gsm_constants.h | 94 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 195 insertions(+) create mode 100644 src/lib/Assert.h create mode 100644 src/lib/gsm.i create mode 100644 src/lib/gsm_constants.h diff --git a/src/lib/Assert.h b/src/lib/Assert.h new file mode 100644 index 0000000..6c04f18 --- /dev/null +++ b/src/lib/Assert.h @@ -0,0 +1,65 @@ +/* +* 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 . + +*/ + + +#ifndef ASSERT_H +#define ASSERT_H + +#include "stdio.h" +#include + +/**@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/gsm.i b/src/lib/gsm.i new file mode 100644 index 0000000..dac7602 --- /dev/null +++ b/src/lib/gsm.i @@ -0,0 +1,36 @@ +/* -*- c++ -*- */ + +%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 +#include "gsm_constants.h" +%} + +// ---------------------------------------------------------------- + +/* + * First arg is the package prefix. + * Second arg is the name of the class minus the prefix. + * + * This does some behind-the-scenes magic so we can + * access howto_square_ff from python as howto.square_ff + */ +GR_SWIG_BLOCK_MAGIC(gsm,receiver_cf); + +gsm_receiver_cf_sptr gsm_make_receiver_cf ( gr_feval_dd *tuner, int osr); + +class gsm_receiver_cf : public gr_block +{ +private: + gsm_receiver_cf ( gr_feval_dd *tuner, int osr); +}; + +// ---------------------------------------------------------------- diff --git a/src/lib/gsm_constants.h b/src/lib/gsm_constants.h new file mode 100644 index 0000000..01dfb22 --- /dev/null +++ b/src/lib/gsm_constants.h @@ -0,0 +1,94 @@ +#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 //8.25 +#define DATA_BITS 58 //size of 1 data block in normal burst +#define N_TRAIN_BITS 26 +#define N_SYNC_BITS 64 +#define USEFUL_BITS 142 //(2*DATA_BITS + N_TRAIN_BITS ) +#define FCCH_BITS USEFUL_BITS + +#define TS_BITS (TAIL_BITS+USEFUL_BITS+TAIL_BITS+GUARD_BITS) //a full TS (156) +#define TS_PER_FRAME 8 +#define FRAME_BITS (TS_PER_FRAME * TS_BITS + 2) // +2 for extra 8*0.25 guard bits +#define FCCH_POS TAIL_BITS +#define SYNC_POS 39 +#define TRAIN_POS 58 + +#define FCCH_HITS_NEEDED (USEFUL_BITS - 4) +#define FCCH_MAX_MISSES 2 + +static const int 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 +}; + +// Sync : .+...++.+..+++.++++++.++++++....++.+..+.+.+++.+.+...+..++++..+.. +// Diff Encoded Sync: .++..+.+++.+..++.....++.....+...+.+++.+++++..+++++..++.+...+.++. + +#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_FCCH 8 +#define TS_DUMMY 9 + +static const unsigned char train_seq[10][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}, + {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}, //#9 FCCH ;-) + {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 +}; + +//Diff encoded train_seq +//TSC0: +.++.+++..+...++..++.+++.. +//TSC1: +.+++.++..++...+..++.+++.. +//TSC2: +++...+..++..+++.++...+..+ +//TSC3: +++..+...++.+++..++..+...+ +//TSC4: +..+.++++..+.++....+.++++. +//TSC5: +++.+..++++.+....++.+..+++ +//TSC6: .+++.+....++.+..++++.+.... +//TSC7: ...++...+..++.+++..++...+. +//TSC8: .......................... +//TSC9: ++..+..+++..+..+++..+..+++ + + +#endif /* INCLUDED_GSM_CONSTANTS_H */ -- cgit v1.2.3 From c3c043a95b27fc130ea79d984d09fe5c415ab9a2 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Mon, 20 Apr 2009 19:59:04 +0200 Subject: added Makefile.am to the git repository --- src/python/Makefile.am | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/python/Makefile.am diff --git a/src/python/Makefile.am b/src/python/Makefile.am new file mode 100644 index 0000000..9a4befd --- /dev/null +++ b/src/python/Makefile.am @@ -0,0 +1,24 @@ +# +# Copyright 2004 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., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +include $(top_srcdir)/Makefile.common + +EXTRA_DIST = gsm_findfcch.py gsm_findfcch_usrp.py -- cgit v1.2.3 From 7894933871c7c880c594949f79c4e340a286d073 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Mon, 20 Apr 2009 20:04:18 +0200 Subject: gsm-receiver.pc.in added to the repository --- gsm-receiver.pc.in | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 gsm-receiver.pc.in diff --git a/gsm-receiver.pc.in b/gsm-receiver.pc.in new file mode 100644 index 0000000..0a18d4b --- /dev/null +++ b/gsm-receiver.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: gsm-receiver +Description: The GSM receiver block which does FCCH burst search, sch decoding and normal burst demodulation +Requires: gnuradio-core +Version: @VERSION@ +Libs: -L${libdir} -lgsm-receiver +Cflags: -I${includedir} -- cgit v1.2.3 From 8591703b11472fa62840e273e13febfe87829bd1 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Fri, 24 Apr 2009 19:24:17 +0200 Subject: Some changes to fcch search function and added first sch search functions --- src/lib/Assert.h | 2 + src/lib/gsm_constants.h | 2 +- src/lib/gsm_receiver_cf.cc | 219 +++++++++++++++++++++++++++++++++++---------- src/lib/gsm_receiver_cf.h | 38 ++++---- src/python/gsm_findfcch.py | 6 +- 5 files changed, 198 insertions(+), 69 deletions(-) diff --git a/src/lib/Assert.h b/src/lib/Assert.h index 6c04f18..acfb3f7 100644 --- a/src/lib/Assert.h +++ b/src/lib/Assert.h @@ -26,6 +26,8 @@ #include "stdio.h" #include +#define NDEBUG + /**@name Macros for standard messages. */ //@{ #define COUT(text) { std::cout << text << std::endl; } diff --git a/src/lib/gsm_constants.h b/src/lib/gsm_constants.h index 01dfb22..62dc86b 100644 --- a/src/lib/gsm_constants.h +++ b/src/lib/gsm_constants.h @@ -21,7 +21,7 @@ #define TRAIN_POS 58 #define FCCH_HITS_NEEDED (USEFUL_BITS - 4) -#define FCCH_MAX_MISSES 2 +#define FCCH_MAX_MISSES 1 static const int SYNC_BITS[] = { 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 4f43f2b..3b0e426 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -53,16 +52,18 @@ gsm_receiver_cf::gsm_receiver_cf(gr_feval_dd *tuner, int osr) : 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_OSR(osr), d_tuner(tuner), d_prev_freq_offset(0), - d_phase_diff_buffer(BUFFER_SIZE), + d_phase_diff_buffer(BUFFER_SIZE * osr), d_counter(0), d_x_temp(0), d_x2_temp(0), d_fcch_count(0), + d_fcch_start_pos(0), d_state(fcch_search) { + gmsk_mapper(SYNC_BITS, d_sch_training_seq, N_SYNC_BITS); } /* @@ -85,7 +86,7 @@ gsm_receiver_cf::general_work(int noutput_items, { const gr_complex *in = (const gr_complex *) input_items[0]; float *out = (float *) output_items[0]; - int produced_out; + int produced_out = 0; switch (d_state) { @@ -93,7 +94,7 @@ gsm_receiver_cf::general_work(int noutput_items, if (find_fcch_burst(in, ninput_items[0])) { produced_out = 1; - d_state = fcch_search; + d_state = sch_search; } else { produced_out = 0; d_state = fcch_search; @@ -102,6 +103,46 @@ gsm_receiver_cf::general_work(int noutput_items, break; case sch_search: + + if (find_sch_burst(in, ninput_items[0], out)) { + + d_state = sch_search; + } else { + for (int i = 0; i < ninput_items[0] - N_SYNC_BITS; i++) { + gr_complex result; + d_counter++; + int ninput = N_SYNC_BITS - 10; + const gr_complex * input_signal = in + i; + gr_complex * sequence = &d_sch_training_seq[5]; + result = correlation(&d_sch_training_seq[5], in + i, N_SYNC_BITS-10); + if (abs(result) > 60000) { + std::cout << "Max val: " << abs(result) << " position: " << d_counter - d_fcch_start_pos << std::endl; +// +// for (int j = 1; j <= 54; j++) { +// std::cout << sequence[j-1] << " * " << conj(input_signal[(j * d_OSR)]) << std::endl; +// } +// +// gr_complex result2(0, 0); +// +// for (int j = 1; j <= 54; j++) { +// result2 += sequence[j-1] * conj(input_signal[(j * d_OSR)]); +// } +// +// std::cout << "Spr: " << abs(result2) << std::endl; +// +// std::cout << std::endl; + } + + +// std::cout << "(" << real(in[i]) << "," << imag(in[i]) << ")\n"; +// std::cout << "(" << real(result) << "," << imag(result) << ")\n"; + } + + consume_each(ninput_items[0]); + + d_state = sch_search; + } + break; } @@ -116,14 +157,15 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) { float phase_diff = 0; gr_complex conjprod; - int hit_count, miss_count, start_pos; + int hit_count = 0; + int miss_count = 0; + int start_pos; float min_phase_diff, max_phase_diff, lowest_max_min_diff; - float sum, best_sum; int to_consume = 0; - int i = 0; + int sample_number = 0; bool end = false; - bool result; + bool result = false; circular_buffer_float::iterator buffer_iter; @@ -133,7 +175,7 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) fcch_search_state = init; - while ((!end) && (i < nitems)) { + while (!end) { switch (fcch_search_state) { case init: @@ -147,23 +189,22 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) break; case search: - i++; + sample_number++; - if (i > nitems - BUFFER_SIZE) { - to_consume = i; + if (sample_number > nitems - BUFFER_SIZE * d_OSR) { + to_consume = sample_number; fcch_search_state = search_fail; - } - - conjprod = in[i] * conj(in[i-1]); + } else { - phase_diff = gr_fast_atan2f(imag(conjprod), real(conjprod)); + conjprod = in[sample_number] * conj(in[sample_number-1]); + phase_diff = gr_fast_atan2f(imag(conjprod), real(conjprod)); - if (phase_diff > 0) { -// start_pos = i - 1; - to_consume = i; - fcch_search_state = found_something; - } else { - fcch_search_state = search; + if (phase_diff > 0) { + to_consume = sample_number; + fcch_search_state = found_something; + } else { + fcch_search_state = search; + } } break; @@ -176,42 +217,42 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) miss_count++; } - //DCOUT("d_phase_diff_buffer.size(): " << d_phase_diff_buffer.size() << " hit_count: " << hit_count); - - if ((miss_count >= FCCH_MAX_MISSES) && (hit_count <= FCCH_HITS_NEEDED)) { + if ((miss_count >= FCCH_MAX_MISSES * d_OSR) && (hit_count <= FCCH_HITS_NEEDED * d_OSR)) { fcch_search_state = init; + // DCOUT("hit_count: " << hit_count << " miss_count: " << miss_count << " d_counter: " << d_counter); continue; - } else if ((miss_count >= FCCH_MAX_MISSES) && (hit_count > FCCH_HITS_NEEDED)) { + } else if ((miss_count >= FCCH_MAX_MISSES * d_OSR) && (hit_count > FCCH_HITS_NEEDED * d_OSR)) { fcch_search_state = fcch_found; continue; - } else if ((miss_count < FCCH_MAX_MISSES) && (hit_count > FCCH_HITS_NEEDED)) { + } 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(d_phase_diff_buffer.begin(), d_phase_diff_buffer.end())); max_phase_diff = *(max_element(d_phase_diff_buffer.begin(), d_phase_diff_buffer.end())); - - if(lowest_max_min_diff > max_phase_diff - min_phase_diff){ + + if (lowest_max_min_diff > max_phase_diff - min_phase_diff) { lowest_max_min_diff = max_phase_diff - min_phase_diff; - start_pos = i - FCCH_HITS_NEEDED; + start_pos = sample_number - FCCH_HITS_NEEDED * d_OSR - FCCH_MAX_MISSES * d_OSR; d_best_sum = 0; + for (buffer_iter = (d_phase_diff_buffer.begin()); buffer_iter != (d_phase_diff_buffer.end()); buffer_iter++) { - d_best_sum += *buffer_iter; + d_best_sum += *buffer_iter - (M_PI / 2) / d_OSR; } - DCOUT(d_best_sum); } } - i++; + sample_number++; - if (i >= nitems) { + if (sample_number >= nitems) { fcch_search_state = search_fail; continue; } - conjprod = in[i] * conj(in[i-1]); + conjprod = in[sample_number] * conj(in[sample_number-1]); + phase_diff = gr_fast_atan2f(imag(conjprod), real(conjprod)); d_phase_diff_buffer.push_back(phase_diff); @@ -221,10 +262,11 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) case fcch_found: DCOUT("znalezione fcch na pozycji" << d_counter + start_pos); - to_consume = start_pos + FCCH_HITS_NEEDED + 1; + to_consume = start_pos + FCCH_HITS_NEEDED * d_OSR + 1; /* mean = d_best_sum / FCCH_HITS_NEEDED; phase_offset = mean - (M_PI / 2); freq_offset = phase_offset * 1625000.0 / (12.0 * M_PI);*/ + d_fcch_start_pos = d_counter + start_pos; compute_freq_offset(); end = true; result = true; @@ -237,14 +279,15 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) } } + // DCOUT("hit_count: " << hit_count << " miss_count: " << miss_count << " d_counter: " << d_counter); + d_counter += to_consume; + consume_each(to_consume); return result; } -bool find_sch_burst( const gr_complex *in, const int nitems , gr_complex *out); - double gsm_receiver_cf::compute_freq_offset() { @@ -252,19 +295,17 @@ double gsm_receiver_cf::compute_freq_offset() DCOUT(" d_phase_diff_buffer.size(): " << d_phase_diff_buffer.size()); - mean = d_best_sum / FCCH_HITS_NEEDED; - phase_offset = mean - (M_PI / 2); + //mean = d_best_sum / FCCH_HITS_NEEDED; + phase_offset = d_best_sum / FCCH_HITS_NEEDED; + //phase_offset = mean - ; freq_offset = phase_offset * 1625000.0 / (12.0 * M_PI); - DCOUT("freq_offset: " << freq_offset); + DCOUT("freq_offset: " << freq_offset << " d_best_sum: " << d_best_sum); d_fcch_count++; d_x_temp += freq_offset; d_x2_temp += freq_offset * freq_offset; d_mean = d_x_temp / d_fcch_count; - //d_mean = 0.9 * freq_offset + 0.1 * d_mean; - - - //d_tuner->calleval(freq_offset); + set_frequency(freq_offset); d_prev_freq_offset -= freq_offset; DCOUT("wariancja: " << sqrt((d_x2_temp / d_fcch_count - d_mean * d_mean)) << " fcch_count:" << d_fcch_count << " d_mean: " << d_mean); @@ -272,12 +313,92 @@ double gsm_receiver_cf::compute_freq_offset() return freq_offset; } -void gsm_receiver_cf::set_frequency() +void gsm_receiver_cf::set_frequency(double freq_offset) { + d_tuner->calleval(freq_offset); +} + +bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , float *out) +{ + int sample_number = 0; + int to_consume = 0; + bool end = false; + bool result = false; + int sch_start = d_fcch_start_pos + FRAME_BITS * d_OSR; + + enum states { + init, search, sch_found, search_fail + } sch_search_state; + + while (!end) { + switch (sch_search_state) { + case init: + sch_search_state = search_fail; + break; + + case search: + + if ((sch_start >= d_counter) && (sch_start <= d_counter + nitems)) { + DCOUT("sch_start-d_counter: " << sch_start - d_counter); + /* for (int i = 0; i < nitems - N_SYNC_BITS; i++) { + gr_complex result = correlation(&d_sch_training_seq[5], in + i, N_SYNC_BITS-10); + //std::cout << "(" << real(in[i]) << "," << imag(in[i]) << ")\n"; + std::cout << "(" << real(result) << "," << imag(result) << ")\n"; + } + std::cout << std::endl; + */ + } + + to_consume = nitems - N_SYNC_BITS; + + sch_search_state = search_fail; + break; + + case sch_found: + end = true; + break; + + case search_fail: + end = true; + break; + } + } + + d_counter += to_consume; + +// consume_each(to_consume); + + return result; } -bool gsm_receiver_cf::find_sch_burst( const gr_complex *in, const int nitems , gr_complex *out) +void gsm_receiver_cf::gmsk_mapper(const int * input, gr_complex * output, int ninput) { - + gr_complex j = gr_complex(0.0, 1.0); + + int current_symbol; + int encoded_symbol; + int previous_symbol = 2 * input[0] - 1; + output[0] = gr_complex(1.0, 0.0); + + for (int i = 1; i < ninput; i++) { + //change bits representation to NRZ + current_symbol = 2 * input[i] - 1; + //differentially encode + encoded_symbol = current_symbol * previous_symbol; + //and do gmsk mapping + output[i] = j * gr_complex(encoded_symbol, 0.0) * output[i-1]; + previous_symbol = current_symbol; + } +} + +gr_complex gsm_receiver_cf::correlation(const gr_complex * sequence, const gr_complex * input_signal, int ninput) +{ + gr_complex result(0.0, 0.0); + + for (int ii = 1; (ii * d_OSR) <= ninput; ii++) { + result += sequence[ii-1] * conj(input_signal[(ii * d_OSR)]); + } + + return result; } diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index 2012325..0e287c5 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -26,6 +26,8 @@ #include #include #include +#include + class gsm_receiver_cf; @@ -51,7 +53,7 @@ typedef boost::circular_buffer circular_buffer_float; * constructor is private. howto_make_square_ff is the public * interface for creating new instances. */ -gsm_receiver_cf_sptr gsm_make_receiver_cf( gr_feval_dd *tuner, int osr ); +gsm_receiver_cf_sptr gsm_make_receiver_cf(gr_feval_dd *tuner, int osr); /*! * \brief Receives fcch @@ -64,34 +66,38 @@ class gsm_receiver_cf : public gr_block private: gr_feval_dd *d_tuner; - const int d_osr; + const int d_OSR; int d_counter; + int d_fcch_start_pos; float d_prev_freq_offset; circular_buffer_float d_phase_diff_buffer; double d_x_temp, d_x2_temp, d_mean; int d_fcch_count; double d_best_sum; - - enum states - { + gr_complex d_sch_training_seq[N_SYNC_BITS]; //encoded training sequence of a SCH burst + + + enum states { fcch_search, sch_search } d_state; - friend gsm_receiver_cf_sptr gsm_make_receiver_cf( gr_feval_dd *tuner, int osr ); - gsm_receiver_cf( gr_feval_dd *tuner, int osr ); + friend gsm_receiver_cf_sptr gsm_make_receiver_cf(gr_feval_dd *tuner, int osr); + gsm_receiver_cf(gr_feval_dd *tuner, int osr); - bool find_fcch_burst( const gr_complex *in, const int nitems ); - bool find_sch_burst( const gr_complex *in, const int nitems , gr_complex *out); - double compute_freq_offset ( ); - void set_frequency ( ); + bool find_fcch_burst(const gr_complex *in, const int nitems); + double compute_freq_offset(); + void set_frequency(double freq_offset); + bool find_sch_burst(const gr_complex *in, const int nitems , float *out); + void gmsk_mapper(const int * input, gr_complex * gmsk_output, int ninput); + gr_complex correlation(const gr_complex * sequence, const gr_complex * input_signal, int ninput); 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 ); + 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/python/gsm_findfcch.py b/src/python/gsm_findfcch.py index 7ab9c18..9c0620b 100755 --- a/src/python/gsm_findfcch.py +++ b/src/python/gsm_findfcch.py @@ -10,7 +10,7 @@ from os import sys for extdir in ['../../debug/src/lib','../../debug/src/lib/.libs']: if extdir not in sys.path: sys.path.append(extdir) -import gsm +import gsm class tune(gr.feval_dd): def __init__(self, top_block): @@ -57,13 +57,13 @@ class gsm_receiver_first_blood(gr.top_block): self.clock_rate = clock_rate self.input_rate = clock_rate / options.decim self.gsm_symb_rate = 1625000.0 / 6.0 - self.sps = self.input_rate / self.gsm_symb_rate + self.sps = ( self.input_rate / self.gsm_symb_rate ) / options.osr def _ustaw_filtr(self): filter_cutoff = 145e3 filter_t_width = 10e3 offset = 0 - print "input_rate:", self.input_rate, "sample rate:", self.sps, " filter_cutoff:", filter_cutoff, " filter_t_width:", filter_t_width + #print "input_rate:", self.input_rate, "sample rate:", self.sps, " filter_cutoff:", filter_cutoff, " filter_t_width:", filter_t_width filter_taps = gr.firdes.low_pass(1.0, self.input_rate, filter_cutoff, filter_t_width, gr.firdes.WIN_HAMMING) filtr = gr.freq_xlating_fir_filter_ccf(1, filter_taps, offset, self.input_rate) return filtr -- cgit v1.2.3 From 1398632c44cc53bc02fce57d5da3f10a6f951cf9 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Tue, 28 Apr 2009 20:08:18 +0200 Subject: cleanup of fcch search related entities --- src/lib/gsm_constants.h | 1 + src/lib/gsm_receiver_cf.cc | 132 ++++++++++++++++++--------------------------- src/lib/gsm_receiver_cf.h | 22 +++++--- src/python/gsm_findfcch.py | 4 +- 4 files changed, 71 insertions(+), 88 deletions(-) diff --git a/src/lib/gsm_constants.h b/src/lib/gsm_constants.h index 62dc86b..50ea600 100644 --- a/src/lib/gsm_constants.h +++ b/src/lib/gsm_constants.h @@ -19,6 +19,7 @@ #define FCCH_POS TAIL_BITS #define SYNC_POS 39 #define TRAIN_POS 58 +#define SAFETY_MARGIN 6 #define FCCH_HITS_NEEDED (USEFUL_BITS - 4) #define FCCH_MAX_MISSES 1 diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 3b0e426..474a9d1 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -54,14 +54,14 @@ gsm_receiver_cf::gsm_receiver_cf(gr_feval_dd *tuner, int osr) gr_make_io_signature(MIN_OUT, MAX_OUT, 142 * sizeof(float))), d_OSR(osr), d_tuner(tuner), - d_prev_freq_offset(0), - d_phase_diff_buffer(BUFFER_SIZE * osr), d_counter(0), - d_x_temp(0), - d_x2_temp(0), - d_fcch_count(0), d_fcch_start_pos(0), - d_state(fcch_search) + d_freq_offset(0), + d_state(first_fcch_search), + d_first(false) + // d_fcch_count(0), + // d_x_temp(0), + // d_x2_temp(0) { gmsk_mapper(SYNC_BITS, d_sch_training_seq, N_SYNC_BITS); } @@ -90,77 +90,56 @@ gsm_receiver_cf::general_work(int noutput_items, switch (d_state) { - case fcch_search: + case first_fcch_search: if (find_fcch_burst(in, ninput_items[0])) { - produced_out = 1; - d_state = sch_search; + set_frequency(d_freq_offset); + produced_out = 0; + d_state = next_fcch_search; } else { produced_out = 0; - d_state = fcch_search; + d_state = first_fcch_search; } break; - case sch_search: - - if (find_sch_burst(in, ninput_items[0], out)) { - + case next_fcch_search: + if (find_fcch_burst(in, ninput_items[0])) { + produced_out = 0; d_state = sch_search; } else { - for (int i = 0; i < ninput_items[0] - N_SYNC_BITS; i++) { - gr_complex result; - d_counter++; - int ninput = N_SYNC_BITS - 10; - const gr_complex * input_signal = in + i; - gr_complex * sequence = &d_sch_training_seq[5]; - result = correlation(&d_sch_training_seq[5], in + i, N_SYNC_BITS-10); - if (abs(result) > 60000) { - std::cout << "Max val: " << abs(result) << " position: " << d_counter - d_fcch_start_pos << std::endl; -// -// for (int j = 1; j <= 54; j++) { -// std::cout << sequence[j-1] << " * " << conj(input_signal[(j * d_OSR)]) << std::endl; -// } -// -// gr_complex result2(0, 0); -// -// for (int j = 1; j <= 54; j++) { -// result2 += sequence[j-1] * conj(input_signal[(j * d_OSR)]); -// } -// -// std::cout << "Spr: " << abs(result2) << std::endl; -// -// std::cout << std::endl; - } - - -// std::cout << "(" << real(in[i]) << "," << imag(in[i]) << ")\n"; -// std::cout << "(" << real(result) << "," << imag(result) << ")\n"; - } - - consume_each(ninput_items[0]); + produced_out = 0; + d_state = next_fcch_search; + } + break; + case sch_search: + if (find_sch_burst(in, ninput_items[0], out)) { + d_state = read_bcch; + } else { d_state = sch_search; } - + break; + + case read_bcch: break; } -// for (int i = 0; i < TS_BITS; i++) { -// out[i] = d_phase_diff_buffer[i+start_pos-USEFUL_BITS]; -// } - return produced_out; } bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) { + circular_buffer_float phase_diff_buffer(BUFFER_SIZE * d_OSR); + float phase_diff = 0; gr_complex conjprod; int hit_count = 0; int miss_count = 0; - int start_pos; - float min_phase_diff, max_phase_diff, lowest_max_min_diff; + int start_pos = -1; + float min_phase_diff; + float max_phase_diff; + float lowest_max_min_diff = 99999; int to_consume = 0; int sample_number = 0; @@ -183,7 +162,7 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) miss_count = 0; start_pos = -1; lowest_max_min_diff = 99999; - d_phase_diff_buffer.clear(); + phase_diff_buffer.clear(); fcch_search_state = search; break; @@ -196,8 +175,7 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) fcch_search_state = search_fail; } else { - conjprod = in[sample_number] * conj(in[sample_number-1]); - phase_diff = gr_fast_atan2f(imag(conjprod), real(conjprod)); + phase_diff = compute_phase_diff(in[sample_number], in[sample_number-1]); if (phase_diff > 0) { to_consume = sample_number; @@ -228,16 +206,16 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) //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(d_phase_diff_buffer.begin(), d_phase_diff_buffer.end())); - max_phase_diff = *(max_element(d_phase_diff_buffer.begin(), d_phase_diff_buffer.end())); + 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; d_best_sum = 0; - for (buffer_iter = (d_phase_diff_buffer.begin()); - buffer_iter != (d_phase_diff_buffer.end()); + for (buffer_iter = (phase_diff_buffer.begin()); + buffer_iter != (phase_diff_buffer.end()); buffer_iter++) { d_best_sum += *buffer_iter - (M_PI / 2) / d_OSR; } @@ -251,10 +229,8 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) continue; } - conjprod = in[sample_number] * conj(in[sample_number-1]); - - phase_diff = gr_fast_atan2f(imag(conjprod), real(conjprod)); - d_phase_diff_buffer.push_back(phase_diff); + phase_diff = compute_phase_diff(in[sample_number], in[sample_number-1]); + phase_diff_buffer.push_back(phase_diff); fcch_search_state = found_something; @@ -280,7 +256,11 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) } // DCOUT("hit_count: " << hit_count << " miss_count: " << miss_count << " d_counter: " << d_counter); - + //! + for(int i = 0; i < to_consume; i++){ + //std::cout << "(" << real(in[i]) << "," << imag(in[i]) << ")\n"; + } + d_counter += to_consume; consume_each(to_consume); @@ -291,24 +271,18 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) double gsm_receiver_cf::compute_freq_offset() { - float mean, phase_offset, freq_offset; + float phase_offset, freq_offset; - DCOUT(" d_phase_diff_buffer.size(): " << d_phase_diff_buffer.size()); - - //mean = d_best_sum / FCCH_HITS_NEEDED; phase_offset = d_best_sum / FCCH_HITS_NEEDED; - //phase_offset = mean - ; freq_offset = phase_offset * 1625000.0 / (12.0 * M_PI); - DCOUT("freq_offset: " << freq_offset << " d_best_sum: " << d_best_sum); - d_fcch_count++; - d_x_temp += freq_offset; - d_x2_temp += freq_offset * freq_offset; - d_mean = d_x_temp / d_fcch_count; - - set_frequency(freq_offset); - d_prev_freq_offset -= freq_offset; - - DCOUT("wariancja: " << sqrt((d_x2_temp / d_fcch_count - d_mean * d_mean)) << " fcch_count:" << d_fcch_count << " d_mean: " << d_mean); + d_freq_offset -= freq_offset; + +// d_x_temp += freq_offset; +// d_x2_temp += freq_offset * freq_offset; +// d_mean = d_x_temp / d_fcch_count; +// d_fcch_count++; + DCOUT("freq_offset: " << freq_offset << " d_best_sum: " << d_best_sum); +// DCOUT("wariancja: " << sqrt((d_x2_temp / d_fcch_count - d_mean * d_mean)) << " fcch_count:" << d_fcch_count << " d_mean: " << d_mean); return freq_offset; } diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index 0e287c5..ccc99fb 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -65,20 +65,25 @@ class gsm_receiver_cf : public gr_block { private: - gr_feval_dd *d_tuner; const int d_OSR; + gr_complex d_sch_training_seq[N_SYNC_BITS]; //encoded training sequence of a SCH burst + + gr_feval_dd *d_tuner; int d_counter; + + //variables used to store result of the find_fcch_burst fuction int d_fcch_start_pos; - float d_prev_freq_offset; - circular_buffer_float d_phase_diff_buffer; - double d_x_temp, d_x2_temp, d_mean; - int d_fcch_count; + float d_freq_offset; double d_best_sum; - gr_complex d_sch_training_seq[N_SYNC_BITS]; //encoded training sequence of a SCH burst + int d_fcch_count; + + bool d_first; +// int d_fcch_count; +// double d_x_temp, d_x2_temp, d_mean; enum states { - fcch_search, sch_search + first_fcch_search, next_fcch_search, sch_search, read_bcch } d_state; friend gsm_receiver_cf_sptr gsm_make_receiver_cf(gr_feval_dd *tuner, int osr); @@ -87,9 +92,12 @@ class gsm_receiver_cf : public gr_block bool find_fcch_burst(const gr_complex *in, const int nitems); double compute_freq_offset(); void set_frequency(double freq_offset); + inline float compute_phase_diff(gr_complex val1, gr_complex val2); + bool find_sch_burst(const gr_complex *in, const int nitems , float *out); void gmsk_mapper(const int * input, gr_complex * gmsk_output, int ninput); gr_complex correlation(const gr_complex * sequence, const gr_complex * input_signal, int ninput); + public: ~gsm_receiver_cf(); diff --git a/src/python/gsm_findfcch.py b/src/python/gsm_findfcch.py index 9c0620b..09615bf 100755 --- a/src/python/gsm_findfcch.py +++ b/src/python/gsm_findfcch.py @@ -18,8 +18,8 @@ class tune(gr.feval_dd): self.top_block = top_block self.center_freq = 0 def eval(self, freq_offet): - self.center_freq = self.center_freq - freq_offet - self.top_block.set_frequency(self.center_freq) +# self.center_freq = self.center_freq - freq_offet + self.top_block.set_frequency(freq_offet) return self.center_freq -- cgit v1.2.3 From 961ff106d137b744eeafae55c939a5524370267b Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Tue, 28 Apr 2009 20:09:37 +0200 Subject: first part of sch sychronisation - getting close to sch burst --- src/lib/gsm_receiver_cf.cc | 86 +++++++++++++++++++++++++++++++++------------- 1 file changed, 62 insertions(+), 24 deletions(-) diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 474a9d1..5f730dc 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -75,7 +75,7 @@ gsm_receiver_cf::~gsm_receiver_cf() void gsm_receiver_cf::forecast(int noutput_items, gr_vector_int &ninput_items_required) { - ninput_items_required[0] = noutput_items * TS_BITS; //TODO include oversampling ratio here + ninput_items_required[0] = noutput_items * (TS_BITS + SAFETY_MARGIN) * d_OSR; } int @@ -294,46 +294,73 @@ void gsm_receiver_cf::set_frequency(double freq_offset) bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , float *out) { - int sample_number = 0; +// int sample_number = 0; int to_consume = 0; bool end = false; bool result = false; - int sch_start = d_fcch_start_pos + FRAME_BITS * d_OSR; + int sample_nr_near_sch_start = d_fcch_start_pos + (FRAME_BITS - SAFETY_MARGIN) * d_OSR; + enum states { - init, search, sch_found, search_fail + start, reach_sch, find_sch_start, search_not_finished, sch_found } sch_search_state; + + sch_search_state = start; + while (!end) { switch (sch_search_state) { - - case init: - sch_search_state = search_fail; + case start: + if(d_counter < sample_nr_near_sch_start){ + sch_search_state = reach_sch; + } else { + sch_search_state = find_sch_start; + } break; - case search: + case reach_sch: - if ((sch_start >= d_counter) && (sch_start <= d_counter + nitems)) { - DCOUT("sch_start-d_counter: " << sch_start - d_counter); - /* for (int i = 0; i < nitems - N_SYNC_BITS; i++) { - gr_complex result = correlation(&d_sch_training_seq[5], in + i, N_SYNC_BITS-10); - //std::cout << "(" << real(in[i]) << "," << imag(in[i]) << ")\n"; - std::cout << "(" << real(result) << "," << imag(result) << ")\n"; - } - std::cout << std::endl; - */ + if(d_counter + nitems >= sample_nr_near_sch_start){ + to_consume = sample_nr_near_sch_start - d_counter; + DCOUT("reach_sch consumes: " << to_consume << "bits"); + } else { + to_consume = nitems; } + + - to_consume = nitems - N_SYNC_BITS; + sch_search_state = search_not_finished; + break; - sch_search_state = search_fail; + case find_sch_start: + DCOUT("find_sch_start nitems" << nitems); +// if ((sch_start >= d_counter) && (sch_start <= d_counter + nitems)) { +// for (int i = 0; i < ninput_items[0] - N_SYNC_BITS; i++) { +// gr_complex result; +// d_counter++; +// result = correlation(&d_sch_training_seq[5], in + i, N_SYNC_BITS - 10); +// +// if (abs(result) > 60000) { +// DCOUT("znaleziono środek sch na pozycji: " << d_counter); +// } +// +// // std::cout << "(" << real(in[i]) << "," << imag(in[i]) << ")\n"; +// // std::cout << "(" << real(result) << "," << imag(result) << ")\n"; +// +// int ninput = N_SYNC_BITS - 10; +// const gr_complex * input_signal = in + i; +// gr_complex * sequence = &d_sch_training_seq[5]; +// } +// } + to_consume = nitems; + sch_search_state = sch_found; break; - case sch_found: + case search_not_finished: end = true; break; - case search_fail: + case sch_found: end = true; break; } @@ -341,7 +368,7 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl d_counter += to_consume; -// consume_each(to_consume); + consume_each(to_consume); return result; } @@ -369,10 +396,21 @@ void gsm_receiver_cf::gmsk_mapper(const int * input, gr_complex * output, int ni gr_complex gsm_receiver_cf::correlation(const gr_complex * sequence, const gr_complex * input_signal, int ninput) { gr_complex result(0.0, 0.0); + int sample_number = 0; - for (int ii = 1; (ii * d_OSR) <= ninput; ii++) { - result += sequence[ii-1] * conj(input_signal[(ii * d_OSR)]); + for (int ii = 0; ii < ninput; ii++) { + sample_number = (ii * d_OSR) ; + result += sequence[ii] * conj(input_signal[sample_number]); } return result; } + +// gr_complex gsm_receiver_cf::calc_energy(int window_len){ +// +// } +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)); +} \ No newline at end of file -- cgit v1.2.3 From 5027749b23b0b4a49d166aee6712b7de01a3d54c Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Thu, 30 Apr 2009 19:07:08 +0200 Subject: liettle changes to fcch search, commit before test to find reason of bad behavior when OSR value is changed --- src/lib/Assert.h | 2 +- src/lib/gsm_receiver_cf.cc | 178 ++++++++++++++++++++++++++++----------------- src/lib/gsm_receiver_cf.h | 16 ++-- src/python/gsm_findfcch.py | 10 +-- 4 files changed, 123 insertions(+), 83 deletions(-) diff --git a/src/lib/Assert.h b/src/lib/Assert.h index acfb3f7..67fe02f 100644 --- a/src/lib/Assert.h +++ b/src/lib/Assert.h @@ -26,7 +26,7 @@ #include "stdio.h" #include -#define NDEBUG +//#define NDEBUG /**@name Macros for standard messages. */ //@{ diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 5f730dc..045c639 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -29,10 +29,17 @@ #include #include #include +#include +#include #include -#define SAFETY_MARGIN 50 -#define BUFFER_SIZE (FCCH_HITS_NEEDED) +#define FCCH_BUFFER_SIZE (FCCH_HITS_NEEDED) +#define SYNC_SEARCH_RANGE 40 + +typedef std::list list_float; +typedef std::vector vector_float; + +typedef boost::circular_buffer circular_buffer_float; gsm_receiver_cf_sptr gsm_make_receiver_cf(gr_feval_dd *tuner, int osr) @@ -58,10 +65,9 @@ gsm_receiver_cf::gsm_receiver_cf(gr_feval_dd *tuner, int osr) d_fcch_start_pos(0), d_freq_offset(0), d_state(first_fcch_search), - d_first(false) - // d_fcch_count(0), - // d_x_temp(0), - // d_x2_temp(0) + d_fcch_count(0), //!! + d_x_temp(0),//!! + d_x2_temp(0)//!! { gmsk_mapper(SYNC_BITS, d_sch_training_seq, N_SYNC_BITS); } @@ -75,7 +81,7 @@ gsm_receiver_cf::~gsm_receiver_cf() void gsm_receiver_cf::forecast(int noutput_items, gr_vector_int &ninput_items_required) { - ninput_items_required[0] = noutput_items * (TS_BITS + SAFETY_MARGIN) * d_OSR; + ninput_items_required[0] = noutput_items * (TS_BITS + 2 * SAFETY_MARGIN) * d_OSR; } int @@ -87,11 +93,10 @@ gsm_receiver_cf::general_work(int noutput_items, const gr_complex *in = (const gr_complex *) input_items[0]; float *out = (float *) output_items[0]; int produced_out = 0; + float prev_freq_offset; switch (d_state) { - case first_fcch_search: - if (find_fcch_burst(in, ninput_items[0])) { set_frequency(d_freq_offset); produced_out = 0; @@ -100,11 +105,15 @@ gsm_receiver_cf::general_work(int noutput_items, produced_out = 0; d_state = first_fcch_search; } - break; case next_fcch_search: + prev_freq_offset = d_freq_offset; if (find_fcch_burst(in, ninput_items[0])) { + if (abs(d_freq_offset) > 100) { + float mean_freq_offset = (prev_freq_offset + d_freq_offset) / 2; +// set_frequency(d_freq_offset); + } produced_out = 0; d_state = sch_search; } else { @@ -115,12 +124,13 @@ gsm_receiver_cf::general_work(int noutput_items, case sch_search: if (find_sch_burst(in, ninput_items[0], out)) { - d_state = read_bcch; +// d_state = read_bcch; + d_state = next_fcch_search; } else { d_state = sch_search; } break; - + case read_bcch: break; } @@ -130,7 +140,7 @@ gsm_receiver_cf::general_work(int noutput_items, bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) { - circular_buffer_float phase_diff_buffer(BUFFER_SIZE * d_OSR); + circular_buffer_float phase_diff_buffer(FCCH_BUFFER_SIZE * d_OSR); float phase_diff = 0; gr_complex conjprod; @@ -145,6 +155,7 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) int sample_number = 0; bool end = false; bool result = false; +// float mean=0, phase_offset=0, freq_offset=0; circular_buffer_float::iterator buffer_iter; @@ -170,11 +181,10 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) case search: sample_number++; - if (sample_number > nitems - BUFFER_SIZE * d_OSR) { + if (sample_number > nitems - FCCH_BUFFER_SIZE * d_OSR) { to_consume = sample_number; fcch_search_state = search_fail; } else { - phase_diff = compute_phase_diff(in[sample_number], in[sample_number-1]); if (phase_diff > 0) { @@ -188,7 +198,6 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) break; case found_something: - if (phase_diff > 0) { hit_count++; } else { @@ -197,7 +206,7 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) if ((miss_count >= FCCH_MAX_MISSES * d_OSR) && (hit_count <= FCCH_HITS_NEEDED * d_OSR)) { fcch_search_state = init; - // DCOUT("hit_count: " << hit_count << " miss_count: " << miss_count << " d_counter: " << d_counter); + //DCOUT("hit_count: " << hit_count << " miss_count: " << miss_count << " d_counter: " << d_counter); continue; } else if ((miss_count >= FCCH_MAX_MISSES * d_OSR) && (hit_count > FCCH_HITS_NEEDED * d_OSR)) { fcch_search_state = fcch_found; @@ -214,7 +223,7 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) start_pos = sample_number - FCCH_HITS_NEEDED * d_OSR - FCCH_MAX_MISSES * d_OSR; d_best_sum = 0; - for (buffer_iter = (phase_diff_buffer.begin()); + for (buffer_iter = phase_diff_buffer.begin(); buffer_iter != (phase_diff_buffer.end()); buffer_iter++) { d_best_sum += *buffer_iter - (M_PI / 2) / d_OSR; @@ -231,7 +240,6 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) phase_diff = compute_phase_diff(in[sample_number], in[sample_number-1]); phase_diff_buffer.push_back(phase_diff); - fcch_search_state = found_something; break; @@ -239,9 +247,9 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) case fcch_found: DCOUT("znalezione fcch na pozycji" << d_counter + start_pos); to_consume = start_pos + FCCH_HITS_NEEDED * d_OSR + 1; - /* mean = d_best_sum / FCCH_HITS_NEEDED; - phase_offset = mean - (M_PI / 2); - freq_offset = phase_offset * 1625000.0 / (12.0 * M_PI);*/ +// mean = d_best_sum / FCCH_HITS_NEEDED; +// phase_offset = mean - (M_PI / 2); +// freq_offset = phase_offset * 1625000.0 / (12.0 * M_PI); d_fcch_start_pos = d_counter + start_pos; compute_freq_offset(); end = true; @@ -255,14 +263,7 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) } } - // DCOUT("hit_count: " << hit_count << " miss_count: " << miss_count << " d_counter: " << d_counter); - //! - for(int i = 0; i < to_consume; i++){ - //std::cout << "(" << real(in[i]) << "," << imag(in[i]) << ")\n"; - } - d_counter += to_consume; - consume_each(to_consume); return result; @@ -277,12 +278,13 @@ double gsm_receiver_cf::compute_freq_offset() freq_offset = phase_offset * 1625000.0 / (12.0 * M_PI); d_freq_offset -= freq_offset; -// d_x_temp += freq_offset; -// d_x2_temp += freq_offset * freq_offset; -// d_mean = d_x_temp / d_fcch_count; -// d_fcch_count++; - DCOUT("freq_offset: " << freq_offset << " d_best_sum: " << d_best_sum); -// DCOUT("wariancja: " << sqrt((d_x2_temp / d_fcch_count - d_mean * d_mean)) << " fcch_count:" << d_fcch_count << " d_mean: " << d_mean); + d_fcch_count++; + d_x_temp += freq_offset; + d_x2_temp += freq_offset * freq_offset; + d_mean = d_x_temp / d_fcch_count; + + DCOUT("freq_offset: " << freq_offset );//" d_best_sum: " << d_best_sum + DCOUT("wariancja: " << sqrt((d_x2_temp / d_fcch_count - d_mean * d_mean)) << " fcch_count:" << d_fcch_count << " d_mean: " << d_mean); return freq_offset; } @@ -299,19 +301,27 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl bool end = false; bool result = false; int sample_nr_near_sch_start = d_fcch_start_pos + (FRAME_BITS - SAFETY_MARGIN) * d_OSR; + vector_complex correlation_buffer; + list_float power_buffer; + vector_float window_energy_buffer; + int strongest_window_nr; - enum states { start, reach_sch, find_sch_start, search_not_finished, sch_found } sch_search_state; - + sch_search_state = start; + //!!!! + int chan_imp_length = 4; + float energy = 0; + bool loop_end = false; + list_float::iterator iter; - while (!end) { switch (sch_search_state) { + case start: - if(d_counter < sample_nr_near_sch_start){ + if (d_counter < sample_nr_near_sch_start) { sch_search_state = reach_sch; } else { sch_search_state = find_sch_start; @@ -319,48 +329,67 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl break; case reach_sch: - - if(d_counter + nitems >= sample_nr_near_sch_start){ + if (d_counter + nitems >= sample_nr_near_sch_start) { to_consume = sample_nr_near_sch_start - d_counter; - DCOUT("reach_sch consumes: " << to_consume << "bits"); } else { to_consume = nitems; } - - - sch_search_state = search_not_finished; break; case find_sch_start: - DCOUT("find_sch_start nitems" << nitems); -// if ((sch_start >= d_counter) && (sch_start <= d_counter + nitems)) { -// for (int i = 0; i < ninput_items[0] - N_SYNC_BITS; i++) { -// gr_complex result; -// d_counter++; -// result = correlation(&d_sch_training_seq[5], in + i, N_SYNC_BITS - 10); -// -// if (abs(result) > 60000) { -// DCOUT("znaleziono środek sch na pozycji: " << d_counter); -// } -// -// // std::cout << "(" << real(in[i]) << "," << imag(in[i]) << ")\n"; -// // std::cout << "(" << real(result) << "," << imag(result) << ")\n"; -// -// int ninput = N_SYNC_BITS - 10; -// const gr_complex * input_signal = in + i; -// gr_complex * sequence = &d_sch_training_seq[5]; -// } -// } - to_consume = nitems; +// DCOUT("find_sch_start d_counter" << d_counter); + for (int ii = SYNC_POS * d_OSR; ii < (SYNC_POS + SYNC_SEARCH_RANGE)*d_OSR; ii++) { + to_consume++; + gr_complex correlation = correlate_sequence(&d_sch_training_seq[5], &in[ii], N_SYNC_BITS - 10); + correlation_buffer.push_back(correlation); // tylko do znalezienia odp imp kanału + power_buffer.push_back(pow(abs(correlation), 2)); + if (abs(correlation) > 30000) { + DCOUT("znaleziono środek sch na pozycji: " << ii - SYNC_POS * d_OSR); + } + } + + //compute window energies + iter = power_buffer.begin(); + while (iter != power_buffer.end()) { + list_float::iterator iter_ii = iter; + energy = 0; + + for (int ii = 0; ii < chan_imp_length; ii++, iter_ii++) { + if (iter_ii == power_buffer.end()) { + loop_end = true; + break; + } + energy += (*iter_ii); + } + + if (loop_end) { + break; + } + iter++; +// std::cout << energy << "\n"; + 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(); + for (int ii = 0; ii < chan_imp_length; ii++) { + gr_complex correlation = correlation_buffer[strongest_window_nr + (ii * d_OSR)]; + d_channel_imp_resp.push_back(correlation); + } + + DCOUT("strongest_window_nr: " << strongest_window_nr); + sch_search_state = sch_found; break; case search_not_finished: + result = false; end = true; break; case sch_found: + result = true; end = true; break; } @@ -393,12 +422,12 @@ void gsm_receiver_cf::gmsk_mapper(const int * input, gr_complex * output, int ni } } -gr_complex gsm_receiver_cf::correlation(const gr_complex * sequence, const gr_complex * input_signal, int ninput) +gr_complex gsm_receiver_cf::correlate_sequence(const gr_complex * sequence, const gr_complex * input_signal, int length) { gr_complex result(0.0, 0.0); int sample_number = 0; - for (int ii = 0; ii < ninput; ii++) { + for (int ii = 0; ii < length; ii++) { sample_number = (ii * d_OSR) ; result += sequence[ii] * conj(input_signal[sample_number]); } @@ -406,6 +435,19 @@ gr_complex gsm_receiver_cf::correlation(const gr_complex * sequence, const gr_co return result; } +// gr_complex gsm_receiver_cf::compute_energy(const gr_complex * input_signal, int length) +// { +// float result = 0; +// int sample_number = 0; +// +// for (int ii = 0; ii < length; ii++) { +// result += input_signal[(ii * d_OSR)]; +// } +// +// return result; +// } + + // gr_complex gsm_receiver_cf::calc_energy(int window_len){ // // } @@ -413,4 +455,4 @@ inline float gsm_receiver_cf::compute_phase_diff(gr_complex val1, gr_complex val { gr_complex conjprod = val1 * conj(val2); return gr_fast_atan2f(imag(conjprod), real(conjprod)); -} \ No newline at end of file +} diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index ccc99fb..d4e26e5 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -25,8 +25,8 @@ #include #include #include -#include #include +#include class gsm_receiver_cf; @@ -43,8 +43,7 @@ class gsm_receiver_cf; * As a convention, the _sptr suffix indicates a boost::shared_ptr */ typedef boost::shared_ptr gsm_receiver_cf_sptr; - -typedef boost::circular_buffer circular_buffer_float; +typedef std::vector vector_complex; /*! * \brief Return a shared_ptr to a new instance of gsm_receiver_cf. @@ -75,12 +74,11 @@ class gsm_receiver_cf : public gr_block int d_fcch_start_pos; float d_freq_offset; double d_best_sum; - - int d_fcch_count; - bool d_first; -// int d_fcch_count; -// double d_x_temp, d_x2_temp, d_mean; + int d_fcch_count; //!!! + double d_x_temp, d_x2_temp, d_mean;//!! + + vector_complex d_channel_imp_resp; enum states { first_fcch_search, next_fcch_search, sch_search, read_bcch @@ -96,7 +94,7 @@ class gsm_receiver_cf : public gr_block bool find_sch_burst(const gr_complex *in, const int nitems , float *out); void gmsk_mapper(const int * input, gr_complex * gmsk_output, int ninput); - gr_complex correlation(const gr_complex * sequence, const gr_complex * input_signal, int ninput); + gr_complex correlate_sequence(const gr_complex * sequence, const gr_complex * input_signal, int ninput); public: diff --git a/src/python/gsm_findfcch.py b/src/python/gsm_findfcch.py index 09615bf..7ab9c18 100755 --- a/src/python/gsm_findfcch.py +++ b/src/python/gsm_findfcch.py @@ -10,7 +10,7 @@ from os import sys for extdir in ['../../debug/src/lib','../../debug/src/lib/.libs']: if extdir not in sys.path: sys.path.append(extdir) -import gsm +import gsm class tune(gr.feval_dd): def __init__(self, top_block): @@ -18,8 +18,8 @@ class tune(gr.feval_dd): self.top_block = top_block self.center_freq = 0 def eval(self, freq_offet): -# self.center_freq = self.center_freq - freq_offet - self.top_block.set_frequency(freq_offet) + self.center_freq = self.center_freq - freq_offet + self.top_block.set_frequency(self.center_freq) return self.center_freq @@ -57,13 +57,13 @@ class gsm_receiver_first_blood(gr.top_block): self.clock_rate = clock_rate self.input_rate = clock_rate / options.decim self.gsm_symb_rate = 1625000.0 / 6.0 - self.sps = ( self.input_rate / self.gsm_symb_rate ) / options.osr + self.sps = self.input_rate / self.gsm_symb_rate def _ustaw_filtr(self): filter_cutoff = 145e3 filter_t_width = 10e3 offset = 0 - #print "input_rate:", self.input_rate, "sample rate:", self.sps, " filter_cutoff:", filter_cutoff, " filter_t_width:", filter_t_width + print "input_rate:", self.input_rate, "sample rate:", self.sps, " filter_cutoff:", filter_cutoff, " filter_t_width:", filter_t_width filter_taps = gr.firdes.low_pass(1.0, self.input_rate, filter_cutoff, filter_t_width, gr.firdes.WIN_HAMMING) filtr = gr.freq_xlating_fir_filter_ccf(1, filter_taps, offset, self.input_rate) return filtr -- cgit v1.2.3 From b464d0b7e16abe2e1a2ff9aad73409c2b42228dd Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Wed, 6 May 2009 13:54:03 +0200 Subject: resampler causes that frequency estimate is getting lower for higher osr --- src/lib/gsm_receiver_cf.cc | 31 ++++++++++++++++++++++++------- src/python/gsm_findfcch.py | 13 ++++++------- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 045c639..8e4670b 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -208,7 +208,7 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) fcch_search_state = init; //DCOUT("hit_count: " << hit_count << " miss_count: " << miss_count << " d_counter: " << d_counter); continue; - } else if ((miss_count >= FCCH_MAX_MISSES * d_OSR) && (hit_count > FCCH_HITS_NEEDED * d_OSR)) { + } else if (((miss_count >= FCCH_MAX_MISSES * d_OSR) && (hit_count > FCCH_HITS_NEEDED * d_OSR)) || (hit_count > 2 * FCCH_HITS_NEEDED * d_OSR)) { fcch_search_state = fcch_found; continue; } else if ((miss_count < FCCH_MAX_MISSES * d_OSR) && (hit_count > FCCH_HITS_NEEDED * d_OSR)) { @@ -239,6 +239,7 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) } phase_diff = compute_phase_diff(in[sample_number], in[sample_number-1]); +// std::cout << phase_diff << "\n"; phase_diff_buffer.push_back(phase_diff); fcch_search_state = found_something; @@ -302,7 +303,7 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl bool result = false; int sample_nr_near_sch_start = d_fcch_start_pos + (FRAME_BITS - SAFETY_MARGIN) * d_OSR; vector_complex correlation_buffer; - list_float power_buffer; + vector_float power_buffer; vector_float window_energy_buffer; int strongest_window_nr; @@ -315,7 +316,7 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl int chan_imp_length = 4; float energy = 0; bool loop_end = false; - list_float::iterator iter; + vector_float::iterator iter; while (!end) { switch (sch_search_state) { @@ -350,34 +351,50 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl } //compute window energies + +// std::cout << "\nkorelacje wybrane do liczenia energii\n"; iter = power_buffer.begin(); + while (iter != power_buffer.end()) { - list_float::iterator iter_ii = iter; + vector_float::iterator iter_ii = iter; energy = 0; - for (int ii = 0; ii < chan_imp_length; ii++, iter_ii++) { + for (int ii = 0; ii < chan_imp_length; ii++) { if (iter_ii == power_buffer.end()) { loop_end = true; break; } +// std::cout << iter_ii - power_buffer.begin() << "\n"; energy += (*iter_ii); + iter_ii = iter_ii+d_OSR; } +// std::cout << "\n"; if (loop_end) { break; } iter++; -// std::cout << energy << "\n"; +// std::cout << energy << "\n"; 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(); - for (int ii = 0; ii < chan_imp_length; ii++) { + std::cout << "\nOdp impulsowa:\n"; + for (int ii = 0; ii < chan_imp_length+1; ii++) { gr_complex correlation = correlation_buffer[strongest_window_nr + (ii * d_OSR)]; + std::cout << correlation << "\n"; d_channel_imp_resp.push_back(correlation); } + std::cout << "\nBurst:\n"; + + for (int ii = 0; ii < 156; ii++) { + gr_complex correlation = in[strongest_window_nr + (ii * d_OSR) - 42* d_OSR + SYNC_POS * d_OSR]; + std::cout << correlation << "\n"; + d_channel_imp_resp.push_back(correlation); + } + std::cout << "\n\n"; DCOUT("strongest_window_nr: " << strongest_window_nr); sch_search_state = sch_found; diff --git a/src/python/gsm_findfcch.py b/src/python/gsm_findfcch.py index 7ab9c18..5f85dc2 100755 --- a/src/python/gsm_findfcch.py +++ b/src/python/gsm_findfcch.py @@ -16,12 +16,11 @@ class tune(gr.feval_dd): def __init__(self, top_block): gr.feval_dd.__init__(self) self.top_block = top_block - self.center_freq = 0 + # self.center_freq = 0 def eval(self, freq_offet): - self.center_freq = self.center_freq - freq_offet - self.top_block.set_frequency(self.center_freq) - return self.center_freq - + # self.center_freq = self.center_freq - freq_offet + self.top_block.set_frequency(freq_offet) + return freq_offet class gsm_receiver_first_blood(gr.top_block): def __init__(self): @@ -57,13 +56,13 @@ class gsm_receiver_first_blood(gr.top_block): self.clock_rate = clock_rate self.input_rate = clock_rate / options.decim self.gsm_symb_rate = 1625000.0 / 6.0 - self.sps = self.input_rate / self.gsm_symb_rate + self.sps = self.input_rate / self.gsm_symb_rate / self.options.osr def _ustaw_filtr(self): filter_cutoff = 145e3 filter_t_width = 10e3 offset = 0 - print "input_rate:", self.input_rate, "sample rate:", self.sps, " filter_cutoff:", filter_cutoff, " filter_t_width:", filter_t_width + #print "input_rate:", self.input_rate, "sample rate:", self.sps, " filter_cutoff:", filter_cutoff, " filter_t_width:", filter_t_width filter_taps = gr.firdes.low_pass(1.0, self.input_rate, filter_cutoff, filter_t_width, gr.firdes.WIN_HAMMING) filtr = gr.freq_xlating_fir_filter_ccf(1, filter_taps, offset, self.input_rate) return filtr -- cgit v1.2.3 From 8ac6aed74715e12208c8f84a5018303457edd9c8 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Thu, 14 May 2009 08:16:51 +0200 Subject: sch search is now working (but the code is dirty) --- src/lib/Assert.h | 2 +- src/lib/gsm_constants.h | 1 + src/lib/gsm_receiver_cf.cc | 146 ++++++++++++++++++++++++++++++++++++--------- src/lib/gsm_receiver_cf.h | 3 +- src/python/gsm_findfcch.py | 2 +- 5 files changed, 124 insertions(+), 30 deletions(-) diff --git a/src/lib/Assert.h b/src/lib/Assert.h index 67fe02f..acfb3f7 100644 --- a/src/lib/Assert.h +++ b/src/lib/Assert.h @@ -26,7 +26,7 @@ #include "stdio.h" #include -//#define NDEBUG +#define NDEBUG /**@name Macros for standard messages. */ //@{ diff --git a/src/lib/gsm_constants.h b/src/lib/gsm_constants.h index 50ea600..9ba70cb 100644 --- a/src/lib/gsm_constants.h +++ b/src/lib/gsm_constants.h @@ -12,6 +12,7 @@ #define N_SYNC_BITS 64 #define USEFUL_BITS 142 //(2*DATA_BITS + N_TRAIN_BITS ) #define FCCH_BITS USEFUL_BITS +#define BURST_SIZE (USEFUL_BITS+2*TAIL_BITS) #define TS_BITS (TAIL_BITS+USEFUL_BITS+TAIL_BITS+GUARD_BITS) //a full TS (156) #define TS_PER_FRAME 8 diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 8e4670b..5019c71 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -125,13 +125,14 @@ gsm_receiver_cf::general_work(int noutput_items, case sch_search: if (find_sch_burst(in, ninput_items[0], out)) { // d_state = read_bcch; - d_state = next_fcch_search; + d_state = read_bcch;//next_fcch_search; } else { d_state = sch_search; } break; case read_bcch: + consume_each(ninput_items[0]); break; } @@ -156,7 +157,6 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) bool end = false; bool result = false; // float mean=0, phase_offset=0, freq_offset=0; - circular_buffer_float::iterator buffer_iter; enum states { @@ -295,6 +295,12 @@ 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::find_sch_burst(const gr_complex *in, const int nitems , float *out) { // int sample_number = 0; @@ -306,6 +312,8 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl vector_float power_buffer; vector_float window_energy_buffer; int strongest_window_nr; + int chan_imp_resp_center; + float max_correlation = 0; enum states { start, reach_sch, find_sch_start, search_not_finished, sch_found @@ -313,10 +321,21 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl sch_search_state = start; //!!!! - int chan_imp_length = 4; + int chan_imp_length = 5; + //!!!! + gr_complex chan_imp_resp[100]; + gr_complex rhh_temp[100]; + gr_complex rhh[6]; + gr_complex filtered_burst[148]; + //!!!! + int burst_start = 0; + unsigned int stop_states[1] = { 4, }; + float output[BURST_SIZE]; + float energy = 0; bool loop_end = false; vector_float::iterator iter; + gr_complex dzielnik(54, 0); while (!end) { switch (sch_search_state) { @@ -342,31 +361,27 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl // DCOUT("find_sch_start d_counter" << d_counter); for (int ii = SYNC_POS * d_OSR; ii < (SYNC_POS + SYNC_SEARCH_RANGE)*d_OSR; ii++) { to_consume++; - gr_complex correlation = correlate_sequence(&d_sch_training_seq[5], &in[ii], N_SYNC_BITS - 10); + gr_complex correlation = correlate_sequence(&d_sch_training_seq[5], &in[ii], N_SYNC_BITS - 10) / dzielnik; correlation_buffer.push_back(correlation); // tylko do znalezienia odp imp kanału power_buffer.push_back(pow(abs(correlation), 2)); - if (abs(correlation) > 30000) { + if (abs(correlation) > 30000 / 54) { DCOUT("znaleziono środek sch na pozycji: " << ii - SYNC_POS * d_OSR); } } //compute window energies -// std::cout << "\nkorelacje wybrane do liczenia energii\n"; iter = power_buffer.begin(); - while (iter != power_buffer.end()) { vector_float::iterator iter_ii = iter; energy = 0; - for (int ii = 0; ii < chan_imp_length; ii++) { + for (int ii = 0; ii < (chan_imp_length)*d_OSR; ii++, iter_ii++) { if (iter_ii == power_buffer.end()) { loop_end = true; break; } -// std::cout << iter_ii - power_buffer.begin() << "\n"; energy += (*iter_ii); - iter_ii = iter_ii+d_OSR; } // std::cout << "\n"; @@ -374,26 +389,74 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl break; } iter++; -// std::cout << energy << "\n"; +// std::cout << energy << "\n"; 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(); - std::cout << "\nOdp impulsowa:\n"; - for (int ii = 0; ii < chan_imp_length+1; ii++) { - gr_complex correlation = correlation_buffer[strongest_window_nr + (ii * d_OSR)]; - std::cout << correlation << "\n"; - d_channel_imp_resp.push_back(correlation); - } - std::cout << "\nBurst:\n"; - - for (int ii = 0; ii < 156; ii++) { - gr_complex correlation = in[strongest_window_nr + (ii * d_OSR) - 42* d_OSR + SYNC_POS * d_OSR]; - std::cout << correlation << "\n"; +// std::cout << "# name: h_est\n" ; +// std::cout << "# type: complex matrix\n" ; +// std::cout << "# rows: 1\n" ; +// std::cout << "# columns: " << (chan_imp_length)*d_OSR << "\n"; + + max_correlation = 0; + for (int ii = 0; ii < (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); + } +// std::cout << correlation << " "; d_channel_imp_resp.push_back(correlation); + chan_imp_resp[ii] = correlation; } + DCOUT("\nSrodek odp_imp:" << chan_imp_resp_center ); + + autocorrelation(chan_imp_resp, rhh_temp, chan_imp_length*d_OSR); +// std::cout << "\n# name: rhh_temp\n" ; +// std::cout << "# type: complex matrix\n" ; +// std::cout << "# rows: 1\n" ; +// std::cout << "# columns: " << (chan_imp_length)*d_OSR << "\n"; + +// for (int ii = 0; ii < (chan_imp_length)*d_OSR; ii++) { +// std::cout << rhh_temp[ii] << " "; +// } + +// std::cout << "\n# name: Rhh\n" ; +// std::cout << "# type: complex matrix\n" ; +// std::cout << "# rows: 1\n" ; +// std::cout << "# columns: " << (chan_imp_length) << "\n"; + + for (int ii = 0; ii < (chan_imp_length); ii++) { + rhh[ii] = rhh_temp[ii*d_OSR]; +// std::cout << rhh_temp[ii*d_OSR] << " "; + } + +// std::cout << "\n# name: normal_burst\n" ; +// std::cout << "# type: complex matrix\n" ; +// std::cout << "# rows: 1\n" ; +// std::cout << "# columns: " << 156*d_OSR << "\n"; + burst_start = strongest_window_nr + chan_imp_resp_center - 48 * d_OSR - 2 * d_OSR + 2 + SYNC_POS * d_OSR; +// for (int ii = 0; ii < 156*d_OSR; ii++) { +// gr_complex sample = in[burst_start+ii]; +// std::cout << sample << " "; +// } + + mafi(&in[burst_start], 148, chan_imp_resp, chan_imp_length*d_OSR, filtered_burst); + +// std::cout << "\n# name: Y\n" ; +// std::cout << "# type: complex matrix\n" ; +// std::cout << "# rows: 1\n" ; +// std::cout << "# columns: " << 148 << "\n"; +// for (int ii = 0; ii < 148; ii++) { +// gr_complex filtered_sample = filtered_burst[ii]; +// std::cout << filtered_sample << " "; +// } + + viterbi_detector(filtered_burst, BURST_SIZE, rhh, 3, stop_states, 1, output); + std::cout << "\n\n"; DCOUT("strongest_window_nr: " << strongest_window_nr); @@ -413,9 +476,7 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl } d_counter += to_consume; - consume_each(to_consume); - return result; } @@ -468,8 +529,39 @@ gr_complex gsm_receiver_cf::correlate_sequence(const gr_complex * sequence, cons // gr_complex gsm_receiver_cf::calc_energy(int window_len){ // // } -inline float gsm_receiver_cf::compute_phase_diff(gr_complex val1, gr_complex val2) + +//oblicza dodatnią część autokorelacji +inline void gsm_receiver_cf::autocorrelation(const gr_complex * input, gr_complex * out, int length) { - gr_complex conjprod = val1 * conj(val2); - return gr_fast_atan2f(imag(conjprod), real(conjprod)); + int i, k; + for (k = length - 1; k >= 0; k--) { + out[k] = gr_complex(0, 0); + for (i = k; i < length; i++) { + out[k] += input[i] * conj(input[i-k]); + } + } +} + +//funkcja matched filter +inline void gsm_receiver_cf::mafi(const gr_complex * input, int input_length, gr_complex * filter, int filter_length, gr_complex * output) +{ + int ii = 0, n, a; + std::cout << "\n"; + for (n = 0; n < input_length; n++) { + a = n * d_OSR; + output[n] = 0; + ii = 0; + + while (ii < filter_length) { +// if (n == 0) { +// std::cout << "a:" << a << " ii: " << ii << " input[" << a + ii << "]: " << input[a+ii] << "\n"; +// } + if ((a + ii) >= input_length*d_OSR) + break; + + output[n] += input[a+ii] * filter[ii]; + ii++; + } +// output[n] = conj(output[n]); + } } diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index d4e26e5..20d66da 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -95,7 +95,8 @@ class gsm_receiver_cf : public gr_block bool find_sch_burst(const gr_complex *in, const int nitems , float *out); void gmsk_mapper(const int * input, gr_complex * gmsk_output, int ninput); gr_complex correlate_sequence(const gr_complex * sequence, const gr_complex * input_signal, int ninput); - + inline void autocorrelation(const gr_complex * input, gr_complex * out, int length); + inline void mafi(const gr_complex * input, int input_length, gr_complex * filter, int filter_length, gr_complex * output); public: ~gsm_receiver_cf(); diff --git a/src/python/gsm_findfcch.py b/src/python/gsm_findfcch.py index 5f85dc2..5df5971 100755 --- a/src/python/gsm_findfcch.py +++ b/src/python/gsm_findfcch.py @@ -83,7 +83,7 @@ class gsm_receiver_first_blood(gr.top_block): parser = OptionParser(option_class=eng_option) parser.add_option("-d", "--decim", type="int", default=128, help="Set USRP decimation rate to DECIM [default=%default]") - parser.add_option("-r", "--osr", type="int", default=1, + parser.add_option("-r", "--osr", type="int", default=4, help="Oversampling ratio [default=%default]") parser.add_option("-I", "--inputfile", type="string", default="cfile", help="Input filename") -- cgit v1.2.3 From f0532c01b907c0dcb1fb0f5efe9e9be9c47afc4f Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Wed, 20 May 2009 21:14:54 +0200 Subject: decoding of sch now works --- src/lib/gsm_receiver_cf.cc | 79 +++++++++++++++++++++++++++------------------- src/python/gsm_findfcch.py | 1 + 2 files changed, 48 insertions(+), 32 deletions(-) diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 5019c71..578cd80 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -24,7 +24,6 @@ #include "config.h" #endif -#include #include #include #include @@ -32,6 +31,9 @@ #include #include #include +#include +#include +#include #define FCCH_BUFFER_SIZE (FCCH_HITS_NEEDED) #define SYNC_SEARCH_RANGE 40 @@ -112,7 +114,7 @@ gsm_receiver_cf::general_work(int noutput_items, if (find_fcch_burst(in, ninput_items[0])) { if (abs(d_freq_offset) > 100) { float mean_freq_offset = (prev_freq_offset + d_freq_offset) / 2; -// set_frequency(d_freq_offset); + set_frequency(d_freq_offset); } produced_out = 0; d_state = sch_search; @@ -125,7 +127,7 @@ gsm_receiver_cf::general_work(int noutput_items, case sch_search: if (find_sch_burst(in, ninput_items[0], out)) { // d_state = read_bcch; - d_state = read_bcch;//next_fcch_search; + d_state = next_fcch_search;//read_bcch; } else { d_state = sch_search; } @@ -284,8 +286,8 @@ double gsm_receiver_cf::compute_freq_offset() d_x2_temp += freq_offset * freq_offset; d_mean = d_x_temp / d_fcch_count; - DCOUT("freq_offset: " << freq_offset );//" d_best_sum: " << d_best_sum - DCOUT("wariancja: " << sqrt((d_x2_temp / d_fcch_count - d_mean * d_mean)) << " fcch_count:" << d_fcch_count << " d_mean: " << d_mean); + DCOUT("freq_offset: " << freq_offset );//" d_best_sum: " << d_best_sum +// DCOUT("wariancja: " << sqrt((d_x2_temp / d_fcch_count - d_mean * d_mean)) << " fcch_count:" << d_fcch_count << " d_mean: " << d_mean); return freq_offset; } @@ -328,14 +330,16 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl gr_complex rhh[6]; gr_complex filtered_burst[148]; //!!!! + int fn_o; + int bsic_o; int burst_start = 0; - unsigned int stop_states[1] = { 4, }; + unsigned int stop_states[2] = {4,12}; float output[BURST_SIZE]; + unsigned char output_binary[BURST_SIZE]; float energy = 0; bool loop_end = false; vector_float::iterator iter; - gr_complex dzielnik(54, 0); while (!end) { switch (sch_search_state) { @@ -361,11 +365,11 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl // DCOUT("find_sch_start d_counter" << d_counter); for (int ii = SYNC_POS * d_OSR; ii < (SYNC_POS + SYNC_SEARCH_RANGE)*d_OSR; ii++) { to_consume++; - gr_complex correlation = correlate_sequence(&d_sch_training_seq[5], &in[ii], N_SYNC_BITS - 10) / dzielnik; + gr_complex correlation = correlate_sequence(&d_sch_training_seq[5], &in[ii], N_SYNC_BITS - 10); correlation_buffer.push_back(correlation); // tylko do znalezienia odp imp kanału power_buffer.push_back(pow(abs(correlation), 2)); if (abs(correlation) > 30000 / 54) { - DCOUT("znaleziono środek sch na pozycji: " << ii - SYNC_POS * d_OSR); +// DCOUT("znaleziono środek sch na pozycji: " << ii - SYNC_POS * d_OSR); } } @@ -400,7 +404,7 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl // std::cout << "# type: complex matrix\n" ; // std::cout << "# rows: 1\n" ; // std::cout << "# columns: " << (chan_imp_length)*d_OSR << "\n"; - + max_correlation = 0; for (int ii = 0; ii < (chan_imp_length)*d_OSR; ii++) { gr_complex correlation = correlation_buffer[strongest_window_nr + ii]; @@ -408,11 +412,11 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl chan_imp_resp_center = ii; max_correlation = abs(correlation); } -// std::cout << correlation << " "; +// std::cout << correlation << " "; d_channel_imp_resp.push_back(correlation); chan_imp_resp[ii] = correlation; } - DCOUT("\nSrodek odp_imp:" << chan_imp_resp_center ); +// DCOUT("\nSrodek odp_imp:" << chan_imp_resp_center ); autocorrelation(chan_imp_resp, rhh_temp, chan_imp_length*d_OSR); // std::cout << "\n# name: rhh_temp\n" ; @@ -430,8 +434,8 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl // std::cout << "# columns: " << (chan_imp_length) << "\n"; for (int ii = 0; ii < (chan_imp_length); ii++) { - rhh[ii] = rhh_temp[ii*d_OSR]; -// std::cout << rhh_temp[ii*d_OSR] << " "; + rhh[ii] = conj(rhh_temp[ii*d_OSR]); +// std::cout << rhh[ii] << " "; } // std::cout << "\n# name: normal_burst\n" ; @@ -439,10 +443,10 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl // std::cout << "# rows: 1\n" ; // std::cout << "# columns: " << 156*d_OSR << "\n"; burst_start = strongest_window_nr + chan_imp_resp_center - 48 * d_OSR - 2 * d_OSR + 2 + SYNC_POS * d_OSR; -// for (int ii = 0; ii < 156*d_OSR; ii++) { -// gr_complex sample = in[burst_start+ii]; -// std::cout << sample << " "; -// } + for (int ii = 0; ii < 156*d_OSR; ii++) { + gr_complex sample = in[burst_start+ii]; +// std::cout << sample << " "; + } mafi(&in[burst_start], 148, chan_imp_resp, chan_imp_length*d_OSR, filtered_burst); @@ -450,15 +454,22 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl // std::cout << "# type: complex matrix\n" ; // std::cout << "# rows: 1\n" ; // std::cout << "# columns: " << 148 << "\n"; -// for (int ii = 0; ii < 148; ii++) { -// gr_complex filtered_sample = filtered_burst[ii]; + for (int ii = 0; ii < 148; ii++) { + gr_complex filtered_sample = filtered_burst[ii]; // std::cout << filtered_sample << " "; -// } + } - viterbi_detector(filtered_burst, BURST_SIZE, rhh, 3, stop_states, 1, output); + viterbi_detector(filtered_burst, 148, rhh, 3, stop_states, 2, output); +// printf("# name: output\n# type: matrix\n# rows: 1\n# columns: 148\n"); + for(int i=0; i0); +// printf(" %d", output_binary[i]); + } +// printf("\n"); + decode_sch(&output_binary[3], &fn_o, &bsic_o); - std::cout << "\n\n"; - DCOUT("strongest_window_nr: " << strongest_window_nr); +// std::cout << "fn: " << fn_o << " bsic: " << bsic_o << "\n"; +// DCOUT("strongest_window_nr: " << strongest_window_nr); sch_search_state = sch_found; break; @@ -510,6 +521,7 @@ gr_complex gsm_receiver_cf::correlate_sequence(const gr_complex * sequence, cons result += sequence[ii] * conj(input_signal[sample_number]); } + result = result/gr_complex(length, 0); return result; } @@ -546,22 +558,25 @@ inline void gsm_receiver_cf::autocorrelation(const gr_complex * input, gr_comple inline void gsm_receiver_cf::mafi(const gr_complex * input, int input_length, gr_complex * filter, int filter_length, gr_complex * output) { int ii = 0, n, a; - std::cout << "\n"; +// std::cout << "\nfilter:"; +// for(n = 0; n < filter_length; n++) +// { +// std::cout << filter[n] << " "; +// } +// std::cout << "\n"; for (n = 0; n < input_length; n++) { a = n * d_OSR; output[n] = 0; ii = 0; - + while (ii < filter_length) { -// if (n == 0) { -// std::cout << "a:" << a << " ii: " << ii << " input[" << a + ii << "]: " << input[a+ii] << "\n"; -// } if ((a + ii) >= input_length*d_OSR) break; - - output[n] += input[a+ii] * filter[ii]; +// if(n==0) +// std::cout << input[a+ii] << " "; + output[n] += input[a+ii] * filter[ii]; //!!conj ii++; } -// output[n] = conj(output[n]); + output[n] = output[n]*gr_complex(0,-1);//!!nie powinno tego tu być } } diff --git a/src/python/gsm_findfcch.py b/src/python/gsm_findfcch.py index 5df5971..2050d33 100755 --- a/src/python/gsm_findfcch.py +++ b/src/python/gsm_findfcch.py @@ -73,6 +73,7 @@ class gsm_receiver_first_blood(gr.top_block): def _ustaw_interpolator(self): interpolator = gr.fractional_interpolator_cc(0, self.sps) +# interpolator = blks2.rational_resampler_ccf(13, 6) return interpolator def _ustaw_odbiornik(self): -- cgit v1.2.3 From 29eae4c8d199fe15cdfa6c871847151955c3724d Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Wed, 20 May 2009 21:15:48 +0200 Subject: changes to makefiles.am to add decoding library - neds a little cleanup --- Makefile.am | 1 - Makefile.common | 8 ++++++++ configure.ac | 4 ++-- src/lib/Makefile.am | 7 +++++-- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Makefile.am b/Makefile.am index f940fe8..863aebb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -17,4 +17,3 @@ EXTRA_DIST = \ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = gsm-receiver.pc - \ No newline at end of file diff --git a/Makefile.common b/Makefile.common index 6b62f25..7bd8dac 100644 --- a/Makefile.common +++ b/Makefile.common @@ -19,6 +19,14 @@ # the Free Software Foundation, Inc., 51 Franklin Street, # Boston, MA 02110-1301, USA. # +DECODER_INCLUDEDIR = $(top_srcdir)/src/lib/decoder +MAIN_INCLUDEDIR = $(top_srcdir)/src/lib + +#STD_DEFINES_AND_INCLUDES = \ +# -I$(DECODER_INCLUDEDIR) \ +# -I$(MAIN_INCLUDEDIR) + +DECODER_LA = $(top_builddir)/src/lib/decoder/libdecoder.la # includes grincludedir = $(includedir)/gnuradio diff --git a/configure.ac b/configure.ac index 556d5c5..aa33970 100644 --- a/configure.ac +++ b/configure.ac @@ -105,9 +105,9 @@ AC_CONFIG_FILES([\ config/Makefile \ src/Makefile \ src/lib/Makefile \ + src/lib/decoder/Makefile \ src/python/Makefile \ - gsm-receiver.pc \ - + gsm-receiver.pc ]) # doc/Makefile \ # src/python/run_tests \ diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index bec9b80..78c7511 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -21,6 +21,7 @@ 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 @@ -28,7 +29,7 @@ include $(top_srcdir)/Makefile.common ourpythondir = $(grpythondir) ourlibdir = $(grpyexecdir) -AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(WITH_INCLUDES) +AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(WITH_INCLUDES) -I$(DECODER_INCLUDEDIR) SWIGPYTHONARGS = $(SWIGPYTHONFLAGS) $(SWIGGRFLAGS) $(WITH_SWIG_INCLUDES) \ $(WITH_INCLUDES) @@ -75,7 +76,9 @@ _gsm_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version _gsm_la_LIBADD = \ $(PYTHON_LDFLAGS) \ libgsmdemod.la \ - -lstdc++ + -lstdc++ \ + decoder/libdecoder.la +# $(DECODER_LA) #libgsmdemod_la_LIBADD = -- cgit v1.2.3 From 0a452fcc8e030f5bdb7187e1db7182cfc488aa31 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Thu, 28 May 2009 19:39:56 +0200 Subject: cleanup of unneeded test code, separation of longer parts of fch_search into two functions, addidion of 'synchronized' state and reading of sch in this state --- src/lib/gsm_constants.h | 10 +- src/lib/gsm_receiver_cf.cc | 333 +++++++++++++++++++++++---------------------- src/lib/gsm_receiver_cf.h | 203 ++++++++++++++++++++++++--- src/python/gsm_findfcch.py | 108 --------------- 4 files changed, 362 insertions(+), 292 deletions(-) delete mode 100755 src/python/gsm_findfcch.py diff --git a/src/lib/gsm_constants.h b/src/lib/gsm_constants.h index 9ba70cb..d08df17 100644 --- a/src/lib/gsm_constants.h +++ b/src/lib/gsm_constants.h @@ -6,7 +6,7 @@ //Burst timing #define TAIL_BITS 3 -#define GUARD_BITS 8 //8.25 +#define GUARD_BITS 8.25 #define DATA_BITS 58 //size of 1 data block in normal burst #define N_TRAIN_BITS 26 #define N_SYNC_BITS 64 @@ -16,7 +16,7 @@ #define TS_BITS (TAIL_BITS+USEFUL_BITS+TAIL_BITS+GUARD_BITS) //a full TS (156) #define TS_PER_FRAME 8 -#define FRAME_BITS (TS_PER_FRAME * TS_BITS + 2) // +2 for extra 8*0.25 guard bits +#define FRAME_BITS (TS_PER_FRAME * TS_BITS) #define FCCH_POS TAIL_BITS #define SYNC_POS 39 #define TRAIN_POS 58 @@ -25,6 +25,8 @@ #define FCCH_HITS_NEEDED (USEFUL_BITS - 4) #define FCCH_MAX_MISSES 1 +#define CHAN_IMP_RESP_LENGTH 5 + static const int 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, @@ -32,6 +34,10 @@ static const int SYNC_BITS[] = { 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}; + + // Sync : .+...++.+..+++.++++++.++++++....++.+..+.+.+++.+.+...+..++++..+.. // Diff Encoded Sync: .++..+.+++.+..++.....++.....+...+.+++.+++++..+++++..++.+...+.++. diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 578cd80..089a563 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -38,6 +38,9 @@ #define FCCH_BUFFER_SIZE (FCCH_HITS_NEEDED) #define SYNC_SEARCH_RANGE 40 +//TODO !! - move this methods to some else place + +// - move it to some else place !! typedef std::list list_float; typedef std::vector vector_float; @@ -62,14 +65,15 @@ gsm_receiver_cf::gsm_receiver_cf(gr_feval_dd *tuner, int osr) 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_fcch_count(0), //!! - d_x_temp(0),//!! - d_x2_temp(0)//!! + d_state(first_fcch_search) +// d_fcch_count(0), //!! +// d_x_temp(0),//!! +// d_x2_temp(0)//!! { gmsk_mapper(SYNC_BITS, d_sch_training_seq, N_SYNC_BITS); } @@ -98,6 +102,7 @@ gsm_receiver_cf::general_work(int noutput_items, float prev_freq_offset; switch (d_state) { + //bootstrapping case first_fcch_search: if (find_fcch_burst(in, ninput_items[0])) { set_frequency(d_freq_offset); @@ -113,7 +118,6 @@ gsm_receiver_cf::general_work(int noutput_items, prev_freq_offset = d_freq_offset; if (find_fcch_burst(in, ninput_items[0])) { if (abs(d_freq_offset) > 100) { - float mean_freq_offset = (prev_freq_offset + d_freq_offset) / 2; set_frequency(d_freq_offset); } produced_out = 0; @@ -126,15 +130,59 @@ gsm_receiver_cf::general_work(int noutput_items, case sch_search: if (find_sch_burst(in, ninput_items[0], out)) { -// d_state = read_bcch; - d_state = next_fcch_search;//read_bcch; + d_channel_conf.set_multiframe_type(0, multiframe_51); + d_channel_conf.set_burst_types(0, FCCH_FRAMES, sizeof(FCCH_FRAMES) / sizeof(unsigned), fcch_burst); + d_channel_conf.set_burst_types(0, SCH_FRAMES, sizeof(SCH_FRAMES) / sizeof(unsigned), sch_burst); + d_burst_nr++; + d_state = synchronized; } else { d_state = sch_search; } break; - case read_bcch: - consume_each(ninput_items[0]); + //in this state receiver is synchronized and it processes bursts according to burst type for given burst number + case synchronized: { + gr_complex chan_imp_resp[100];//!! + burst_type b_type = d_channel_conf.get_burst_type(d_burst_nr); + int burst_start; + int offset = 0; + int to_consume = 0; + unsigned char output_binary[BURST_SIZE]; + + switch (b_type) { + case fcch_burst: { + + } + break; + case sch_burst: { + int t1, t2, t3, d_ncc, d_bcc; + burst_start = get_sch_chan_imp_resp(in, chan_imp_resp); + detect_burst(in, chan_imp_resp, burst_start, output_binary); + if(decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc) == 0){ +// d_burst_nr.set(t1, t2, t3, 0); + printf("bcc: %d, ncc: %d, t1: %d, t2: %d, t3: %d\n", d_bcc, d_ncc, t1, t2, t3); + offset = burst_start - GUARD_BITS * d_OSR; + to_consume += offset; + } + std::cout << offset << std::endl; + } + break; + case normal_burst: + + break; + + case rach_burst: + break; + case dummy: + break; + case empty: + break; + } + + d_burst_nr++; + to_consume += floor(TS_BITS * d_OSR); + consume_each(to_consume); + } break; } @@ -158,7 +206,6 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) int sample_number = 0; bool end = false; bool result = false; -// float mean=0, phase_offset=0, freq_offset=0; circular_buffer_float::iterator buffer_iter; enum states { @@ -208,7 +255,6 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) if ((miss_count >= FCCH_MAX_MISSES * d_OSR) && (hit_count <= FCCH_HITS_NEEDED * d_OSR)) { fcch_search_state = init; - //DCOUT("hit_count: " << hit_count << " miss_count: " << miss_count << " d_counter: " << d_counter); 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)) { fcch_search_state = fcch_found; @@ -241,18 +287,15 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) } phase_diff = compute_phase_diff(in[sample_number], in[sample_number-1]); -// std::cout << phase_diff << "\n"; phase_diff_buffer.push_back(phase_diff); fcch_search_state = found_something; break; case fcch_found: - DCOUT("znalezione fcch na pozycji" << d_counter + start_pos); + DCOUT("fcch found on position: " << d_counter + start_pos); to_consume = start_pos + FCCH_HITS_NEEDED * d_OSR + 1; -// mean = d_best_sum / FCCH_HITS_NEEDED; -// phase_offset = mean - (M_PI / 2); -// freq_offset = phase_offset * 1625000.0 / (12.0 * M_PI); + d_fcch_start_pos = d_counter + start_pos; compute_freq_offset(); end = true; @@ -281,13 +324,13 @@ double gsm_receiver_cf::compute_freq_offset() freq_offset = phase_offset * 1625000.0 / (12.0 * M_PI); d_freq_offset -= freq_offset; - d_fcch_count++; - d_x_temp += freq_offset; - d_x2_temp += freq_offset * freq_offset; - d_mean = d_x_temp / d_fcch_count; +// d_fcch_count++; +// d_x_temp += freq_offset; +// d_x2_temp += freq_offset * freq_offset; +// d_mean = d_x_temp / d_fcch_count; - DCOUT("freq_offset: " << freq_offset );//" d_best_sum: " << d_best_sum -// DCOUT("wariancja: " << sqrt((d_x2_temp / d_fcch_count - d_mean * d_mean)) << " fcch_count:" << d_fcch_count << " d_mean: " << d_mean); + DCOUT("freq_offset: " << freq_offset );//" d_best_sum: " << d_best_sum +// DCOUT("wariance: " << sqrt((d_x2_temp / d_fcch_count - d_mean * d_mean)) << " fcch_count:" << d_fcch_count << " d_mean: " << d_mean); return freq_offset; } @@ -305,41 +348,23 @@ inline float gsm_receiver_cf::compute_phase_diff(gr_complex val1, gr_complex val bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , float *out) { -// int sample_number = 0; int to_consume = 0; bool end = false; bool result = false; int sample_nr_near_sch_start = d_fcch_start_pos + (FRAME_BITS - SAFETY_MARGIN) * d_OSR; - vector_complex correlation_buffer; - vector_float power_buffer; - vector_float window_energy_buffer; - int strongest_window_nr; - int chan_imp_resp_center; - float max_correlation = 0; + gr_complex chan_imp_resp[CHAN_IMP_RESP_LENGTH*d_OSR]; +// vector_complex correlation_buffer; +// vector_float power_buffer; +// vector_float window_energy_buffer; enum states { - start, reach_sch, find_sch_start, search_not_finished, sch_found + start, reach_sch, find_sch_start, detect_and_decode_sch, search_not_finished, sch_found } sch_search_state; sch_search_state = start; - //!!!! - int chan_imp_length = 5; - //!!!! - gr_complex chan_imp_resp[100]; - gr_complex rhh_temp[100]; - gr_complex rhh[6]; - gr_complex filtered_burst[148]; - //!!!! - int fn_o; - int bsic_o; + int t1, t2, t3; int burst_start = 0; - unsigned int stop_states[2] = {4,12}; - float output[BURST_SIZE]; unsigned char output_binary[BURST_SIZE]; - - float energy = 0; - bool loop_end = false; - vector_float::iterator iter; while (!end) { switch (sch_search_state) { @@ -362,115 +387,16 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl break; case find_sch_start: -// DCOUT("find_sch_start d_counter" << d_counter); - for (int ii = SYNC_POS * d_OSR; ii < (SYNC_POS + SYNC_SEARCH_RANGE)*d_OSR; ii++) { - to_consume++; - gr_complex correlation = correlate_sequence(&d_sch_training_seq[5], &in[ii], N_SYNC_BITS - 10); - correlation_buffer.push_back(correlation); // tylko do znalezienia odp imp kanału - power_buffer.push_back(pow(abs(correlation), 2)); - if (abs(correlation) > 30000 / 54) { -// DCOUT("znaleziono środek sch na pozycji: " << ii - SYNC_POS * d_OSR); - } - } - - //compute window energies - - iter = power_buffer.begin(); - while (iter != power_buffer.end()) { - vector_float::iterator iter_ii = iter; - energy = 0; - - for (int ii = 0; ii < (chan_imp_length)*d_OSR; ii++, iter_ii++) { - if (iter_ii == power_buffer.end()) { - loop_end = true; - break; - } - energy += (*iter_ii); - } -// std::cout << "\n"; - - if (loop_end) { - break; - } - iter++; -// std::cout << energy << "\n"; - 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(); - -// std::cout << "# name: h_est\n" ; -// std::cout << "# type: complex matrix\n" ; -// std::cout << "# rows: 1\n" ; -// std::cout << "# columns: " << (chan_imp_length)*d_OSR << "\n"; - - max_correlation = 0; - for (int ii = 0; ii < (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); - } -// std::cout << correlation << " "; - d_channel_imp_resp.push_back(correlation); - chan_imp_resp[ii] = correlation; - } -// DCOUT("\nSrodek odp_imp:" << chan_imp_resp_center ); - - autocorrelation(chan_imp_resp, rhh_temp, chan_imp_length*d_OSR); -// std::cout << "\n# name: rhh_temp\n" ; -// std::cout << "# type: complex matrix\n" ; -// std::cout << "# rows: 1\n" ; -// std::cout << "# columns: " << (chan_imp_length)*d_OSR << "\n"; - -// for (int ii = 0; ii < (chan_imp_length)*d_OSR; ii++) { -// std::cout << rhh_temp[ii] << " "; -// } - -// std::cout << "\n# name: Rhh\n" ; -// std::cout << "# type: complex matrix\n" ; -// std::cout << "# rows: 1\n" ; -// std::cout << "# columns: " << (chan_imp_length) << "\n"; - - for (int ii = 0; ii < (chan_imp_length); ii++) { - rhh[ii] = conj(rhh_temp[ii*d_OSR]); -// std::cout << rhh[ii] << " "; - } - -// std::cout << "\n# name: normal_burst\n" ; -// std::cout << "# type: complex matrix\n" ; -// std::cout << "# rows: 1\n" ; -// std::cout << "# columns: " << 156*d_OSR << "\n"; - burst_start = strongest_window_nr + chan_imp_resp_center - 48 * d_OSR - 2 * d_OSR + 2 + SYNC_POS * d_OSR; - for (int ii = 0; ii < 156*d_OSR; ii++) { - gr_complex sample = in[burst_start+ii]; -// std::cout << sample << " "; - } - - mafi(&in[burst_start], 148, chan_imp_resp, chan_imp_length*d_OSR, filtered_burst); - -// std::cout << "\n# name: Y\n" ; -// std::cout << "# type: complex matrix\n" ; -// std::cout << "# rows: 1\n" ; -// std::cout << "# columns: " << 148 << "\n"; - for (int ii = 0; ii < 148; ii++) { - gr_complex filtered_sample = filtered_burst[ii]; -// std::cout << filtered_sample << " "; - } - - viterbi_detector(filtered_burst, 148, rhh, 3, stop_states, 2, output); -// printf("# name: output\n# type: matrix\n# rows: 1\n# columns: 148\n"); - for(int i=0; i0); -// printf(" %d", output_binary[i]); - } -// printf("\n"); - decode_sch(&output_binary[3], &fn_o, &bsic_o); - -// std::cout << "fn: " << fn_o << " bsic: " << bsic_o << "\n"; -// DCOUT("strongest_window_nr: " << strongest_window_nr); + burst_start = get_sch_chan_imp_resp(in, chan_imp_resp); + sch_search_state = detect_and_decode_sch; + break; + case detect_and_decode_sch: + detect_burst(in, chan_imp_resp, burst_start, output_binary); + decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc); + d_burst_nr.set(t1, t2, t3, 0); + printf("bcc: %d, ncc: %d, t1: %d, t2: %d, t3: %d\n", d_bcc, d_ncc, t1, t2, t3); + to_consume += burst_start + BURST_SIZE * d_OSR; sch_search_state = sch_found; break; @@ -491,6 +417,87 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl return result; } +int gsm_receiver_cf::get_sch_chan_imp_resp(const gr_complex *in, 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; + 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], &in[ii], N_SYNC_BITS - 10); + 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 * in, 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(&in[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 int * input, gr_complex * output, int ninput) { gr_complex j = gr_complex(0.0, 1.0); @@ -511,6 +518,7 @@ void gsm_receiver_cf::gmsk_mapper(const int * input, gr_complex * output, int ni } } +//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, const gr_complex * input_signal, int length) { gr_complex result(0.0, 0.0); @@ -521,7 +529,7 @@ gr_complex gsm_receiver_cf::correlate_sequence(const gr_complex * sequence, cons result += sequence[ii] * conj(input_signal[sample_number]); } - result = result/gr_complex(length, 0); + result = result / gr_complex(length, 0); return result; } @@ -543,6 +551,7 @@ gr_complex gsm_receiver_cf::correlate_sequence(const gr_complex * sequence, cons // } //oblicza dodatnią część autokorelacji +//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 length) { int i, k; @@ -554,29 +563,23 @@ inline void gsm_receiver_cf::autocorrelation(const gr_complex * input, gr_comple } } +//TODO consider use of some generalized function for filtering and placing it in a separate class for signal processing //funkcja matched filter inline void gsm_receiver_cf::mafi(const gr_complex * input, int input_length, gr_complex * filter, int filter_length, gr_complex * output) { int ii = 0, n, a; -// std::cout << "\nfilter:"; -// for(n = 0; n < filter_length; n++) -// { -// std::cout << filter[n] << " "; -// } -// std::cout << "\n"; + for (n = 0; n < input_length; n++) { a = n * d_OSR; output[n] = 0; ii = 0; - + while (ii < filter_length) { if ((a + ii) >= input_length*d_OSR) break; -// if(n==0) -// std::cout << input[a+ii] << " "; output[n] += input[a+ii] * filter[ii]; //!!conj ii++; } - output[n] = output[n]*gr_complex(0,-1);//!!nie powinno tego tu być + output[n] = output[n] * gr_complex(0, -1);//!!this shouldn't be here } } diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index 20d66da..2bad50e 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -29,19 +29,176 @@ #include +//TODO !! - move this classes to some other place +#include +#include +typedef enum {empty, fcch_burst, sch_burst, normal_burst, rach_burst, dummy} burst_type; +typedef enum {unknown, multiframe_26, multiframe_51} multiframe_type; + +class multiframe_configuration +{ + private: + multiframe_type d_type; + std::vector d_burst_types; + public: + multiframe_configuration() { + d_type = unknown; + fill(d_burst_types.begin(), d_burst_types.end(), empty); + } + +// multiframe_configuration(multiframe_type type, const std::vector & burst_types): +// d_type(type) { +// d_burst_types.resize(burst_types.size()); +// copy(burst_types.begin(), burst_types.end(), d_burst_types.begin()); +// } + +// multiframe_configuration(multiframe_configuration & conf) { +// d_type = conf.d_type; +// copy(conf.d_burst_types.begin(), conf.d_burst_types.end(), d_burst_types.begin()); +// } + + ~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: + uint32_t d_t1, d_t2, d_t3, d_timeslot_nr; + public: + burst_counter(): + d_t1(0), + d_t2(0), + d_t3(0), + d_timeslot_nr(0) { + } + + burst_counter(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) { + } + + 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; + } + return (*this); + } + + void 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; + } + + 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; + } +}; + +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_timeslot_desc(int timeslot_nr, multiframe_configuration conf){ +// d_timeslots_descriptions[timeslot_nr] = conf; +// } + 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); +}; + +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); +} +// move it to some other place !! + class gsm_receiver_cf; -/* - * We use boost::shared_ptr's instead of raw pointers for all access - * to gr_blocks (and many other data structures). The shared_ptr gets - * us transparent reference counting, which greatly simplifies storage - * management issues. This is especially helpful in our hybrid - * C++ / Python system. - * - * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm - * - * As a convention, the _sptr suffix indicates a boost::shared_ptr - */ typedef boost::shared_ptr gsm_receiver_cf_sptr; typedef std::vector vector_complex; @@ -65,6 +222,8 @@ class gsm_receiver_cf : public gr_block private: const int d_OSR; + const int d_chan_imp_length; + gr_complex d_sch_training_seq[N_SYNC_BITS]; //encoded training sequence of a SCH burst gr_feval_dd *d_tuner; @@ -74,14 +233,22 @@ class gsm_receiver_cf : public gr_block int d_fcch_start_pos; float d_freq_offset; double d_best_sum; - - int d_fcch_count; //!!! - double d_x_temp, d_x2_temp, d_mean;//!! - + +// int d_fcch_count; //!!! +// double d_x_temp, d_x2_temp, d_mean;//!! + + burst_counter d_burst_nr; + channel_configuration d_channel_conf; + vector_complex d_channel_imp_resp; + int d_ncc; + int d_bcc; + enum states { - first_fcch_search, next_fcch_search, sch_search, read_bcch + //synchronization search part + first_fcch_search, next_fcch_search, sch_search, synchronized + // } d_state; friend gsm_receiver_cf_sptr gsm_make_receiver_cf(gr_feval_dd *tuner, int osr); @@ -91,8 +258,10 @@ class gsm_receiver_cf : public gr_block double compute_freq_offset(); void set_frequency(double freq_offset); inline float compute_phase_diff(gr_complex val1, gr_complex val2); - + bool find_sch_burst(const gr_complex *in, const int nitems , float *out); + int get_sch_chan_imp_resp(const gr_complex *in, gr_complex * chan_imp_resp); + void detect_burst(const gr_complex * in, gr_complex * chan_imp_resp, int burst_start, unsigned char * output_binary); void gmsk_mapper(const int * input, gr_complex * gmsk_output, int ninput); gr_complex correlate_sequence(const gr_complex * sequence, const gr_complex * input_signal, int ninput); inline void autocorrelation(const gr_complex * input, gr_complex * out, int length); diff --git a/src/python/gsm_findfcch.py b/src/python/gsm_findfcch.py deleted file mode 100755 index 2050d33..0000000 --- a/src/python/gsm_findfcch.py +++ /dev/null @@ -1,108 +0,0 @@ -#!/usr/bin/env python -#!/usr/bin/env python - -from gnuradio import gr, gru, blks2 -#, gsm -from gnuradio.eng_option import eng_option -from optparse import OptionParser -from os import sys - -for extdir in ['../../debug/src/lib','../../debug/src/lib/.libs']: - if extdir not in sys.path: - sys.path.append(extdir) -import gsm - -class tune(gr.feval_dd): - def __init__(self, top_block): - gr.feval_dd.__init__(self) - self.top_block = top_block - # self.center_freq = 0 - def eval(self, freq_offet): - # self.center_freq = self.center_freq - freq_offet - self.top_block.set_frequency(freq_offet) - return freq_offet - -class gsm_receiver_first_blood(gr.top_block): - def __init__(self): - gr.top_block.__init__(self) - (options, args) = self._przetworz_opcje() - self.tune_callback = tune(self) - self.options = options - self.args = args - self._ustaw_taktowanie() - self.zrodlo = self._ustaw_zrodlo() - self.filtr = self._ustaw_filtr() - self.interpolator = self._ustaw_interpolator() - self.odbiornik = self._ustaw_odbiornik() - self.konwerter = self._ustaw_konwerter() - self.ujscie = self._ustaw_ujscie() - - self.connect(self.zrodlo, self.filtr, self.interpolator, self.odbiornik, self.konwerter, self.ujscie) -# self.connect(self.zrodlo, self.ujscie) - - def _ustaw_ujscie(self): - nazwa_pliku_wy = self.options.outputfile - ujscie = gr.file_sink(gr.sizeof_float, nazwa_pliku_wy) - return ujscie - - def _ustaw_zrodlo(self): - nazwa_pliku = self.options.inputfile - zrodlo = gr.file_source(gr.sizeof_gr_complex, nazwa_pliku, False) - return zrodlo - - def _ustaw_taktowanie(self): - options = self.options - clock_rate = 64e6 - self.clock_rate = clock_rate - self.input_rate = clock_rate / options.decim - self.gsm_symb_rate = 1625000.0 / 6.0 - self.sps = self.input_rate / self.gsm_symb_rate / self.options.osr - - def _ustaw_filtr(self): - filter_cutoff = 145e3 - filter_t_width = 10e3 - offset = 0 - #print "input_rate:", self.input_rate, "sample rate:", self.sps, " filter_cutoff:", filter_cutoff, " filter_t_width:", filter_t_width - filter_taps = gr.firdes.low_pass(1.0, self.input_rate, filter_cutoff, filter_t_width, gr.firdes.WIN_HAMMING) - filtr = gr.freq_xlating_fir_filter_ccf(1, filter_taps, offset, self.input_rate) - return filtr - - def _ustaw_konwerter(self): - v2s = gr.vector_to_stream(gr.sizeof_float, 142) - return v2s - - def _ustaw_interpolator(self): - interpolator = gr.fractional_interpolator_cc(0, self.sps) -# interpolator = blks2.rational_resampler_ccf(13, 6) - return interpolator - - def _ustaw_odbiornik(self): - odbiornik = gsm.receiver_cf(self.tune_callback, self.options.osr) - return odbiornik - - def _przetworz_opcje(self): - parser = OptionParser(option_class=eng_option) - parser.add_option("-d", "--decim", type="int", default=128, - help="Set USRP decimation rate to DECIM [default=%default]") - parser.add_option("-r", "--osr", type="int", default=4, - help="Oversampling ratio [default=%default]") - parser.add_option("-I", "--inputfile", type="string", default="cfile", - help="Input filename") - parser.add_option("-O", "--outputfile", type="string", default="cfile2.out", - help="Output filename") - (options, args) = parser.parse_args () - return (options, args) - - def set_frequency(self, center_freq): - self.filtr.set_center_freq(center_freq) - -def main(): - try: - gsm_receiver_first_blood().run() - except KeyboardInterrupt: - pass - -if __name__ == '__main__': - main() - - -- cgit v1.2.3 From 19e70e64b98c50eb8bcc6221d43e3c3b615d88ca Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Thu, 28 May 2009 19:44:12 +0200 Subject: added decoder to the repository --- src/lib/decoder/Makefile.am | 34 +++++ src/lib/decoder/burst_types.h | 213 +++++++++++++++++++++++++++ src/lib/decoder/sch.c | 333 ++++++++++++++++++++++++++++++++++++++++++ src/lib/decoder/sch.h | 17 +++ src/lib/decoder/system.h | 11 ++ 5 files changed, 608 insertions(+) create mode 100644 src/lib/decoder/Makefile.am create mode 100644 src/lib/decoder/burst_types.h create mode 100644 src/lib/decoder/sch.c create mode 100644 src/lib/decoder/sch.h create mode 100644 src/lib/decoder/system.h diff --git a/src/lib/decoder/Makefile.am b/src/lib/decoder/Makefile.am new file mode 100644 index 0000000..32b55e0 --- /dev/null +++ b/src/lib/decoder/Makefile.am @@ -0,0 +1,34 @@ +# +# 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) -I$(MAIN_INCLUDEDIR) + +noinst_LTLIBRARIES = libdecoder.la + +libdecoder_la_SOURCES = \ + sch.c + +noinst_HEADERS = \ + sch.h \ + burst_types.h \ + system.h diff --git a/src/lib/decoder/burst_types.h b/src/lib/decoder/burst_types.h new file mode 100644 index 0000000..990e8f1 --- /dev/null +++ b/src/lib/decoder/burst_types.h @@ -0,0 +1,213 @@ +// $Id: burst_types.h,v 1.5 2007/03/14 05:44:53 jl Exp $ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +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/sch.c b/src/lib/decoder/sch.c new file mode 100644 index 0000000..9f570c9 --- /dev/null +++ b/src/lib/decoder/sch.c @@ -0,0 +1,333 @@ +#include "system.h" +#include +#include +#include +#include +#include "burst_types.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, SB_EDATA_LEN_1); + memcpy(data + SB_EDATA_LEN_1, buf + SB_EDATA_LEN_1 + N_SYNC_BITS, SB_EDATA_LEN_2); + + // 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 new file mode 100644 index 0000000..199d739 --- /dev/null +++ b/src/lib/decoder/sch.h @@ -0,0 +1,17 @@ + +#ifndef __GSMSTACK_H__ +#define __GSMSTACK_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 new file mode 100644 index 0000000..414730a --- /dev/null +++ b/src/lib/decoder/system.h @@ -0,0 +1,11 @@ + +#ifndef __GSMTVOID_SYSTEM_H__ +#define __GSMTVOID_SYSTEM_H__ 1 + +#define DEBUGF(a...) { \ + fprintf(stderr, "%s:%d ", __FILE__, __LINE__); \ + fprintf(stderr, a); \ +} while (0) + +#endif + -- cgit v1.2.3 From af882b8366031073fab380204a3abfc21cd921df Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Thu, 28 May 2009 19:45:32 +0200 Subject: added viterbi detector --- src/lib/viterbi_detector.h | 552 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 552 insertions(+) create mode 100644 src/lib/viterbi_detector.h diff --git a/src/lib/viterbi_detector.h b/src/lib/viterbi_detector.h new file mode 100644 index 0000000..2a2fede --- /dev/null +++ b/src/lib/viterbi_detector.h @@ -0,0 +1,552 @@ +/*************************************************************************** + * Copyright (C) 2008 by Piotr Krysik * + * pkrysik@stud.elka.pw.edu.pl * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 +#include +#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 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 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; + } +} -- cgit v1.2.3 From 3d271a927940df0d7368c774c0e1ed0881e6d493 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Thu, 28 May 2009 20:27:13 +0200 Subject: added new python script gsm_receive --- src/lib/gsm_receiver_cf.cc | 39 +++++++++------- src/lib/gsm_receiver_cf.h | 4 +- src/python/gsm_receive.py | 108 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 17 deletions(-) create mode 100755 src/python/gsm_receive.py diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 089a563..5453253 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -151,7 +151,19 @@ gsm_receiver_cf::general_work(int noutput_items, switch (b_type) { case fcch_burst: { - + int ii; + int first_sample = (GUARD_BITS+TAIL_BITS)*d_OSR; + int last_sample = first_sample+USEFUL_BITS*d_OSR; + double phase_sum = 0; + for(ii = first_sample; ii < last_sample; ii++){ + phase_sum += compute_phase_diff(in[ii], in[ii-1]) - (M_PI / 2) / d_OSR; + } + std::cout << "freq_offset: " << d_freq_offset << "\n"; + + double freq_offset = compute_freq_offset(phase_sum, USEFUL_BITS-TAIL_BITS); + d_freq_offset -= freq_offset; + set_frequency(d_freq_offset); + std::cout << "freq_offset: " << d_freq_offset << "\n"; } break; case sch_burst: { @@ -200,12 +212,14 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) int start_pos = -1; float min_phase_diff; float max_phase_diff; + double best_sum; float lowest_max_min_diff = 99999; int to_consume = 0; int sample_number = 0; bool end = false; bool result = false; + double freq_offset; circular_buffer_float::iterator buffer_iter; enum states { @@ -269,12 +283,12 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) 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; - d_best_sum = 0; + best_sum = 0; for (buffer_iter = phase_diff_buffer.begin(); buffer_iter != (phase_diff_buffer.end()); buffer_iter++) { - d_best_sum += *buffer_iter - (M_PI / 2) / d_OSR; + best_sum += *buffer_iter - (M_PI / 2) / d_OSR; } } } @@ -297,7 +311,9 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) to_consume = start_pos + FCCH_HITS_NEEDED * d_OSR + 1; d_fcch_start_pos = d_counter + start_pos; - compute_freq_offset(); + freq_offset = compute_freq_offset(best_sum, FCCH_HITS_NEEDED); + d_freq_offset -= freq_offset; + end = true; result = true; break; @@ -315,21 +331,19 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) return result; } - -double gsm_receiver_cf::compute_freq_offset() +double gsm_receiver_cf::compute_freq_offset(double best_sum, unsigned denominator) { float phase_offset, freq_offset; - phase_offset = d_best_sum / FCCH_HITS_NEEDED; + phase_offset = best_sum / denominator; freq_offset = phase_offset * 1625000.0 / (12.0 * M_PI); - d_freq_offset -= freq_offset; // d_fcch_count++; // d_x_temp += freq_offset; // d_x2_temp += freq_offset * freq_offset; // d_mean = d_x_temp / d_fcch_count; - DCOUT("freq_offset: " << freq_offset );//" d_best_sum: " << d_best_sum + DCOUT("freq_offset: " << freq_offset );//" best_sum: " << best_sum // DCOUT("wariance: " << sqrt((d_x2_temp / d_fcch_count - d_mean * d_mean)) << " fcch_count:" << d_fcch_count << " d_mean: " << d_mean); return freq_offset; @@ -545,12 +559,7 @@ gr_complex gsm_receiver_cf::correlate_sequence(const gr_complex * sequence, cons // return result; // } - -// gr_complex gsm_receiver_cf::calc_energy(int window_len){ -// -// } - -//oblicza dodatnią część autokorelacji +//computes autocorrelation for positive values //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 length) { diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index 2bad50e..98df34d 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -232,7 +232,7 @@ class gsm_receiver_cf : public gr_block //variables used to store result of the find_fcch_burst fuction int d_fcch_start_pos; float d_freq_offset; - double d_best_sum; +// double d_best_sum; // int d_fcch_count; //!!! // double d_x_temp, d_x2_temp, d_mean;//!! @@ -255,7 +255,7 @@ class gsm_receiver_cf : public gr_block gsm_receiver_cf(gr_feval_dd *tuner, int osr); bool find_fcch_burst(const gr_complex *in, const int nitems); - double compute_freq_offset(); + double compute_freq_offset(double best_sum, unsigned denominator); void set_frequency(double freq_offset); inline float compute_phase_diff(gr_complex val1, gr_complex val2); diff --git a/src/python/gsm_receive.py b/src/python/gsm_receive.py new file mode 100755 index 0000000..449f7d8 --- /dev/null +++ b/src/python/gsm_receive.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python +#!/usr/bin/env python + +from gnuradio import gr, gru, blks2 +#, gsm +from gnuradio.eng_option import eng_option +from optparse import OptionParser +from os import sys + +for extdir in ['../../debug/src/lib','../../debug/src/lib/.libs']: + if extdir not in sys.path: + sys.path.append(extdir) +import gsm + +class tune(gr.feval_dd): + def __init__(self, top_block): + gr.feval_dd.__init__(self) + self.top_block = top_block + # self.center_freq = 0 + def eval(self, freq_offet): + # self.center_freq = self.center_freq - freq_offet + self.top_block.set_frequency(freq_offet) + return freq_offet + +class gsm_receiver_first_blood(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + (options, args) = self._przetworz_opcje() + self.tune_callback = tune(self) + self.options = options + self.args = args + self._ustaw_taktowanie() + self.zrodlo = self._ustaw_zrodlo() + self.filtr = self._ustaw_filtr() + self.interpolator = self._ustaw_interpolator() + self.odbiornik = self._ustaw_odbiornik() + self.konwerter = self._ustaw_konwerter() + self.ujscie = self._ustaw_ujscie() + + self.connect(self.zrodlo, self.filtr, self.interpolator, self.odbiornik, self.konwerter, self.ujscie) +# self.connect(self.zrodlo, self.ujscie) + + def _ustaw_ujscie(self): + nazwa_pliku_wy = self.options.outputfile + ujscie = gr.file_sink(gr.sizeof_float, nazwa_pliku_wy) + return ujscie + + def _ustaw_zrodlo(self): + nazwa_pliku = self.options.inputfile + zrodlo = gr.file_source(gr.sizeof_gr_complex, nazwa_pliku, False) + return zrodlo + + def _ustaw_taktowanie(self): + options = self.options + clock_rate = 64e6 + self.clock_rate = clock_rate + self.input_rate = clock_rate / options.decim + self.gsm_symb_rate = 1625000.0 / 6.0 + self.sps = self.input_rate / self.gsm_symb_rate / self.options.osr + + def _ustaw_filtr(self): + filter_cutoff = 145e3 + filter_t_width = 10e3 + offset = 0 +# print "input_rate:", self.input_rate, "sample rate:", self.sps, " filter_cutoff:", filter_cutoff, " filter_t_width:", filter_t_width + filter_taps = gr.firdes.low_pass(1.0, self.input_rate, filter_cutoff, filter_t_width, gr.firdes.WIN_HAMMING) + filtr = gr.freq_xlating_fir_filter_ccf(1, filter_taps, offset, self.input_rate) + return filtr + + def _ustaw_konwerter(self): + v2s = gr.vector_to_stream(gr.sizeof_float, 142) + return v2s + + def _ustaw_interpolator(self): + interpolator = gr.fractional_interpolator_cc(0, self.sps) +# interpolator = blks2.rational_resampler_ccf(13, 6) + return interpolator + + def _ustaw_odbiornik(self): + odbiornik = gsm.receiver_cf(self.tune_callback, self.options.osr) + return odbiornik + + def _przetworz_opcje(self): + parser = OptionParser(option_class=eng_option) + parser.add_option("-d", "--decim", type="int", default=128, + help="Set USRP decimation rate to DECIM [default=%default]") + parser.add_option("-r", "--osr", type="int", default=4, + help="Oversampling ratio [default=%default]") + parser.add_option("-I", "--inputfile", type="string", default="cfile", + help="Input filename") + parser.add_option("-O", "--outputfile", type="string", default="cfile2.out", + help="Output filename") + (options, args) = parser.parse_args () + return (options, args) + + def set_frequency(self, center_freq): + self.filtr.set_center_freq(center_freq) + +def main(): + try: + gsm_receiver_first_blood().run() + except KeyboardInterrupt: + pass + +if __name__ == '__main__': + main() + + -- cgit v1.2.3 From 39dec54e5b4b1cea5f52ad7009907241eea75e02 Mon Sep 17 00:00:00 2001 From: piotr Date: Mon, 1 Jun 2009 11:09:44 +0200 Subject: big and dirty commit - before osr_repair --- Makefile.common | 1 + config/libtool.m4 | 152 ++++++++++++++++++++++++++++++++------------- config/ltoptions.m4 | 2 +- config/ltsugar.m4 | 20 +++--- config/ltversion.m4 | 10 +-- configure.ac | 2 +- src/lib/gsm_receiver_cf.cc | 118 ++++++++++++++++++----------------- 7 files changed, 186 insertions(+), 119 deletions(-) diff --git a/Makefile.common b/Makefile.common index 7bd8dac..e662909 100644 --- a/Makefile.common +++ b/Makefile.common @@ -49,3 +49,4 @@ SWIGGRFLAGS = -I$(GNURADIO_CORE_INCLUDEDIR)/swig -I$(GNURADIO_CORE_INCLUDEDIR) # not. We define it now in configure.ac using AM_PATH_PROG, but now # here have to add a -f to be like GNU make. RM=$(RM_PROG) -f + diff --git a/config/libtool.m4 b/config/libtool.m4 index 4ceb7f1..2ca1c1f 100644 --- a/config/libtool.m4 +++ b/config/libtool.m4 @@ -380,12 +380,12 @@ m4_define([lt_decl_dquote_varnames], # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], -[_$0(m4_quote(m4_default([$1], [[, ]])), - m4_quote(m4_if([$2], [], - m4_quote(lt_decl_tag_varnames), - m4_quote(m4_shift($@)))), - m4_split(m4_normalize(m4_quote(_LT_TAGS))))]) -m4_define([_lt_decl_varnames_tagged], [lt_combine([$1], [$2], [_], $3)]) +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) @@ -945,10 +945,10 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on + darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? + # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; @@ -990,7 +990,11 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES], _LT_TAGVAR(whole_archive_flag_spec, $1)='' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" - if test "$GCC" = "yes"; then + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=echo _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" @@ -1512,7 +1516,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl lt_cv_sys_max_cmd_len=-1; ;; - cygwin* | mingw*) + cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, @@ -1680,10 +1684,6 @@ else # endif #endif -#ifdef __cplusplus -extern "C" void exit (int); -#endif - void fnord() { int i=42;} int main () { @@ -1699,7 +1699,7 @@ int main () else puts (dlerror ()); - exit (status); + return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then @@ -1738,7 +1738,7 @@ else lt_cv_dlopen_self=yes ;; - mingw* | pw32*) + mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; @@ -2035,6 +2035,7 @@ m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], @@ -2199,14 +2200,14 @@ bsdi[[45]]*) # libtool to hard-code these into programs ;; -cygwin* | mingw* | pw32*) +cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$host_os in - yes,cygwin* | yes,mingw* | yes,pw32*) + yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ @@ -2229,7 +2230,7 @@ cygwin* | mingw* | pw32*) soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ;; - mingw*) + mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` @@ -2484,6 +2485,18 @@ linux* | k*bsd*-gnu) dynamic_linker='GNU/Linux ld.so' ;; +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + netbsd*) version_type=sunos need_lib_prefix=no @@ -2655,7 +2668,7 @@ tpf*) version_type=linux need_lib_prefix=no need_version=no - library_name_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes @@ -2679,7 +2692,7 @@ variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi - + if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi @@ -2956,6 +2969,7 @@ _LT_DECL([], [reload_cmds], [2])dnl # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_MAGIC_METHOD], [m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) AC_CACHE_CHECK([how to recognize dependent libraries], lt_cv_deplibs_check_method, [lt_cv_file_magic_cmd='$MAGIC_CMD' @@ -3006,6 +3020,12 @@ mingw* | pw32*) fi ;; +cegcc) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; @@ -3068,7 +3088,7 @@ linux* | k*bsd*-gnu) lt_cv_deplibs_check_method=pass_all ;; -netbsd*) +netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else @@ -3317,7 +3337,7 @@ case $host_os in aix*) symcode='[[BCDT]]' ;; -cygwin* | mingw* | pw32*) +cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) @@ -3563,7 +3583,7 @@ m4_if([$1], [CXX], [ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; - mingw* | cygwin* | os2* | pw32*) + mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style @@ -3590,10 +3610,11 @@ m4_if([$1], [CXX], [ fi ;; hpux*) - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. case $host_cpu in - hppa*64*|ia64*) + hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' @@ -3691,12 +3712,19 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; - icpc* | ecpc* ) - # Intel C++ + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' @@ -3741,7 +3769,7 @@ m4_if([$1], [CXX], [ ;; esac ;; - netbsd*) + netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise @@ -3862,7 +3890,7 @@ m4_if([$1], [CXX], [ # PIC is the default for these OSes. ;; - mingw* | cygwin* | pw32* | os2*) + mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style @@ -3878,10 +3906,11 @@ m4_if([$1], [CXX], [ ;; hpux*) - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. case $host_cpu in - hppa*64*|ia64*) + hppa*64*) # +Z the default ;; *) @@ -3931,7 +3960,7 @@ m4_if([$1], [CXX], [ fi ;; - mingw* | cygwin* | pw32* | os2*) + mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], @@ -3962,11 +3991,25 @@ m4_if([$1], [CXX], [ linux* | k*bsd*-gnu) case $cc_basename in - icc* | ecc* | ifort*) + # old Intel for x86_64 which still supported -KPIC. + ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; pgcc* | pgf77* | pgf90* | pgf95*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) @@ -4148,9 +4191,12 @@ m4_if([$1], [CXX], [ pw32*) _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; - cygwin* | mingw*) + cygwin* | mingw* | cegcc*) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' ;; + linux* | k*bsd*-gnu) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; @@ -4200,7 +4246,7 @@ dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in - cygwin* | mingw* | pw32*) + cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. @@ -4287,7 +4333,7 @@ _LT_EOF fi ;; - cygwin* | mingw* | pw32*) + cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' @@ -4353,6 +4399,9 @@ _LT_EOF tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; xl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; @@ -4394,7 +4443,7 @@ _LT_EOF fi ;; - netbsd*) + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= @@ -4569,6 +4618,7 @@ _LT_EOF if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi + _LT_TAGVAR(link_all_deplibs, $1)=no else # not using gcc if test "$host_cpu" = ia64; then @@ -4584,6 +4634,7 @@ _LT_EOF fi fi + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes @@ -4638,7 +4689,7 @@ _LT_EOF _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; - cygwin* | mingw* | pw32*) + cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is @@ -4742,7 +4793,7 @@ _LT_EOF _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' @@ -4806,7 +4857,7 @@ _LT_EOF _LT_TAGVAR(link_all_deplibs, $1)=yes ;; - netbsd*) + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else @@ -5527,6 +5578,7 @@ if test "$_lt_caught_CXX_error" != yes; then fi fi + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. @@ -5585,7 +5637,7 @@ if test "$_lt_caught_CXX_error" != yes; then esac ;; - cygwin* | mingw* | pw32*) + cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' @@ -6970,6 +7022,18 @@ AC_SUBST([GREP]) ]) +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + + # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates diff --git a/config/ltoptions.m4 b/config/ltoptions.m4 index e970119..34151a3 100644 --- a/config/ltoptions.m4 +++ b/config/ltoptions.m4 @@ -125,7 +125,7 @@ LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in -*-*-cygwin* | *-*-mingw* | *-*-pw32*) +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) diff --git a/config/ltsugar.m4 b/config/ltsugar.m4 index 0d258e0..9000a05 100644 --- a/config/ltsugar.m4 +++ b/config/ltsugar.m4 @@ -1,13 +1,13 @@ # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # -# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc. -# Written by Gary V. Vaughan, 2004 +# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. -# serial 5 ltsugar.m4 +# serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) @@ -63,14 +63,14 @@ m4_define([lt_append], # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], -[m4_if([$2], [], [], - [m4_if([$4], [], [], - [lt_join(m4_quote(m4_default([$1], [[, ]])), - lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_prefix, [$2], - [m4_foreach(_Lt_suffix, lt_car([m4_shiftn(3, $@)]), - [_Lt_prefix[]$3[]_Lt_suffix ])])))))])])dnl -]) +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) diff --git a/config/ltversion.m4 b/config/ltversion.m4 index 45cb155..b8e154f 100644 --- a/config/ltversion.m4 +++ b/config/ltversion.m4 @@ -9,15 +9,15 @@ # Generated from ltversion.in. -# serial 2976 ltversion.m4 +# serial 3012 ltversion.m4 # This file is part of GNU Libtool -m4_define([LT_PACKAGE_VERSION], [2.2.4]) -m4_define([LT_PACKAGE_REVISION], [1.2976]) +m4_define([LT_PACKAGE_VERSION], [2.2.6]) +m4_define([LT_PACKAGE_REVISION], [1.3012]) AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.2.4' -macro_revision='1.2976' +[macro_version='2.2.6' +macro_revision='1.3012' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) diff --git a/configure.ac b/configure.ac index aa33970..709ac12 100644 --- a/configure.ac +++ b/configure.ac @@ -26,6 +26,7 @@ AM_CONFIG_HEADER(config.h) AC_CANONICAL_TARGET([]) AC_CONFIG_AUX_DIR([.]) AM_INIT_AUTOMAKE(gsm-receiver,0.0.1) +AC_CONFIG_MACRO_DIR([config]) GR_X86_64 dnl LF_CONFIGURE_CC @@ -53,7 +54,6 @@ AC_LIBTOOL_WIN32_DLL AC_ENABLE_SHARED dnl do build shared libraries AC_DISABLE_STATIC dnl don't build static libraries m4_ifdef([LT_INIT],[LT_INIT],[AC_PROG_LIBTOOL]) - dnl Locate python, SWIG, etc GR_NO_UNDEFINED GR_SCRIPTING diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 5453253..e4d2696 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -36,7 +36,7 @@ #include #define FCCH_BUFFER_SIZE (FCCH_HITS_NEEDED) -#define SYNC_SEARCH_RANGE 40 +#define SYNC_SEARCH_RANGE 60 //TODO !! - move this methods to some else place @@ -142,60 +142,62 @@ gsm_receiver_cf::general_work(int noutput_items, //in this state receiver is synchronized and it processes bursts according to burst type for given burst number case synchronized: { - gr_complex chan_imp_resp[100];//!! - burst_type b_type = d_channel_conf.get_burst_type(d_burst_nr); - int burst_start; - int offset = 0; - int to_consume = 0; - unsigned char output_binary[BURST_SIZE]; - - switch (b_type) { - case fcch_burst: { - int ii; - int first_sample = (GUARD_BITS+TAIL_BITS)*d_OSR; - int last_sample = first_sample+USEFUL_BITS*d_OSR; - double phase_sum = 0; - for(ii = first_sample; ii < last_sample; ii++){ - phase_sum += compute_phase_diff(in[ii], in[ii-1]) - (M_PI / 2) / d_OSR; - } - std::cout << "freq_offset: " << d_freq_offset << "\n"; - - double freq_offset = compute_freq_offset(phase_sum, USEFUL_BITS-TAIL_BITS); - d_freq_offset -= freq_offset; - set_frequency(d_freq_offset); - std::cout << "freq_offset: " << d_freq_offset << "\n"; - } - break; - case sch_burst: { - int t1, t2, t3, d_ncc, d_bcc; - burst_start = get_sch_chan_imp_resp(in, chan_imp_resp); - detect_burst(in, chan_imp_resp, burst_start, output_binary); - if(decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc) == 0){ -// d_burst_nr.set(t1, t2, t3, 0); - printf("bcc: %d, ncc: %d, t1: %d, t2: %d, t3: %d\n", d_bcc, d_ncc, t1, t2, t3); - offset = burst_start - GUARD_BITS * d_OSR; - to_consume += offset; - } - std::cout << offset << std::endl; - } - break; - case normal_burst: - - break; + gr_complex chan_imp_resp[100];//!! + burst_type b_type = d_channel_conf.get_burst_type(d_burst_nr); + int burst_start; + int offset = 0; + int to_consume = 0; + unsigned char output_binary[BURST_SIZE]; + + switch (b_type) { + case fcch_burst: { + int ii; + int first_sample = (GUARD_BITS+TAIL_BITS) *d_OSR; + int last_sample = first_sample+USEFUL_BITS*d_OSR; + double phase_sum = 0; + for (ii = first_sample; ii < last_sample; ii++) { + double phase_diff = compute_phase_diff(in[ii], in[ii-1]) * d_OSR; +// std::cout << "phase_diff: " << phase_diff << "\n"; + phase_sum += phase_diff; + } + //std::cout << "phase_sum: " << phase_sum << "\n"; - case rach_burst: - break; - case dummy: - break; - case empty: - break; +// double freq_offset = compute_freq_offset(phase_sum, USEFUL_BITS-TAIL_BITS); +// d_freq_offset -= freq_offset; +// set_frequency(d_freq_offset); +// std::cout << "freq_offset: " << d_freq_offset << "\n"; } + break; + case sch_burst: { + int t1, t2, t3, d_ncc, d_bcc; + burst_start = get_sch_chan_imp_resp(in, chan_imp_resp); + detect_burst(in, chan_imp_resp, burst_start, output_binary); + if (decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc) == 0) { +// d_burst_nr.set(t1, t2, t3, 0); + printf("bcc: %d, ncc: %d, t1: %d, t2: %d, t3: %d\n", d_bcc, d_ncc, t1, t2, t3); + offset = burst_start - GUARD_BITS * d_OSR; + to_consume += offset; + } + std::cout << offset << std::endl; + } + break; + case normal_burst: - d_burst_nr++; - to_consume += floor(TS_BITS * d_OSR); - consume_each(to_consume); + break; + + case rach_burst: + break; + case dummy: + break; + case empty: + break; } - break; + + d_burst_nr++; + to_consume += floor(TS_BITS * d_OSR); + consume_each(to_consume); + } + break; } return produced_out; @@ -277,8 +279,8 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) //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())); + 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; @@ -343,7 +345,7 @@ double gsm_receiver_cf::compute_freq_offset(double best_sum, unsigned denominato // d_x2_temp += freq_offset * freq_offset; // d_mean = d_x_temp / d_fcch_count; - DCOUT("freq_offset: " << freq_offset );//" best_sum: " << best_sum + DCOUT("freq_offset: " << freq_offset); //" best_sum: " << best_sum // DCOUT("wariance: " << sqrt((d_x2_temp / d_fcch_count - d_mean * d_mean)) << " fcch_count:" << d_fcch_count << " d_mean: " << d_mean); return freq_offset; @@ -443,7 +445,7 @@ int gsm_receiver_cf::get_sch_chan_imp_resp(const gr_complex *in, gr_complex * ch float max_correlation = 0; float energy = 0; - for (int ii = SYNC_POS * d_OSR; ii < (SYNC_POS + SYNC_SEARCH_RANGE)*d_OSR; ii++) { + 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], &in[ii], N_SYNC_BITS - 10); correlation_buffer.push_back(correlation); power_buffer.push_back(pow(abs(correlation), 2)); @@ -456,7 +458,7 @@ int gsm_receiver_cf::get_sch_chan_imp_resp(const gr_complex *in, gr_complex * ch vector_float::iterator iter_ii = iter; energy = 0; - for (int ii = 0; ii < (d_chan_imp_length)*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; @@ -474,7 +476,7 @@ int gsm_receiver_cf::get_sch_chan_imp_resp(const gr_complex *in, gr_complex * ch d_channel_imp_resp.clear(); max_correlation = 0; - for (int ii = 0; ii < (d_chan_imp_length)*d_OSR; ii++) { + 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; @@ -589,6 +591,6 @@ inline void gsm_receiver_cf::mafi(const gr_complex * input, int input_length, gr output[n] += input[a+ii] * filter[ii]; //!!conj ii++; } - output[n] = output[n] * gr_complex(0, -1);//!!this shouldn't be here + output[n] = output[n] * gr_complex(0, -1); //!!this shouldn't be here } } -- cgit v1.2.3 From 83ca8d75e21d286096c749b7608f847220260b77 Mon Sep 17 00:00:00 2001 From: piotr Date: Mon, 1 Jun 2009 22:14:14 +0200 Subject: program now works for osr from 2,3,4,5,6 and almost for osr==7) --- src/lib/gsm_constants.h | 9 +++-- src/lib/gsm_receiver_cf.cc | 93 ++++++++++++++++++++++++---------------------- src/lib/gsm_receiver_cf.h | 36 ++++++++++++++---- 3 files changed, 83 insertions(+), 55 deletions(-) diff --git a/src/lib/gsm_constants.h b/src/lib/gsm_constants.h index d08df17..1e449b3 100644 --- a/src/lib/gsm_constants.h +++ b/src/lib/gsm_constants.h @@ -6,7 +6,9 @@ //Burst timing #define TAIL_BITS 3 -#define GUARD_BITS 8.25 +#define GUARD_BITS 8 +#define GUARD_FRACTIONAL 0.25 //fractional part of guard period +#define GUARD_PERIOD GUARD_BITS + GUARD_FRACTIONAL #define DATA_BITS 58 //size of 1 data block in normal burst #define N_TRAIN_BITS 26 #define N_SYNC_BITS 64 @@ -14,9 +16,9 @@ #define FCCH_BITS USEFUL_BITS #define BURST_SIZE (USEFUL_BITS+2*TAIL_BITS) -#define TS_BITS (TAIL_BITS+USEFUL_BITS+TAIL_BITS+GUARD_BITS) //a full TS (156) +#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) +#define FRAME_BITS (TS_PER_FRAME * TS_BITS + 2) // 156.25 * 8 #define FCCH_POS TAIL_BITS #define SYNC_POS 39 #define TRAIN_POS 58 @@ -24,6 +26,7 @@ #define FCCH_HITS_NEEDED (USEFUL_BITS - 4) #define FCCH_MAX_MISSES 1 +#define FCCH_MAX_FREQ_OFFSET 100 #define CHAN_IMP_RESP_LENGTH 5 diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index e4d2696..127c674 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -36,7 +36,7 @@ #include #define FCCH_BUFFER_SIZE (FCCH_HITS_NEEDED) -#define SYNC_SEARCH_RANGE 60 +#define SYNC_SEARCH_RANGE 30 //TODO !! - move this methods to some else place @@ -70,7 +70,8 @@ gsm_receiver_cf::gsm_receiver_cf(gr_feval_dd *tuner, int osr) d_counter(0), d_fcch_start_pos(0), d_freq_offset(0), - d_state(first_fcch_search) + d_state(first_fcch_search), + d_burst_nr(osr) // d_fcch_count(0), //!! // d_x_temp(0),//!! // d_x2_temp(0)//!! @@ -128,19 +129,35 @@ gsm_receiver_cf::general_work(int noutput_items, } break; - case sch_search: + case sch_search: { + gr_complex chan_imp_resp[CHAN_IMP_RESP_LENGTH*d_OSR]; + int t1, t2, t3; + int burst_start = 0; + unsigned char output_binary[BURST_SIZE]; + if (find_sch_burst(in, ninput_items[0], out)) { - d_channel_conf.set_multiframe_type(0, multiframe_51); - d_channel_conf.set_burst_types(0, FCCH_FRAMES, sizeof(FCCH_FRAMES) / sizeof(unsigned), fcch_burst); - d_channel_conf.set_burst_types(0, SCH_FRAMES, sizeof(SCH_FRAMES) / sizeof(unsigned), sch_burst); - d_burst_nr++; - d_state = synchronized; + burst_start = get_sch_chan_imp_resp(in, chan_imp_resp); + detect_burst(in, chan_imp_resp, burst_start, output_binary); + if (decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc) == 0) { + DCOUT("sch burst_start: " << burst_start); + d_burst_nr.set(t1, t2, t3, 0); + DCOUT("bcc: " << d_bcc << " ncc: " << d_ncc << " t1: " << t1 << " t2: " << t2 << " t3: " << t3); + d_channel_conf.set_multiframe_type(0, multiframe_51); + d_channel_conf.set_burst_types(0, FCCH_FRAMES, sizeof(FCCH_FRAMES) / sizeof(unsigned), fcch_burst); + d_channel_conf.set_burst_types(0, SCH_FRAMES, sizeof(SCH_FRAMES) / sizeof(unsigned), sch_burst); + d_burst_nr++; + consume_each(burst_start + BURST_SIZE * d_OSR); + d_state = synchronized; + } else { + d_state = next_fcch_search; + } } else { d_state = sch_search; } break; + } - //in this state receiver is synchronized and it processes bursts according to burst type for given burst number + //in this state receiver is synchronized and it processes bursts according to burst type for given burst number case synchronized: { gr_complex chan_imp_resp[100];//!! burst_type b_type = d_channel_conf.get_burst_type(d_burst_nr); @@ -152,20 +169,20 @@ gsm_receiver_cf::general_work(int noutput_items, switch (b_type) { case fcch_burst: { int ii; - int first_sample = (GUARD_BITS+TAIL_BITS) *d_OSR; - int last_sample = first_sample+USEFUL_BITS*d_OSR; + int first_sample = ceil((GUARD_PERIOD + 2*TAIL_BITS) * d_OSR)+1; + int last_sample = first_sample + USEFUL_BITS * d_OSR; double phase_sum = 0; for (ii = first_sample; ii < last_sample; ii++) { - double phase_diff = compute_phase_diff(in[ii], in[ii-1]) * d_OSR; -// std::cout << "phase_diff: " << phase_diff << "\n"; + double phase_diff = compute_phase_diff(in[ii], in[ii-1]) - (M_PI / 2) / d_OSR; phase_sum += phase_diff; } - //std::cout << "phase_sum: " << phase_sum << "\n"; - -// double freq_offset = compute_freq_offset(phase_sum, USEFUL_BITS-TAIL_BITS); -// d_freq_offset -= freq_offset; -// set_frequency(d_freq_offset); -// std::cout << "freq_offset: " << d_freq_offset << "\n"; + double freq_offset = compute_freq_offset(phase_sum, last_sample - first_sample); + if(abs(freq_offset) > FCCH_MAX_FREQ_OFFSET){ + d_freq_offset -= freq_offset; + set_frequency(d_freq_offset); + DCOUT("adjusting frequency, new frequency offset: " << d_freq_offset << "\n"); + } + } break; case sch_burst: { @@ -174,15 +191,15 @@ gsm_receiver_cf::general_work(int noutput_items, detect_burst(in, chan_imp_resp, burst_start, output_binary); if (decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc) == 0) { // d_burst_nr.set(t1, t2, t3, 0); - printf("bcc: %d, ncc: %d, t1: %d, t2: %d, t3: %d\n", d_bcc, d_ncc, t1, t2, t3); - offset = burst_start - GUARD_BITS * d_OSR; + DCOUT("bcc: " << d_bcc << " ncc: " << d_ncc << " t1: " << t1 << " t2: " << t2 << " t3: " << t3); + offset = burst_start - floor((GUARD_PERIOD) * d_OSR); + DCOUT(offset); to_consume += offset; } - std::cout << offset << std::endl; } break; case normal_burst: - + break; case rach_burst: @@ -194,7 +211,8 @@ gsm_receiver_cf::general_work(int noutput_items, } d_burst_nr++; - to_consume += floor(TS_BITS * d_OSR); + + to_consume += TS_BITS * d_OSR + d_burst_nr.get_offset(); consume_each(to_consume); } break; @@ -315,6 +333,7 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) d_fcch_start_pos = d_counter + start_pos; freq_offset = compute_freq_offset(best_sum, FCCH_HITS_NEEDED); d_freq_offset -= freq_offset; + DCOUT("freq_offset: " << d_freq_offset); end = true; result = true; @@ -345,7 +364,7 @@ double gsm_receiver_cf::compute_freq_offset(double best_sum, unsigned denominato // d_x2_temp += freq_offset * freq_offset; // d_mean = d_x_temp / d_fcch_count; - DCOUT("freq_offset: " << freq_offset); //" best_sum: " << best_sum +// DCOUT("freq_offset: " << freq_offset); //" best_sum: " << best_sum // DCOUT("wariance: " << sqrt((d_x2_temp / d_fcch_count - d_mean * d_mean)) << " fcch_count:" << d_fcch_count << " d_mean: " << d_mean); return freq_offset; @@ -368,19 +387,16 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl bool end = false; bool result = false; int sample_nr_near_sch_start = d_fcch_start_pos + (FRAME_BITS - SAFETY_MARGIN) * d_OSR; - gr_complex chan_imp_resp[CHAN_IMP_RESP_LENGTH*d_OSR]; + // vector_complex correlation_buffer; // vector_float power_buffer; // vector_float window_energy_buffer; enum states { - start, reach_sch, find_sch_start, detect_and_decode_sch, search_not_finished, sch_found + start, reach_sch, search_not_finished, sch_found } sch_search_state; sch_search_state = start; - int t1, t2, t3; - int burst_start = 0; - unsigned char output_binary[BURST_SIZE]; while (!end) { switch (sch_search_state) { @@ -389,7 +405,7 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl if (d_counter < sample_nr_near_sch_start) { sch_search_state = reach_sch; } else { - sch_search_state = find_sch_start; + sch_search_state = sch_found; } break; @@ -402,26 +418,13 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl sch_search_state = search_not_finished; break; - case find_sch_start: - burst_start = get_sch_chan_imp_resp(in, chan_imp_resp); - sch_search_state = detect_and_decode_sch; - break; - case detect_and_decode_sch: - detect_burst(in, chan_imp_resp, burst_start, output_binary); - decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc); - d_burst_nr.set(t1, t2, t3, 0); - - printf("bcc: %d, ncc: %d, t1: %d, t2: %d, t3: %d\n", d_bcc, d_ncc, t1, t2, t3); - to_consume += burst_start + BURST_SIZE * d_OSR; - sch_search_state = sch_found; - break; - case search_not_finished: result = false; end = true; break; case sch_found: + to_consume = 0; result = true; end = true; break; diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index 98df34d..cc3fc15 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -32,6 +32,7 @@ //TODO !! - move this classes to some other place #include #include +#include typedef enum {empty, fcch_burst, sch_burst, normal_burst, rach_burst, dummy} burst_type; typedef enum {unknown, multiframe_26, multiframe_51} multiframe_type; @@ -85,20 +86,30 @@ class multiframe_configuration class burst_counter { private: + const int d_OSR; uint32_t d_t1, d_t2, d_t3, d_timeslot_nr; + double d_first_sample_offset; + double d_offset; public: - burst_counter(): + burst_counter(int osr): + d_OSR(osr), d_t1(0), d_t2(0), d_t3(0), - d_timeslot_nr(0) { + d_timeslot_nr(0), + d_first_sample_offset(0), + d_offset(0) { } - burst_counter(uint32_t t1, uint32_t t2, uint32_t t3, uint32_t timeslot_nr): + 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_timeslot_nr(timeslot_nr), + d_offset(0) { + double first_sample_position = (get_frame_nr()*8+timeslot_nr)*TS_BITS; + d_first_sample_offset = first_sample_position - floor(first_sample_position); } burst_counter & operator++(int) { @@ -113,6 +124,10 @@ class burst_counter d_t2 = (d_t2 + 1) % 26; d_t3 = (d_t3 + 1) % 51; } + + d_first_sample_offset += GUARD_FRACTIONAL * d_OSR; + d_offset = floor(d_first_sample_offset); + d_first_sample_offset = d_first_sample_offset - d_offset; return (*this); } @@ -121,6 +136,9 @@ class burst_counter d_t2 = t2; d_t3 = t3; d_timeslot_nr = timeslot_nr; + double first_sample_position = (get_frame_nr()*8+timeslot_nr)*TS_BITS; + d_first_sample_offset = first_sample_position - floor(first_sample_position); + d_offset = 0; } uint32_t get_t1() { @@ -140,7 +158,11 @@ class burst_counter } uint32_t get_frame_nr() { - return (51 * 26 * d_t1) + (51 * (((d_t3 + 26) - d_t2) % 26)) + d_t3; + return (51 * 26 * d_t1) + (51 * (((d_t3 + 26) - d_t2) % 26)) + d_t3; + } + + unsigned get_offset(){ + return (unsigned)d_offset; } }; @@ -180,7 +202,7 @@ 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(); @@ -227,7 +249,7 @@ class gsm_receiver_cf : public gr_block gr_complex d_sch_training_seq[N_SYNC_BITS]; //encoded training sequence of a SCH burst gr_feval_dd *d_tuner; - int d_counter; + unsigned d_counter; //variables used to store result of the find_fcch_burst fuction int d_fcch_start_pos; -- cgit v1.2.3 From 6497de667a5d1f6f1770066ea64bc624407957ff Mon Sep 17 00:00:00 2001 From: piotr Date: Thu, 4 Jun 2009 13:12:03 +0200 Subject: normal bursts detection now works, but the code is a little dirty --- src/lib/decoder/sch.c | 6 +- src/lib/gsm_constants.h | 14 ++-- src/lib/gsm_receiver_cf.cc | 167 +++++++++++++++++++++++++++++++++++++++++---- src/lib/gsm_receiver_cf.h | 10 ++- 4 files changed, 171 insertions(+), 26 deletions(-) diff --git a/src/lib/decoder/sch.c b/src/lib/decoder/sch.c index 9f570c9..e16d14b 100644 --- a/src/lib/decoder/sch.c +++ b/src/lib/decoder/sch.c @@ -3,7 +3,7 @@ #include #include #include -#include "burst_types.h" +#include /* * Synchronization channel. @@ -251,8 +251,8 @@ int decode_sch(const unsigned char *buf, int * t1_o, int * t2_o, int * t3_o, int // extract encoded data from synchronization burst /* buf, 39 bit */ /* buf + 39 + 64 = 103, 39 */ - memcpy(data, buf, SB_EDATA_LEN_1); - memcpy(data + SB_EDATA_LEN_1, buf + SB_EDATA_LEN_1 + N_SYNC_BITS, SB_EDATA_LEN_2); + 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)) { diff --git a/src/lib/gsm_constants.h b/src/lib/gsm_constants.h index 1e449b3..ded8cb4 100644 --- a/src/lib/gsm_constants.h +++ b/src/lib/gsm_constants.h @@ -16,6 +16,7 @@ #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 @@ -30,7 +31,7 @@ #define CHAN_IMP_RESP_LENGTH 5 -static const int SYNC_BITS[] = { +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, @@ -39,7 +40,7 @@ static const int SYNC_BITS[] = { 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, 12}; //remove 12 // Sync : .+...++.+..+++.++++++.++++++....++.+..+.+.+++.+.+...+..++++..+.. // Diff Encoded Sync: .++..+.+++.+..++.....++.....+...+.+++.+++++..+++++..++.+...+.++. @@ -52,10 +53,11 @@ const unsigned SCH_FRAMES[] = {1,11,21,31,41}; #define TSC5 5 #define TSC6 6 #define TSC7 7 -#define TS_FCCH 8 -#define TS_DUMMY 9 +#define TS_DUMMY 8 + +#define TRAIN_SEQ_NUM 9 -static const unsigned char train_seq[10][N_TRAIN_BITS] = { +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}, @@ -64,10 +66,10 @@ static const unsigned char train_seq[10][N_TRAIN_BITS] = { {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}, - {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}, //#9 FCCH ;-) {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, diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 127c674..ce59bee 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -37,6 +37,7 @@ #define FCCH_BUFFER_SIZE (FCCH_HITS_NEEDED) #define SYNC_SEARCH_RANGE 30 +#define TRAIN_SEARCH_RANGE 40 //TODO !! - move this methods to some else place @@ -76,7 +77,12 @@ gsm_receiver_cf::gsm_receiver_cf(gr_feval_dd *tuner, int osr) // d_x_temp(0),//!! // d_x2_temp(0)//!! { - gmsk_mapper(SYNC_BITS, d_sch_training_seq, N_SYNC_BITS); + 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++) { + gmsk_mapper(train_seq[i], N_TRAIN_BITS, d_norm_training_seq[i], gr_complex(1.0,0.0)); + } } /* @@ -142,10 +148,12 @@ gsm_receiver_cf::general_work(int noutput_items, DCOUT("sch burst_start: " << burst_start); d_burst_nr.set(t1, t2, t3, 0); DCOUT("bcc: " << d_bcc << " ncc: " << d_ncc << " t1: " << t1 << " t2: " << t2 << " t3: " << t3); - d_channel_conf.set_multiframe_type(0, multiframe_51); - d_channel_conf.set_burst_types(0, FCCH_FRAMES, sizeof(FCCH_FRAMES) / sizeof(unsigned), fcch_burst); - d_channel_conf.set_burst_types(0, SCH_FRAMES, sizeof(SCH_FRAMES) / sizeof(unsigned), sch_burst); + d_channel_conf.set_multiframe_type(TSC0, multiframe_51); + d_channel_conf.set_burst_types(TSC0, FCCH_FRAMES, sizeof(FCCH_FRAMES) / sizeof(unsigned), fcch_burst); + d_channel_conf.set_burst_types(TSC0, SCH_FRAMES, sizeof(SCH_FRAMES) / sizeof(unsigned), sch_burst); + d_channel_conf.set_burst_types(TSC0, BCCH_FRAMES, sizeof(BCCH_FRAMES) / sizeof(unsigned), normal_burst); d_burst_nr++; + consume_each(burst_start + BURST_SIZE * d_OSR); d_state = synchronized; } else { @@ -159,7 +167,7 @@ gsm_receiver_cf::general_work(int noutput_items, //in this state receiver is synchronized and it processes bursts according to burst type for given burst number case synchronized: { - gr_complex chan_imp_resp[100];//!! + gr_complex chan_imp_resp[d_chan_imp_length*d_OSR]; burst_type b_type = d_channel_conf.get_burst_type(d_burst_nr); int burst_start; int offset = 0; @@ -169,7 +177,7 @@ gsm_receiver_cf::general_work(int noutput_items, switch (b_type) { case fcch_burst: { int ii; - int first_sample = ceil((GUARD_PERIOD + 2*TAIL_BITS) * d_OSR)+1; + int first_sample = ceil((GUARD_PERIOD + 2 * TAIL_BITS) * d_OSR) + 1; int last_sample = first_sample + USEFUL_BITS * d_OSR; double phase_sum = 0; for (ii = first_sample; ii < last_sample; ii++) { @@ -177,18 +185,18 @@ gsm_receiver_cf::general_work(int noutput_items, phase_sum += phase_diff; } double freq_offset = compute_freq_offset(phase_sum, last_sample - first_sample); - if(abs(freq_offset) > FCCH_MAX_FREQ_OFFSET){ + if (abs(freq_offset) > FCCH_MAX_FREQ_OFFSET) { d_freq_offset -= freq_offset; set_frequency(d_freq_offset); DCOUT("adjusting frequency, new frequency offset: " << d_freq_offset << "\n"); } - } break; + case sch_burst: { int t1, t2, t3, d_ncc, d_bcc; burst_start = get_sch_chan_imp_resp(in, chan_imp_resp); - detect_burst(in, chan_imp_resp, burst_start, output_binary); + detect_burst(in, &d_channel_imp_resp[0], burst_start, output_binary); if (decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc) == 0) { // d_burst_nr.set(t1, t2, t3, 0); DCOUT("bcc: " << d_bcc << " ncc: " << d_ncc << " t1: " << t1 << " t2: " << t2 << " t3: " << t3); @@ -198,8 +206,25 @@ gsm_receiver_cf::general_work(int noutput_items, } } break; + case normal_burst: - +// std::cout << "# name: norm_complex\n" ; +// std::cout << "# type: complex matrix\n" ; +// std::cout << "# rows: 1\n" ; +// std::cout << "# columns: " << floor(d_OSR*(TS_BITS+GUARD_PERIOD)) << "\n"; + burst_start = get_norm_chan_imp_resp(in, chan_imp_resp, TRAIN_SEARCH_RANGE); +// std::cout << burst_start << "\n" ; + detect_burst(in, &d_channel_imp_resp[0], burst_start, output_binary); +// printf("burst = [ "); +// + for (int i = 0; i < BURST_SIZE ; i++) { + printf(" %d", output_binary[i]); + } + printf("];\n"); +// +// for(int i=0; i= input_length*d_OSR) + break; + output[n] += input[a+ii] * filter[ii]; + ii++; + } + } +} + +int gsm_receiver_cf::get_norm_chan_imp_resp(const gr_complex *in, gr_complex * chan_imp_resp, unsigned search_range) +{ + 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; + float max_correlation = 0; + float energy = 0; + int search_start_pos = floor((TRAIN_POS + GUARD_PERIOD) * d_OSR); + int search_stop_pos = search_start_pos + search_range * d_OSR; +// std::cout << "# name: correlation\n" ; +// std::cout << "# type: complex matrix\n" ; +// std::cout << "# rows: 1\n" ; +// std::cout << "# columns: " << (search_stop_pos - search_start_pos) << "\n"; + + + for (int ii = search_start_pos; ii < search_stop_pos; ii++) { +// for (int ii = SYNC_POS * d_OSR; ii < (SYNC_POS + SYNC_SEARCH_RANGE) *d_OSR; ii++) { +// for (int ii = 1; ii < (150) *d_OSR; ii++) { + gr_complex correlation = correlate_sequence(&d_norm_training_seq[d_bcc][5], &in[ii], N_TRAIN_BITS - 10); + +// std::cout << correlation << "\n" ; + 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++; +// std::cout << energy << "\n"; + 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(); + strongest_window_nr = 36; + + 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; + } + + std::cout << "center: " << strongest_window_nr + chan_imp_resp_center << " stronegest window nr: " << strongest_window_nr << "\n"; + + burst_start = search_start_pos + strongest_window_nr + chan_imp_resp_center - 66 * d_OSR - 2 * d_OSR + 2; + return burst_start; +} + +void gsm_receiver_cf::detect_norm_burst(const gr_complex * in, 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_norm(&in[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); + } +} + +inline void gsm_receiver_cf::mafi_norm(const gr_complex * input, int input_length, gr_complex * filter, int filter_length, gr_complex * output) +{ + int ii = 0, n, a; + for (n = 0; n < input_length; n++) { a = n * d_OSR; output[n] = 0; @@ -594,6 +734,5 @@ inline void gsm_receiver_cf::mafi(const gr_complex * input, int input_length, gr output[n] += input[a+ii] * filter[ii]; //!!conj ii++; } - output[n] = output[n] * gr_complex(0, -1); //!!this shouldn't be here } } diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index cc3fc15..796bb5b 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -247,7 +247,8 @@ class gsm_receiver_cf : public gr_block const int d_chan_imp_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]; + gr_feval_dd *d_tuner; unsigned d_counter; @@ -284,11 +285,14 @@ class gsm_receiver_cf : public gr_block bool find_sch_burst(const gr_complex *in, const int nitems , float *out); int get_sch_chan_imp_resp(const gr_complex *in, gr_complex * chan_imp_resp); void detect_burst(const gr_complex * in, gr_complex * chan_imp_resp, int burst_start, unsigned char * output_binary); - void gmsk_mapper(const int * input, gr_complex * gmsk_output, int ninput); + void gmsk_mapper(const unsigned char * input, int ninput, gr_complex * gmsk_output, gr_complex start_point); gr_complex correlate_sequence(const gr_complex * sequence, const gr_complex * input_signal, int ninput); inline void autocorrelation(const gr_complex * input, gr_complex * out, int length); inline void mafi(const gr_complex * input, int input_length, gr_complex * filter, int filter_length, gr_complex * output); - + int get_norm_chan_imp_resp(const gr_complex *in, gr_complex * chan_imp_resp, unsigned search_range); + void detect_norm_burst(const gr_complex * in, gr_complex * chan_imp_resp, int burst_start, unsigned char * output_binary); + inline void mafi_norm(const gr_complex * input, int input_length, gr_complex * filter, int filter_length, gr_complex * output); + public: ~gsm_receiver_cf(); void forecast(int noutput_items, gr_vector_int &ninput_items_required); -- cgit v1.2.3 From 99e4a46c9acfb833ae2c9c198046933f9117dca8 Mon Sep 17 00:00:00 2001 From: piotr Date: Thu, 4 Jun 2009 13:18:56 +0200 Subject: removed void detect_norm_burst(const gr_complex * in, gr_complex * chan_imp_resp, int burst_start, unsigned char * output_binary); --- src/lib/gsm_receiver_cf.cc | 41 ----------------------------------------- src/lib/gsm_receiver_cf.h | 2 -- 2 files changed, 43 deletions(-) diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index ce59bee..8e3bad0 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -695,44 +695,3 @@ int gsm_receiver_cf::get_norm_chan_imp_resp(const gr_complex *in, gr_complex * c burst_start = search_start_pos + strongest_window_nr + chan_imp_resp_center - 66 * d_OSR - 2 * d_OSR + 2; return burst_start; } - -void gsm_receiver_cf::detect_norm_burst(const gr_complex * in, 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_norm(&in[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); - } -} - -inline void gsm_receiver_cf::mafi_norm(const gr_complex * input, int input_length, gr_complex * filter, int filter_length, gr_complex * output) -{ - int ii = 0, n, a; - - for (n = 0; n < input_length; n++) { - a = n * d_OSR; - output[n] = 0; - ii = 0; - - while (ii < filter_length) { - if ((a + ii) >= input_length*d_OSR) - break; - output[n] += input[a+ii] * filter[ii]; //!!conj - ii++; - } - } -} diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index 796bb5b..cfdcd5b 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -290,8 +290,6 @@ class gsm_receiver_cf : public gr_block inline void autocorrelation(const gr_complex * input, gr_complex * out, int length); inline void mafi(const gr_complex * input, int input_length, gr_complex * filter, int filter_length, gr_complex * output); int get_norm_chan_imp_resp(const gr_complex *in, gr_complex * chan_imp_resp, unsigned search_range); - void detect_norm_burst(const gr_complex * in, gr_complex * chan_imp_resp, int burst_start, unsigned char * output_binary); - inline void mafi_norm(const gr_complex * input, int input_length, gr_complex * filter, int filter_length, gr_complex * output); public: ~gsm_receiver_cf(); -- cgit v1.2.3 From 5e8b4c680934a16b6e554c53ba2bd3ae4f621d49 Mon Sep 17 00:00:00 2001 From: piotr Date: Thu, 4 Jun 2009 13:19:27 +0200 Subject: Revert "removed void detect_norm_burst(const gr_complex * in, gr_complex * chan_imp_resp, int burst_start, unsigned char * output_binary);" This reverts commit 99e4a46c9acfb833ae2c9c198046933f9117dca8. --- src/lib/gsm_receiver_cf.cc | 41 +++++++++++++++++++++++++++++++++++++++++ src/lib/gsm_receiver_cf.h | 2 ++ 2 files changed, 43 insertions(+) diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 8e3bad0..ce59bee 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -695,3 +695,44 @@ int gsm_receiver_cf::get_norm_chan_imp_resp(const gr_complex *in, gr_complex * c burst_start = search_start_pos + strongest_window_nr + chan_imp_resp_center - 66 * d_OSR - 2 * d_OSR + 2; return burst_start; } + +void gsm_receiver_cf::detect_norm_burst(const gr_complex * in, 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_norm(&in[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); + } +} + +inline void gsm_receiver_cf::mafi_norm(const gr_complex * input, int input_length, gr_complex * filter, int filter_length, gr_complex * output) +{ + int ii = 0, n, a; + + for (n = 0; n < input_length; n++) { + a = n * d_OSR; + output[n] = 0; + ii = 0; + + while (ii < filter_length) { + if ((a + ii) >= input_length*d_OSR) + break; + output[n] += input[a+ii] * filter[ii]; //!!conj + ii++; + } + } +} diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index cfdcd5b..796bb5b 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -290,6 +290,8 @@ class gsm_receiver_cf : public gr_block inline void autocorrelation(const gr_complex * input, gr_complex * out, int length); inline void mafi(const gr_complex * input, int input_length, gr_complex * filter, int filter_length, gr_complex * output); int get_norm_chan_imp_resp(const gr_complex *in, gr_complex * chan_imp_resp, unsigned search_range); + void detect_norm_burst(const gr_complex * in, gr_complex * chan_imp_resp, int burst_start, unsigned char * output_binary); + inline void mafi_norm(const gr_complex * input, int input_length, gr_complex * filter, int filter_length, gr_complex * output); public: ~gsm_receiver_cf(); -- cgit v1.2.3 From b80f1794b87f35839cda7f5070223ba5c1c44cea Mon Sep 17 00:00:00 2001 From: piotr Date: Thu, 4 Jun 2009 13:21:04 +0200 Subject: removed functions detect_norm_burst and mafi_norm and replaced them with more generic ones --- src/lib/gsm_receiver_cf.cc | 41 ----------------------------------------- 1 file changed, 41 deletions(-) diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index ce59bee..8e3bad0 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -695,44 +695,3 @@ int gsm_receiver_cf::get_norm_chan_imp_resp(const gr_complex *in, gr_complex * c burst_start = search_start_pos + strongest_window_nr + chan_imp_resp_center - 66 * d_OSR - 2 * d_OSR + 2; return burst_start; } - -void gsm_receiver_cf::detect_norm_burst(const gr_complex * in, 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_norm(&in[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); - } -} - -inline void gsm_receiver_cf::mafi_norm(const gr_complex * input, int input_length, gr_complex * filter, int filter_length, gr_complex * output) -{ - int ii = 0, n, a; - - for (n = 0; n < input_length; n++) { - a = n * d_OSR; - output[n] = 0; - ii = 0; - - while (ii < filter_length) { - if ((a + ii) >= input_length*d_OSR) - break; - output[n] += input[a+ii] * filter[ii]; //!!conj - ii++; - } - } -} -- cgit v1.2.3 From c4c209ff18a0809cd7517f13c69e610d41891902 Mon Sep 17 00:00:00 2001 From: piotr Date: Thu, 4 Jun 2009 13:26:55 +0200 Subject: removed compute_energy function --- src/lib/gsm_receiver_cf.cc | 12 ------------ src/lib/gsm_receiver_cf.h | 9 +++------ 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 8e3bad0..b58b108 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -577,18 +577,6 @@ gr_complex gsm_receiver_cf::correlate_sequence(const gr_complex * sequence, cons return result; } -// gr_complex gsm_receiver_cf::compute_energy(const gr_complex * input_signal, int length) -// { -// float result = 0; -// int sample_number = 0; -// -// for (int ii = 0; ii < length; ii++) { -// result += input_signal[(ii * d_OSR)]; -// } -// -// return result; -// } - //computes autocorrelation for positive values //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 length) diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index 796bb5b..978576b 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -269,9 +269,8 @@ class gsm_receiver_cf : public gr_block int d_bcc; enum states { - //synchronization search part - first_fcch_search, next_fcch_search, sch_search, synchronized - // + first_fcch_search, next_fcch_search, sch_search, //synchronization search part + synchronized //receiver is synchronized in this state } d_state; friend gsm_receiver_cf_sptr gsm_make_receiver_cf(gr_feval_dd *tuner, int osr); @@ -290,9 +289,7 @@ class gsm_receiver_cf : public gr_block inline void autocorrelation(const gr_complex * input, gr_complex * out, int length); inline void mafi(const gr_complex * input, int input_length, gr_complex * filter, int filter_length, gr_complex * output); int get_norm_chan_imp_resp(const gr_complex *in, gr_complex * chan_imp_resp, unsigned search_range); - void detect_norm_burst(const gr_complex * in, gr_complex * chan_imp_resp, int burst_start, unsigned char * output_binary); - inline void mafi_norm(const gr_complex * input, int input_length, gr_complex * filter, int filter_length, gr_complex * output); - + public: ~gsm_receiver_cf(); void forecast(int noutput_items, gr_vector_int &ninput_items_required); -- cgit v1.2.3 From ba23d7efb87cd8ba624a1f9c577cf2bbea1b2fed Mon Sep 17 00:00:00 2001 From: piotr Date: Thu, 4 Jun 2009 14:09:12 +0200 Subject: removed unneeded viariables from compute_freq_offset --- src/lib/gsm_receiver_cf.cc | 43 +++++-------------------------------------- 1 file changed, 5 insertions(+), 38 deletions(-) diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index b58b108..c47e111 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -73,9 +73,6 @@ gsm_receiver_cf::gsm_receiver_cf(gr_feval_dd *tuner, int osr) d_freq_offset(0), d_state(first_fcch_search), d_burst_nr(osr) -// d_fcch_count(0), //!! -// d_x_temp(0),//!! -// d_x2_temp(0)//!! { int i; gmsk_mapper(SYNC_BITS, N_SYNC_BITS, d_sch_training_seq, gr_complex(0.0,-1.0)); @@ -208,23 +205,15 @@ gsm_receiver_cf::general_work(int noutput_items, break; case normal_burst: -// std::cout << "# name: norm_complex\n" ; -// std::cout << "# type: complex matrix\n" ; -// std::cout << "# rows: 1\n" ; -// std::cout << "# columns: " << floor(d_OSR*(TS_BITS+GUARD_PERIOD)) << "\n"; burst_start = get_norm_chan_imp_resp(in, chan_imp_resp, TRAIN_SEARCH_RANGE); -// std::cout << burst_start << "\n" ; detect_burst(in, &d_channel_imp_resp[0], burst_start, output_binary); // printf("burst = [ "); // - for (int i = 0; i < BURST_SIZE ; i++) { - printf(" %d", output_binary[i]); - } - printf("];\n"); -// -// for(int i=0; i Date: Fri, 5 Jun 2009 21:01:11 +0200 Subject: just next cleanup, move along --- src/lib/gsm_constants.h | 48 +++++++++++++++++++++++++++++++++++------ src/lib/gsm_receiver_cf.cc | 53 +++++++++++++++++++++++++++++----------------- src/lib/gsm_receiver_cf.h | 8 +++---- 3 files changed, 79 insertions(+), 30 deletions(-) diff --git a/src/lib/gsm_constants.h b/src/lib/gsm_constants.h index ded8cb4..520ff4f 100644 --- a/src/lib/gsm_constants.h +++ b/src/lib/gsm_constants.h @@ -22,10 +22,12 @@ #define FRAME_BITS (TS_PER_FRAME * TS_BITS + 2) // 156.25 * 8 #define FCCH_POS TAIL_BITS #define SYNC_POS 39 -#define TRAIN_POS 58 -#define SAFETY_MARGIN 6 +#define TRAIN_POS TAIL_BITS + DATA_BITS + 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_HITS_NEEDED (USEFUL_BITS - 4) #define FCCH_MAX_MISSES 1 #define FCCH_MAX_FREQ_OFFSET 100 @@ -38,9 +40,9 @@ static const unsigned char SYNC_BITS[] = { 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, 12}; //remove 12 +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}; // Sync : .+...++.+..+++.++++++.++++++....++.+..+.+.+++.+.+...+..++++..+.. // Diff Encoded Sync: .++..+.+++.+..++.....++.....+...+.+++.+++++..+++++..++.+...+.++. @@ -91,6 +93,40 @@ static const unsigned char dummy_burst[] = { 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 +}; + //Diff encoded train_seq //TSC0: +.++.+++..+...++..++.+++.. //TSC1: +.+++.++..++...+..++.+++.. diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index c47e111..c1280f4 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -75,10 +75,10 @@ gsm_receiver_cf::gsm_receiver_cf(gr_feval_dd *tuner, int osr) d_burst_nr(osr) { int i; - gmsk_mapper(SYNC_BITS, N_SYNC_BITS, d_sch_training_seq, gr_complex(0.0,-1.0)); + 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++) { - gmsk_mapper(train_seq[i], N_TRAIN_BITS, d_norm_training_seq[i], gr_complex(1.0,0.0)); + gmsk_mapper(train_seq[i], N_TRAIN_BITS, d_norm_training_seq[i], gr_complex(1.0, 0.0)); } } @@ -91,7 +91,7 @@ gsm_receiver_cf::~gsm_receiver_cf() void gsm_receiver_cf::forecast(int noutput_items, gr_vector_int &ninput_items_required) { - ninput_items_required[0] = noutput_items * (TS_BITS + 2 * SAFETY_MARGIN) * d_OSR; + ninput_items_required[0] = noutput_items * floor((TS_BITS + 2 * GUARD_PERIOD) * d_OSR); } int @@ -207,13 +207,11 @@ gsm_receiver_cf::general_work(int noutput_items, case normal_burst: burst_start = get_norm_chan_imp_resp(in, chan_imp_resp, TRAIN_SEARCH_RANGE); detect_burst(in, &d_channel_imp_resp[0], burst_start, output_binary); -// printf("burst = [ "); -// -// for (int i = 0; i < BURST_SIZE ; i++) { -// printf(" %d", output_binary[i]); -// } -// printf("];\n"); - + printf("burst = [ "); + for (int i = 0; i < BURST_SIZE ; i++) { + printf(" %d", output_binary[i]); + } + printf("];\n"); break; case rach_burst: @@ -596,12 +594,13 @@ int gsm_receiver_cf::get_norm_chan_imp_resp(const gr_complex *in, gr_complex * c int chan_imp_resp_center; float max_correlation = 0; float energy = 0; - - int search_start_pos = floor((TRAIN_POS + GUARD_PERIOD) * d_OSR); - int search_stop_pos = search_start_pos + search_range * d_OSR; + + int search_center = (int)((TRAIN_POS + GUARD_PERIOD) * d_OSR); + int search_start_pos = search_center+1; + 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[d_bcc][5], &in[ii], N_TRAIN_BITS - 10); + gr_complex correlation = correlate_sequence(&d_norm_training_seq[d_bcc][TRAIN_BEGINNING], &in[ii], N_TRAIN_BITS - 10); correlation_buffer.push_back(correlation); power_buffer.push_back(pow(abs(correlation), 2)); @@ -615,24 +614,27 @@ int gsm_receiver_cf::get_norm_chan_imp_resp(const gr_complex *in, gr_complex * c energy = 0; for (int ii = 0; ii < (d_chan_imp_length)*d_OSR; ii++, iter_ii++) { +// for (int ii = 0; ii < (d_chan_imp_length); ii++) { if (iter_ii == power_buffer.end()) { loop_end = true; break; } energy += (*iter_ii); +// iter_ii = iter_ii + d_OSR; } if (loop_end) { break; } iter++; +// std::cout << energy << "\n"; + window_energy_buffer.push_back(energy); } - - +// std::cout << window_energy_buffer.size() << "\n"; strongest_window_nr = max_element(window_energy_buffer.begin(), window_energy_buffer.end()) - window_energy_buffer.begin(); d_channel_imp_resp.clear(); - strongest_window_nr = 36; +// strongest_window_nr = 3; max_correlation = 0; for (int ii = 0; ii < (d_chan_imp_length)*d_OSR; ii++) { @@ -644,9 +646,20 @@ int gsm_receiver_cf::get_norm_chan_imp_resp(const gr_complex *in, gr_complex * c 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 - 66 * d_OSR - 2 * d_OSR + 2; +// COMPENSATING FOR THE 2 Tb DELAY INTRODUCED IN THE GMSK MODULATOR. +// EACH BIT IS STRECHED OVER A PERIOD OF 3 Tb WITH ITS MAXIMUM VALUE +// IN THE LAST BIT PERIOD. HENCE, burst_start IS 2 * OSR +//compute burst start + std::cout << " burst_start: " << (float)burst_start/(float)d_OSR<< " center: " << ((float)(search_start_pos + strongest_window_nr + chan_imp_resp_center))/d_OSR << " stronegest window nr: " << strongest_window_nr << "\n"; - std::cout << "center: " << strongest_window_nr + chan_imp_resp_center << " stronegest window nr: " << strongest_window_nr << "\n"; - - burst_start = search_start_pos + strongest_window_nr + chan_imp_resp_center - 66 * d_OSR - 2 * d_OSR + 2; return burst_start; + } diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index 978576b..e07eb60 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -164,6 +164,10 @@ class burst_counter unsigned get_offset(){ return (unsigned)d_offset; } + //!! + float get_first_sample_offset(){ + return d_first_sample_offset; + } }; class channel_configuration @@ -255,10 +259,6 @@ class gsm_receiver_cf : public gr_block //variables used to store result of the find_fcch_burst fuction int d_fcch_start_pos; float d_freq_offset; -// double d_best_sum; - -// int d_fcch_count; //!!! -// double d_x_temp, d_x2_temp, d_mean;//!! burst_counter d_burst_nr; channel_configuration d_channel_conf; -- cgit v1.2.3 From 4ebdbec8142d7daf144c5f8af1f299129eda581d Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Sat, 6 Jun 2009 14:35:29 +0200 Subject: added separate header for viterbi detector --- src/lib/viterbi_detector.cc | 552 ++++++++++++++++++++++++++++++++++++++++++++ src/lib/viterbi_detector.h | 498 +-------------------------------------- 2 files changed, 553 insertions(+), 497 deletions(-) create mode 100644 src/lib/viterbi_detector.cc diff --git a/src/lib/viterbi_detector.cc b/src/lib/viterbi_detector.cc new file mode 100644 index 0000000..2a2fede --- /dev/null +++ b/src/lib/viterbi_detector.cc @@ -0,0 +1,552 @@ +/*************************************************************************** + * Copyright (C) 2008 by Piotr Krysik * + * pkrysik@stud.elka.pw.edu.pl * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 +#include +#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 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 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 index 2a2fede..9ecb2a0 100644 --- a/src/lib/viterbi_detector.h +++ b/src/lib/viterbi_detector.h @@ -53,500 +53,4 @@ ** TEST(S): Tested with real world normal burst. */ -#include -#include -#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 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 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; - } -} +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); -- cgit v1.2.3 From 52afa1c28c086eb1051fdc801a69384396f5076a Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Sat, 6 Jun 2009 23:07:09 +0200 Subject: some random changes to the bulidsystem - resolve libtool imcompatibilities between different versions --- config/libtool.m4 | 7373 ---------------------------------------- config/ltoptions.m4 | 368 -- config/ltsugar.m4 | 123 - config/ltversion.m4 | 23 - config/lt~obsolete.m4 | 92 - src/lib/gsm_receiver_config.cc | 11 + src/lib/gsm_receiver_config.h | 11 + 7 files changed, 22 insertions(+), 7979 deletions(-) delete mode 100644 config/libtool.m4 delete mode 100644 config/ltoptions.m4 delete mode 100644 config/ltsugar.m4 delete mode 100644 config/ltversion.m4 delete mode 100644 config/lt~obsolete.m4 create mode 100644 src/lib/gsm_receiver_config.cc create mode 100644 src/lib/gsm_receiver_config.h diff --git a/config/libtool.m4 b/config/libtool.m4 deleted file mode 100644 index 2ca1c1f..0000000 --- a/config/libtool.m4 +++ /dev/null @@ -1,7373 +0,0 @@ -# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008 Free Software Foundation, Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -m4_define([_LT_COPYING], [dnl -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008 Free Software Foundation, Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is part of GNU Libtool. -# -# GNU Libtool is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool 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 Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, or -# obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -]) - -# serial 56 LT_INIT - - -# LT_PREREQ(VERSION) -# ------------------ -# Complain and exit if this libtool version is less that VERSION. -m4_defun([LT_PREREQ], -[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, - [m4_default([$3], - [m4_fatal([Libtool version $1 or higher is required], - 63)])], - [$2])]) - - -# _LT_CHECK_BUILDDIR -# ------------------ -# Complain if the absolute build directory name contains unusual characters -m4_defun([_LT_CHECK_BUILDDIR], -[case `pwd` in - *\ * | *\ *) - AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; -esac -]) - - -# LT_INIT([OPTIONS]) -# ------------------ -AC_DEFUN([LT_INIT], -[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT -AC_BEFORE([$0], [LT_LANG])dnl -AC_BEFORE([$0], [LT_OUTPUT])dnl -AC_BEFORE([$0], [LTDL_INIT])dnl -m4_require([_LT_CHECK_BUILDDIR])dnl - -dnl Autoconf doesn't catch unexpanded LT_ macros by default: -m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl -m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl -dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 -dnl unless we require an AC_DEFUNed macro: -AC_REQUIRE([LTOPTIONS_VERSION])dnl -AC_REQUIRE([LTSUGAR_VERSION])dnl -AC_REQUIRE([LTVERSION_VERSION])dnl -AC_REQUIRE([LTOBSOLETE_VERSION])dnl -m4_require([_LT_PROG_LTMAIN])dnl - -dnl Parse OPTIONS -_LT_SET_OPTIONS([$0], [$1]) - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ltmain" - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' -AC_SUBST(LIBTOOL)dnl - -_LT_SETUP - -# Only expand once: -m4_define([LT_INIT]) -])# LT_INIT - -# Old names: -AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) -AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_PROG_LIBTOOL], []) -dnl AC_DEFUN([AM_PROG_LIBTOOL], []) - - -# _LT_CC_BASENAME(CC) -# ------------------- -# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. -m4_defun([_LT_CC_BASENAME], -[for cc_temp in $1""; do - case $cc_temp in - compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; - distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` -]) - - -# _LT_FILEUTILS_DEFAULTS -# ---------------------- -# It is okay to use these file commands and assume they have been set -# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. -m4_defun([_LT_FILEUTILS_DEFAULTS], -[: ${CP="cp -f"} -: ${MV="mv -f"} -: ${RM="rm -f"} -])# _LT_FILEUTILS_DEFAULTS - - -# _LT_SETUP -# --------- -m4_defun([_LT_SETUP], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -_LT_DECL([], [host_alias], [0], [The host system])dnl -_LT_DECL([], [host], [0])dnl -_LT_DECL([], [host_os], [0])dnl -dnl -_LT_DECL([], [build_alias], [0], [The build system])dnl -_LT_DECL([], [build], [0])dnl -_LT_DECL([], [build_os], [0])dnl -dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([LT_PATH_LD])dnl -AC_REQUIRE([LT_PATH_NM])dnl -dnl -AC_REQUIRE([AC_PROG_LN_S])dnl -test -z "$LN_S" && LN_S="ln -s" -_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl -dnl -AC_REQUIRE([LT_CMD_MAX_LEN])dnl -_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl -_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl -dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_CHECK_SHELL_FEATURES])dnl -m4_require([_LT_CMD_RELOAD])dnl -m4_require([_LT_CHECK_MAGIC_METHOD])dnl -m4_require([_LT_CMD_OLD_ARCHIVE])dnl -m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl - -_LT_CONFIG_LIBTOOL_INIT([ -# See if we are running on zsh, and set the options which allow our -# commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi -]) -if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi - -_LT_CHECK_OBJDIR - -m4_require([_LT_TAG_COMPILER])dnl -_LT_PROG_ECHO_BACKSLASH - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\([["`\\]]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Sed substitution to delay expansion of an escaped single quote. -delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' - -# Sed substitution to avoid accidental globbing in evaled expressions -no_glob_subst='s/\*/\\\*/g' - -# Global variables: -ofile=libtool -can_build_shared=yes - -# All known linkers require a `.a' archive for static linking (except MSVC, -# which needs '.lib'). -libext=a - -with_gnu_ld="$lt_cv_prog_gnu_ld" - -old_CC="$CC" -old_CFLAGS="$CFLAGS" - -# Set sane defaults for various variables -test -z "$CC" && CC=cc -test -z "$LTCC" && LTCC=$CC -test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS -test -z "$LD" && LD=ld -test -z "$ac_objext" && ac_objext=o - -_LT_CC_BASENAME([$compiler]) - -# Only perform the check for file, if the check method requires it -test -z "$MAGIC_CMD" && MAGIC_CMD=file -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - _LT_PATH_MAGIC - fi - ;; -esac - -# Use C for the default configuration in the libtool script -LT_SUPPORTED_TAG([CC]) -_LT_LANG_C_CONFIG -_LT_LANG_DEFAULT_CONFIG -_LT_CONFIG_COMMANDS -])# _LT_SETUP - - -# _LT_PROG_LTMAIN -# --------------- -# Note that this code is called both from `configure', and `config.status' -# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, -# `config.status' has no value for ac_aux_dir unless we are using Automake, -# so we pass a copy along to make sure it has a sensible value anyway. -m4_defun([_LT_PROG_LTMAIN], -[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl -_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) -ltmain="$ac_aux_dir/ltmain.sh" -])# _LT_PROG_LTMAIN - - -## ------------------------------------- ## -## Accumulate code for creating libtool. ## -## ------------------------------------- ## - -# So that we can recreate a full libtool script including additional -# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS -# in macros and then make a single call at the end using the `libtool' -# label. - - -# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) -# ---------------------------------------- -# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. -m4_define([_LT_CONFIG_LIBTOOL_INIT], -[m4_ifval([$1], - [m4_append([_LT_OUTPUT_LIBTOOL_INIT], - [$1 -])])]) - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_INIT]) - - -# _LT_CONFIG_LIBTOOL([COMMANDS]) -# ------------------------------ -# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. -m4_define([_LT_CONFIG_LIBTOOL], -[m4_ifval([$1], - [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], - [$1 -])])]) - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) - - -# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) -# ----------------------------------------------------- -m4_defun([_LT_CONFIG_SAVE_COMMANDS], -[_LT_CONFIG_LIBTOOL([$1]) -_LT_CONFIG_LIBTOOL_INIT([$2]) -]) - - -# _LT_FORMAT_COMMENT([COMMENT]) -# ----------------------------- -# Add leading comment marks to the start of each line, and a trailing -# full-stop to the whole comment if one is not present already. -m4_define([_LT_FORMAT_COMMENT], -[m4_ifval([$1], [ -m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], - [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) -)]) - - - -## ------------------------ ## -## FIXME: Eliminate VARNAME ## -## ------------------------ ## - - -# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) -# ------------------------------------------------------------------- -# CONFIGNAME is the name given to the value in the libtool script. -# VARNAME is the (base) name used in the configure script. -# VALUE may be 0, 1 or 2 for a computed quote escaped value based on -# VARNAME. Any other value will be used directly. -m4_define([_LT_DECL], -[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], - [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], - [m4_ifval([$1], [$1], [$2])]) - lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) - m4_ifval([$4], - [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) - lt_dict_add_subkey([lt_decl_dict], [$2], - [tagged?], [m4_ifval([$5], [yes], [no])])]) -]) - - -# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) -# -------------------------------------------------------- -m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) - - -# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) -# ------------------------------------------------ -m4_define([lt_decl_tag_varnames], -[_lt_decl_filter([tagged?], [yes], $@)]) - - -# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) -# --------------------------------------------------------- -m4_define([_lt_decl_filter], -[m4_case([$#], - [0], [m4_fatal([$0: too few arguments: $#])], - [1], [m4_fatal([$0: too few arguments: $#: $1])], - [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], - [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], - [lt_dict_filter([lt_decl_dict], $@)])[]dnl -]) - - -# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) -# -------------------------------------------------- -m4_define([lt_decl_quote_varnames], -[_lt_decl_filter([value], [1], $@)]) - - -# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) -# --------------------------------------------------- -m4_define([lt_decl_dquote_varnames], -[_lt_decl_filter([value], [2], $@)]) - - -# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) -# --------------------------------------------------- -m4_define([lt_decl_varnames_tagged], -[m4_assert([$# <= 2])dnl -_$0(m4_quote(m4_default([$1], [[, ]])), - m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), - m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) -m4_define([_lt_decl_varnames_tagged], -[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) - - -# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) -# ------------------------------------------------ -m4_define([lt_decl_all_varnames], -[_$0(m4_quote(m4_default([$1], [[, ]])), - m4_if([$2], [], - m4_quote(lt_decl_varnames), - m4_quote(m4_shift($@))))[]dnl -]) -m4_define([_lt_decl_all_varnames], -[lt_join($@, lt_decl_varnames_tagged([$1], - lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl -]) - - -# _LT_CONFIG_STATUS_DECLARE([VARNAME]) -# ------------------------------------ -# Quote a variable value, and forward it to `config.status' so that its -# declaration there will have the same value as in `configure'. VARNAME -# must have a single quote delimited value for this to work. -m4_define([_LT_CONFIG_STATUS_DECLARE], -[$1='`$ECHO "X$][$1" | $Xsed -e "$delay_single_quote_subst"`']) - - -# _LT_CONFIG_STATUS_DECLARATIONS -# ------------------------------ -# We delimit libtool config variables with single quotes, so when -# we write them to config.status, we have to be sure to quote all -# embedded single quotes properly. In configure, this macro expands -# each variable declared with _LT_DECL (and _LT_TAGDECL) into: -# -# ='`$ECHO "X$" | $Xsed -e "$delay_single_quote_subst"`' -m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], -[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), - [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) - - -# _LT_LIBTOOL_TAGS -# ---------------- -# Output comment and list of tags supported by the script -m4_defun([_LT_LIBTOOL_TAGS], -[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl -available_tags="_LT_TAGS"dnl -]) - - -# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) -# ----------------------------------- -# Extract the dictionary values for VARNAME (optionally with TAG) and -# expand to a commented shell variable setting: -# -# # Some comment about what VAR is for. -# visible_name=$lt_internal_name -m4_define([_LT_LIBTOOL_DECLARE], -[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], - [description])))[]dnl -m4_pushdef([_libtool_name], - m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl -m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), - [0], [_libtool_name=[$]$1], - [1], [_libtool_name=$lt_[]$1], - [2], [_libtool_name=$lt_[]$1], - [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl -m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl -]) - - -# _LT_LIBTOOL_CONFIG_VARS -# ----------------------- -# Produce commented declarations of non-tagged libtool config variables -# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' -# script. Tagged libtool config variables (even for the LIBTOOL CONFIG -# section) are produced by _LT_LIBTOOL_TAG_VARS. -m4_defun([_LT_LIBTOOL_CONFIG_VARS], -[m4_foreach([_lt_var], - m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), - [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) - - -# _LT_LIBTOOL_TAG_VARS(TAG) -# ------------------------- -m4_define([_LT_LIBTOOL_TAG_VARS], -[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), - [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) - - -# _LT_TAGVAR(VARNAME, [TAGNAME]) -# ------------------------------ -m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) - - -# _LT_CONFIG_COMMANDS -# ------------------- -# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of -# variables for single and double quote escaping we saved from calls -# to _LT_DECL, we can put quote escaped variables declarations -# into `config.status', and then the shell code to quote escape them in -# for loops in `config.status'. Finally, any additional code accumulated -# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. -m4_defun([_LT_CONFIG_COMMANDS], -[AC_PROVIDE_IFELSE([LT_OUTPUT], - dnl If the libtool generation code has been placed in $CONFIG_LT, - dnl instead of duplicating it all over again into config.status, - dnl then we will have config.status run $CONFIG_LT later, so it - dnl needs to know what name is stored there: - [AC_CONFIG_COMMANDS([libtool], - [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], - dnl If the libtool generation code is destined for config.status, - dnl expand the accumulated commands and init code now: - [AC_CONFIG_COMMANDS([libtool], - [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) -])#_LT_CONFIG_COMMANDS - - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], -[ - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -sed_quote_subst='$sed_quote_subst' -double_quote_subst='$double_quote_subst' -delay_variable_subst='$delay_variable_subst' -_LT_CONFIG_STATUS_DECLARATIONS -LTCC='$LTCC' -LTCFLAGS='$LTCFLAGS' -compiler='$compiler_DEFAULT' - -# Quote evaled strings. -for var in lt_decl_all_varnames([[ \ -]], lt_decl_quote_varnames); do - case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in - *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Double-quote double-evaled strings. -for var in lt_decl_all_varnames([[ \ -]], lt_decl_dquote_varnames); do - case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in - *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Fix-up fallback echo if it was mangled by the above quoting rules. -case \$lt_ECHO in -*'\\\[$]0 --fallback-echo"')dnl " - lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 --fallback-echo"\[$]/\[$]0 --fallback-echo"/'\` - ;; -esac - -_LT_OUTPUT_LIBTOOL_INIT -]) - - -# LT_OUTPUT -# --------- -# This macro allows early generation of the libtool script (before -# AC_OUTPUT is called), incase it is used in configure for compilation -# tests. -AC_DEFUN([LT_OUTPUT], -[: ${CONFIG_LT=./config.lt} -AC_MSG_NOTICE([creating $CONFIG_LT]) -cat >"$CONFIG_LT" <<_LTEOF -#! $SHELL -# Generated by $as_me. -# Run this file to recreate a libtool stub with the current configuration. - -lt_cl_silent=false -SHELL=\${CONFIG_SHELL-$SHELL} -_LTEOF - -cat >>"$CONFIG_LT" <<\_LTEOF -AS_SHELL_SANITIZE -_AS_PREPARE - -exec AS_MESSAGE_FD>&1 -exec AS_MESSAGE_LOG_FD>>config.log -{ - echo - AS_BOX([Running $as_me.]) -} >&AS_MESSAGE_LOG_FD - -lt_cl_help="\ -\`$as_me' creates a local libtool stub from the current configuration, -for use in further configure time tests before the real libtool is -generated. - -Usage: $[0] [[OPTIONS]] - - -h, --help print this help, then exit - -V, --version print version number, then exit - -q, --quiet do not print progress messages - -d, --debug don't remove temporary files - -Report bugs to ." - -lt_cl_version="\ -m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl -m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) -configured by $[0], generated by m4_PACKAGE_STRING. - -Copyright (C) 2008 Free Software Foundation, Inc. -This config.lt script is free software; the Free Software Foundation -gives unlimited permision to copy, distribute and modify it." - -while test $[#] != 0 -do - case $[1] in - --version | --v* | -V ) - echo "$lt_cl_version"; exit 0 ;; - --help | --h* | -h ) - echo "$lt_cl_help"; exit 0 ;; - --debug | --d* | -d ) - debug=: ;; - --quiet | --q* | --silent | --s* | -q ) - lt_cl_silent=: ;; - - -*) AC_MSG_ERROR([unrecognized option: $[1] -Try \`$[0] --help' for more information.]) ;; - - *) AC_MSG_ERROR([unrecognized argument: $[1] -Try \`$[0] --help' for more information.]) ;; - esac - shift -done - -if $lt_cl_silent; then - exec AS_MESSAGE_FD>/dev/null -fi -_LTEOF - -cat >>"$CONFIG_LT" <<_LTEOF -_LT_OUTPUT_LIBTOOL_COMMANDS_INIT -_LTEOF - -cat >>"$CONFIG_LT" <<\_LTEOF -AC_MSG_NOTICE([creating $ofile]) -_LT_OUTPUT_LIBTOOL_COMMANDS -AS_EXIT(0) -_LTEOF -chmod +x "$CONFIG_LT" - -# configure is writing to config.log, but config.lt does its own redirection, -# appending to config.log, which fails on DOS, as config.log is still kept -# open by configure. Here we exec the FD to /dev/null, effectively closing -# config.log, so it can be properly (re)opened and appended to by config.lt. -if test "$no_create" != yes; then - lt_cl_success=: - test "$silent" = yes && - lt_config_lt_args="$lt_config_lt_args --quiet" - exec AS_MESSAGE_LOG_FD>/dev/null - $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false - exec AS_MESSAGE_LOG_FD>>config.log - $lt_cl_success || AS_EXIT(1) -fi -])# LT_OUTPUT - - -# _LT_CONFIG(TAG) -# --------------- -# If TAG is the built-in tag, create an initial libtool script with a -# default configuration from the untagged config vars. Otherwise add code -# to config.status for appending the configuration named by TAG from the -# matching tagged config vars. -m4_defun([_LT_CONFIG], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -_LT_CONFIG_SAVE_COMMANDS([ - m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl - m4_if(_LT_TAG, [C], [ - # See if we are running on zsh, and set the options which allow our - # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - - cfgfile="${ofile}T" - trap "$RM \"$cfgfile\"; exit 1" 1 2 15 - $RM "$cfgfile" - - cat <<_LT_EOF >> "$cfgfile" -#! $SHELL - -# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -_LT_COPYING -_LT_LIBTOOL_TAGS - -# ### BEGIN LIBTOOL CONFIG -_LT_LIBTOOL_CONFIG_VARS -_LT_LIBTOOL_TAG_VARS -# ### END LIBTOOL CONFIG - -_LT_EOF - - case $host_os in - aix3*) - cat <<\_LT_EOF >> "$cfgfile" -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -_LT_EOF - ;; - esac - - _LT_PROG_LTMAIN - - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - _LT_PROG_XSI_SHELLFNS - - sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - mv -f "$cfgfile" "$ofile" || - (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") - chmod +x "$ofile" -], -[cat <<_LT_EOF >> "$ofile" - -dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded -dnl in a comment (ie after a #). -# ### BEGIN LIBTOOL TAG CONFIG: $1 -_LT_LIBTOOL_TAG_VARS(_LT_TAG) -# ### END LIBTOOL TAG CONFIG: $1 -_LT_EOF -])dnl /m4_if -], -[m4_if([$1], [], [ - PACKAGE='$PACKAGE' - VERSION='$VERSION' - TIMESTAMP='$TIMESTAMP' - RM='$RM' - ofile='$ofile'], []) -])dnl /_LT_CONFIG_SAVE_COMMANDS -])# _LT_CONFIG - - -# LT_SUPPORTED_TAG(TAG) -# --------------------- -# Trace this macro to discover what tags are supported by the libtool -# --tag option, using: -# autoconf --trace 'LT_SUPPORTED_TAG:$1' -AC_DEFUN([LT_SUPPORTED_TAG], []) - - -# C support is built-in for now -m4_define([_LT_LANG_C_enabled], []) -m4_define([_LT_TAGS], []) - - -# LT_LANG(LANG) -# ------------- -# Enable libtool support for the given language if not already enabled. -AC_DEFUN([LT_LANG], -[AC_BEFORE([$0], [LT_OUTPUT])dnl -m4_case([$1], - [C], [_LT_LANG(C)], - [C++], [_LT_LANG(CXX)], - [Java], [_LT_LANG(GCJ)], - [Fortran 77], [_LT_LANG(F77)], - [Fortran], [_LT_LANG(FC)], - [Windows Resource], [_LT_LANG(RC)], - [m4_ifdef([_LT_LANG_]$1[_CONFIG], - [_LT_LANG($1)], - [m4_fatal([$0: unsupported language: "$1"])])])dnl -])# LT_LANG - - -# _LT_LANG(LANGNAME) -# ------------------ -m4_defun([_LT_LANG], -[m4_ifdef([_LT_LANG_]$1[_enabled], [], - [LT_SUPPORTED_TAG([$1])dnl - m4_append([_LT_TAGS], [$1 ])dnl - m4_define([_LT_LANG_]$1[_enabled], [])dnl - _LT_LANG_$1_CONFIG($1)])dnl -])# _LT_LANG - - -# _LT_LANG_DEFAULT_CONFIG -# ----------------------- -m4_defun([_LT_LANG_DEFAULT_CONFIG], -[AC_PROVIDE_IFELSE([AC_PROG_CXX], - [LT_LANG(CXX)], - [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) - -AC_PROVIDE_IFELSE([AC_PROG_F77], - [LT_LANG(F77)], - [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) - -AC_PROVIDE_IFELSE([AC_PROG_FC], - [LT_LANG(FC)], - [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) - -dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal -dnl pulling things in needlessly. -AC_PROVIDE_IFELSE([AC_PROG_GCJ], - [LT_LANG(GCJ)], - [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], - [LT_LANG(GCJ)], - [AC_PROVIDE_IFELSE([LT_PROG_GCJ], - [LT_LANG(GCJ)], - [m4_ifdef([AC_PROG_GCJ], - [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) - m4_ifdef([A][M_PROG_GCJ], - [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) - m4_ifdef([LT_PROG_GCJ], - [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) - -AC_PROVIDE_IFELSE([LT_PROG_RC], - [LT_LANG(RC)], - [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) -])# _LT_LANG_DEFAULT_CONFIG - -# Obsolete macros: -AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) -AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) -AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) -AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_CXX], []) -dnl AC_DEFUN([AC_LIBTOOL_F77], []) -dnl AC_DEFUN([AC_LIBTOOL_FC], []) -dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) - - -# _LT_TAG_COMPILER -# ---------------- -m4_defun([_LT_TAG_COMPILER], -[AC_REQUIRE([AC_PROG_CC])dnl - -_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl -_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl -_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl -_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC -])# _LT_TAG_COMPILER - - -# _LT_COMPILER_BOILERPLATE -# ------------------------ -# Check for compiler boilerplate output or warnings with -# the simple compiler test code. -m4_defun([_LT_COMPILER_BOILERPLATE], -[m4_require([_LT_DECL_SED])dnl -ac_outfile=conftest.$ac_objext -echo "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$RM conftest* -])# _LT_COMPILER_BOILERPLATE - - -# _LT_LINKER_BOILERPLATE -# ---------------------- -# Check for linker boilerplate output or warnings with -# the simple link test code. -m4_defun([_LT_LINKER_BOILERPLATE], -[m4_require([_LT_DECL_SED])dnl -ac_outfile=conftest.$ac_objext -echo "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$RM -r conftest* -])# _LT_LINKER_BOILERPLATE - -# _LT_REQUIRED_DARWIN_CHECKS -# ------------------------- -m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ - case $host_os in - rhapsody* | darwin*) - AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) - AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) - AC_CHECK_TOOL([LIPO], [lipo], [:]) - AC_CHECK_TOOL([OTOOL], [otool], [:]) - AC_CHECK_TOOL([OTOOL64], [otool64], [:]) - _LT_DECL([], [DSYMUTIL], [1], - [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) - _LT_DECL([], [NMEDIT], [1], - [Tool to change global to local symbols on Mac OS X]) - _LT_DECL([], [LIPO], [1], - [Tool to manipulate fat objects and archives on Mac OS X]) - _LT_DECL([], [OTOOL], [1], - [ldd/readelf like tool for Mach-O binaries on Mac OS X]) - _LT_DECL([], [OTOOL64], [1], - [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) - - AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], - [lt_cv_apple_cc_single_mod=no - if test -z "${LT_MULTI_MODULE}"; then - # By default we will add the -single_module flag. You can override - # by either setting the environment variable LT_MULTI_MODULE - # non-empty at configure time, or by adding -multi_module to the - # link flags. - rm -rf libconftest.dylib* - echo "int foo(void){return 1;}" > conftest.c - echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ --dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD - $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ - -dynamiclib -Wl,-single_module conftest.c 2>conftest.err - _lt_result=$? - if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then - lt_cv_apple_cc_single_mod=yes - else - cat conftest.err >&AS_MESSAGE_LOG_FD - fi - rm -rf libconftest.dylib* - rm -f conftest.* - fi]) - AC_CACHE_CHECK([for -exported_symbols_list linker flag], - [lt_cv_ld_exported_symbols_list], - [lt_cv_ld_exported_symbols_list=no - save_LDFLAGS=$LDFLAGS - echo "_main" > conftest.sym - LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" - AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], - [lt_cv_ld_exported_symbols_list=yes], - [lt_cv_ld_exported_symbols_list=no]) - LDFLAGS="$save_LDFLAGS" - ]) - case $host_os in - rhapsody* | darwin1.[[012]]) - _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; - darwin1.*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - 10.[[012]]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - 10.*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - esac - ;; - esac - if test "$lt_cv_apple_cc_single_mod" = "yes"; then - _lt_dar_single_mod='$single_module' - fi - if test "$lt_cv_ld_exported_symbols_list" = "yes"; then - _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' - else - _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - if test "$DSYMUTIL" != ":"; then - _lt_dsymutil='~$DSYMUTIL $lib || :' - else - _lt_dsymutil= - fi - ;; - esac -]) - - -# _LT_DARWIN_LINKER_FEATURES -# -------------------------- -# Checks for linker and compiler features on darwin -m4_defun([_LT_DARWIN_LINKER_FEATURES], -[ - m4_require([_LT_REQUIRED_DARWIN_CHECKS]) - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_automatic, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_TAGVAR(whole_archive_flag_spec, $1)='' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" - case $cc_basename in - ifort*) _lt_dar_can_shared=yes ;; - *) _lt_dar_can_shared=$GCC ;; - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=echo - _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" - _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" - _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - m4_if([$1], [CXX], -[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then - _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" - fi -],[]) - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi -]) - -# _LT_SYS_MODULE_PATH_AIX -# ----------------------- -# Links a minimal program and checks the executable -# for the system default hardcoded library path. In most cases, -# this is /usr/lib:/lib, but when the MPI compilers are used -# the location of the communication and MPI libs are included too. -# If we don't find anything, use the default library path according -# to the aix ld manual. -m4_defun([_LT_SYS_MODULE_PATH_AIX], -[m4_require([_LT_DECL_SED])dnl -AC_LINK_IFELSE(AC_LANG_PROGRAM,[ -lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\(.*\)$/\1/ - p - } - }' -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then - aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -fi],[]) -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi -])# _LT_SYS_MODULE_PATH_AIX - - -# _LT_SHELL_INIT(ARG) -# ------------------- -m4_define([_LT_SHELL_INIT], -[ifdef([AC_DIVERSION_NOTICE], - [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], - [AC_DIVERT_PUSH(NOTICE)]) -$1 -AC_DIVERT_POP -])# _LT_SHELL_INIT - - -# _LT_PROG_ECHO_BACKSLASH -# ----------------------- -# Add some code to the start of the generated configure script which -# will find an echo command which doesn't interpret backslashes. -m4_defun([_LT_PROG_ECHO_BACKSLASH], -[_LT_SHELL_INIT([ -# Check that we are running under the correct shell. -SHELL=${CONFIG_SHELL-/bin/sh} - -case X$lt_ECHO in -X*--fallback-echo) - # Remove one level of quotation (which was required for Make). - ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` - ;; -esac - -ECHO=${lt_ECHO-echo} -if test "X[$]1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift -elif test "X[$]1" = X--fallback-echo; then - # Avoid inline document here, it may be left over - : -elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then - # Yippee, $ECHO works! - : -else - # Restart under the correct shell. - exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} -fi - -if test "X[$]1" = X--fallback-echo; then - # used as fallback echo - shift - cat <<_LT_EOF -[$]* -_LT_EOF - exit 0 -fi - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -if test -z "$lt_ECHO"; then - if test "X${echo_test_string+set}" != Xset; then - # find a string as large as possible, as long as the shell can cope with it - for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do - # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... - if { echo_test_string=`eval $cmd`; } 2>/dev/null && - { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null - then - break - fi - done - fi - - if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && - echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - : - else - # The Solaris, AIX, and Digital Unix default echo programs unquote - # backslashes. This makes it impossible to quote backslashes using - # echo "$something" | sed 's/\\/\\\\/g' - # - # So, first we look for a working echo in the user's PATH. - - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for dir in $PATH /usr/ucb; do - IFS="$lt_save_ifs" - if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && - test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - ECHO="$dir/echo" - break - fi - done - IFS="$lt_save_ifs" - - if test "X$ECHO" = Xecho; then - # We didn't find a better echo, so look for alternatives. - if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && - echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # This shell has a builtin print -r that does the trick. - ECHO='print -r' - elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && - test "X$CONFIG_SHELL" != X/bin/ksh; then - # If we have ksh, try running configure again with it. - ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} - export ORIGINAL_CONFIG_SHELL - CONFIG_SHELL=/bin/ksh - export CONFIG_SHELL - exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} - else - # Try using printf. - ECHO='printf %s\n' - if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && - echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # Cool, printf works - : - elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL - export CONFIG_SHELL - SHELL="$CONFIG_SHELL" - export SHELL - ECHO="$CONFIG_SHELL [$]0 --fallback-echo" - elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - ECHO="$CONFIG_SHELL [$]0 --fallback-echo" - else - # maybe with a smaller string... - prev=: - - for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do - if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null - then - break - fi - prev="$cmd" - done - - if test "$prev" != 'sed 50q "[$]0"'; then - echo_test_string=`eval $prev` - export echo_test_string - exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} - else - # Oops. We lost completely, so just stick with echo. - ECHO=echo - fi - fi - fi - fi - fi -fi - -# Copy echo and quote the copy suitably for passing to libtool from -# the Makefile, instead of quoting the original, which is used later. -lt_ECHO=$ECHO -if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then - lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" -fi - -AC_SUBST(lt_ECHO) -]) -_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) -_LT_DECL([], [ECHO], [1], - [An echo program that does not interpret backslashes]) -])# _LT_PROG_ECHO_BACKSLASH - - -# _LT_ENABLE_LOCK -# --------------- -m4_defun([_LT_ENABLE_LOCK], -[AC_ARG_ENABLE([libtool-lock], - [AS_HELP_STRING([--disable-libtool-lock], - [avoid locking (might break parallel builds)])]) -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -ia64-*-hpux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.$ac_objext` in - *ELF-32*) - HPUX_IA64_MODE="32" - ;; - *ELF-64*) - HPUX_IA64_MODE="64" - ;; - esac - fi - rm -rf conftest* - ;; -*-*-irix6*) - # Find out which ABI we are using. - echo '[#]line __oline__ "configure"' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - if test "$lt_cv_prog_gnu_ld" = yes; then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -melf32bsmip" - ;; - *N32*) - LD="${LD-ld} -melf32bmipn32" - ;; - *64-bit*) - LD="${LD-ld} -melf64bmip" - ;; - esac - else - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - fi - rm -rf conftest* - ;; - -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ -s390*-*linux*|s390*-*tpf*|sparc*-*linux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in - *32-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_i386_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_i386" - ;; - ppc64-*linux*|powerpc64-*linux*) - LD="${LD-ld} -m elf32ppclinux" - ;; - s390x-*linux*) - LD="${LD-ld} -m elf_s390" - ;; - sparc64-*linux*) - LD="${LD-ld} -m elf32_sparc" - ;; - esac - ;; - *64-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_x86_64_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_x86_64" - ;; - ppc*-*linux*|powerpc*-*linux*) - LD="${LD-ld} -m elf64ppc" - ;; - s390*-*linux*|s390*-*tpf*) - LD="${LD-ld} -m elf64_s390" - ;; - sparc*-*linux*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -belf" - AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, - [AC_LANG_PUSH(C) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) - AC_LANG_POP]) - if test x"$lt_cv_cc_needs_belf" != x"yes"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" - fi - ;; -sparc*-*solaris*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in - *64-bit*) - case $lt_cv_prog_gnu_ld in - yes*) LD="${LD-ld} -m elf64_sparc" ;; - *) - if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then - LD="${LD-ld} -64" - fi - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; -esac - -need_locks="$enable_libtool_lock" -])# _LT_ENABLE_LOCK - - -# _LT_CMD_OLD_ARCHIVE -# ------------------- -m4_defun([_LT_CMD_OLD_ARCHIVE], -[AC_CHECK_TOOL(AR, ar, false) -test -z "$AR" && AR=ar -test -z "$AR_FLAGS" && AR_FLAGS=cru -_LT_DECL([], [AR], [1], [The archiver]) -_LT_DECL([], [AR_FLAGS], [1]) - -AC_CHECK_TOOL(STRIP, strip, :) -test -z "$STRIP" && STRIP=: -_LT_DECL([], [STRIP], [1], [A symbol stripping program]) - -AC_CHECK_TOOL(RANLIB, ranlib, :) -test -z "$RANLIB" && RANLIB=: -_LT_DECL([], [RANLIB], [1], - [Commands used to install an old-style archive]) - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" - ;; - *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" -fi -_LT_DECL([], [old_postinstall_cmds], [2]) -_LT_DECL([], [old_postuninstall_cmds], [2]) -_LT_TAGDECL([], [old_archive_cmds], [2], - [Commands used to build an old-style archive]) -])# _LT_CMD_OLD_ARCHIVE - - -# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) -# ---------------------------------------------------------------- -# Check whether the given compiler option works -AC_DEFUN([_LT_COMPILER_OPTION], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_SED])dnl -AC_CACHE_CHECK([$1], [$2], - [$2=no - m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$3" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - $2=yes - fi - fi - $RM conftest* -]) - -if test x"[$]$2" = xyes; then - m4_if([$5], , :, [$5]) -else - m4_if([$6], , :, [$6]) -fi -])# _LT_COMPILER_OPTION - -# Old name: -AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) - - -# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [ACTION-SUCCESS], [ACTION-FAILURE]) -# ---------------------------------------------------- -# Check whether the given linker option works -AC_DEFUN([_LT_LINKER_OPTION], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_SED])dnl -AC_CACHE_CHECK([$1], [$2], - [$2=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $3" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&AS_MESSAGE_LOG_FD - $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - $2=yes - fi - else - $2=yes - fi - fi - $RM -r conftest* - LDFLAGS="$save_LDFLAGS" -]) - -if test x"[$]$2" = xyes; then - m4_if([$4], , :, [$4]) -else - m4_if([$5], , :, [$5]) -fi -])# _LT_LINKER_OPTION - -# Old name: -AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) - - -# LT_CMD_MAX_LEN -#--------------- -AC_DEFUN([LT_CMD_MAX_LEN], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -# find the maximum length of command line arguments -AC_MSG_CHECKING([the maximum length of command line arguments]) -AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl - i=0 - teststring="ABCD" - - case $build_os in - msdosdjgpp*) - # On DJGPP, this test can blow up pretty badly due to problems in libc - # (any single argument exceeding 2000 bytes causes a buffer overrun - # during glob expansion). Even if it were fixed, the result of this - # check would be larger than it should be. - lt_cv_sys_max_cmd_len=12288; # 12K is about right - ;; - - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. - # Libtool will interpret -1 as no limit whatsoever - lt_cv_sys_max_cmd_len=-1; - ;; - - cygwin* | mingw* | cegcc*) - # On Win9x/ME, this test blows up -- it succeeds, but takes - # about 5 minutes as the teststring grows exponentially. - # Worse, since 9x/ME are not pre-emptively multitasking, - # you end up with a "frozen" computer, even though with patience - # the test eventually succeeds (with a max line length of 256k). - # Instead, let's just punt: use the minimum linelength reported by - # all of the supported platforms: 8192 (on NT/2K/XP). - lt_cv_sys_max_cmd_len=8192; - ;; - - amigaos*) - # On AmigaOS with pdksh, this test takes hours, literally. - # So we just punt and use a minimum line length of 8192. - lt_cv_sys_max_cmd_len=8192; - ;; - - netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) - # This has been around since 386BSD, at least. Likely further. - if test -x /sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` - elif test -x /usr/sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` - else - lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs - fi - # And add a safety zone - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - ;; - - interix*) - # We know the value 262144 and hardcode it with a safety zone (like BSD) - lt_cv_sys_max_cmd_len=196608 - ;; - - osf*) - # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure - # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not - # nice to cause kernel panics so lets avoid the loop below. - # First set a reasonable default. - lt_cv_sys_max_cmd_len=16384 - # - if test -x /sbin/sysconfig; then - case `/sbin/sysconfig -q proc exec_disable_arg_limit` in - *1*) lt_cv_sys_max_cmd_len=-1 ;; - esac - fi - ;; - sco3.2v5*) - lt_cv_sys_max_cmd_len=102400 - ;; - sysv5* | sco5v6* | sysv4.2uw2*) - kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` - if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` - else - lt_cv_sys_max_cmd_len=32768 - fi - ;; - *) - lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len"; then - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - else - # Make teststring a little bigger before we do anything with it. - # a 1K string should be a reasonable start. - for i in 1 2 3 4 5 6 7 8 ; do - teststring=$teststring$teststring - done - SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ - = "XX$teststring$teststring"; } >/dev/null 2>&1 && - test $i != 17 # 1/2 MB should be enough - do - i=`expr $i + 1` - teststring=$teststring$teststring - done - # Only check the string length outside the loop. - lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` - teststring= - # Add a significant safety factor because C++ compilers can tack on - # massive amounts of additional arguments before passing them to the - # linker. It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` - fi - ;; - esac -]) -if test -n $lt_cv_sys_max_cmd_len ; then - AC_MSG_RESULT($lt_cv_sys_max_cmd_len) -else - AC_MSG_RESULT(none) -fi -max_cmd_len=$lt_cv_sys_max_cmd_len -_LT_DECL([], [max_cmd_len], [0], - [What is the maximum length of a command?]) -])# LT_CMD_MAX_LEN - -# Old name: -AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) - - -# _LT_HEADER_DLFCN -# ---------------- -m4_defun([_LT_HEADER_DLFCN], -[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl -])# _LT_HEADER_DLFCN - - -# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, -# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) -# ---------------------------------------------------------------- -m4_defun([_LT_TRY_DLOPEN_SELF], -[m4_require([_LT_HEADER_DLFCN])dnl -if test "$cross_compiling" = yes; then : - [$4] -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -[#line __oline__ "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -}] -_LT_EOF - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) $1 ;; - x$lt_dlneed_uscore) $2 ;; - x$lt_dlunknown|x*) $3 ;; - esac - else : - # compilation failed - $3 - fi -fi -rm -fr conftest* -])# _LT_TRY_DLOPEN_SELF - - -# LT_SYS_DLOPEN_SELF -# ------------------ -AC_DEFUN([LT_SYS_DLOPEN_SELF], -[m4_require([_LT_HEADER_DLFCN])dnl -if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32* | cegcc*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ]) - ;; - - *) - AC_CHECK_FUNC([shl_load], - [lt_cv_dlopen="shl_load"], - [AC_CHECK_LIB([dld], [shl_load], - [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], - [AC_CHECK_FUNC([dlopen], - [lt_cv_dlopen="dlopen"], - [AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], - [AC_CHECK_LIB([svld], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], - [AC_CHECK_LIB([dld], [dld_link], - [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) - ]) - ]) - ]) - ]) - ]) - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - AC_CACHE_CHECK([whether a program can dlopen itself], - lt_cv_dlopen_self, [dnl - _LT_TRY_DLOPEN_SELF( - lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, - lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) - ]) - - if test "x$lt_cv_dlopen_self" = xyes; then - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" - AC_CACHE_CHECK([whether a statically linked program can dlopen itself], - lt_cv_dlopen_self_static, [dnl - _LT_TRY_DLOPEN_SELF( - lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, - lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) - ]) - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi -_LT_DECL([dlopen_support], [enable_dlopen], [0], - [Whether dlopen is supported]) -_LT_DECL([dlopen_self], [enable_dlopen_self], [0], - [Whether dlopen of programs is supported]) -_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], - [Whether dlopen of statically linked programs is supported]) -])# LT_SYS_DLOPEN_SELF - -# Old name: -AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) - - -# _LT_COMPILER_C_O([TAGNAME]) -# --------------------------- -# Check to see if options -c and -o are simultaneously supported by compiler. -# This macro does not hard code the compiler like AC_PROG_CC_C_O. -m4_defun([_LT_COMPILER_C_O], -[m4_require([_LT_DECL_SED])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_TAG_COMPILER])dnl -AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], - [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], - [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes - fi - fi - chmod u+w . 2>&AS_MESSAGE_LOG_FD - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* -]) -_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], - [Does compiler simultaneously support -c and -o options?]) -])# _LT_COMPILER_C_O - - -# _LT_COMPILER_FILE_LOCKS([TAGNAME]) -# ---------------------------------- -# Check to see if we can do hard links to lock some files if needed -m4_defun([_LT_COMPILER_FILE_LOCKS], -[m4_require([_LT_ENABLE_LOCK])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -_LT_COMPILER_C_O([$1]) - -hard_links="nottested" -if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - AC_MSG_CHECKING([if we can lock with hard links]) - hard_links=yes - $RM conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - AC_MSG_RESULT([$hard_links]) - if test "$hard_links" = no; then - AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) - need_locks=warn - fi -else - need_locks=no -fi -_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) -])# _LT_COMPILER_FILE_LOCKS - - -# _LT_CHECK_OBJDIR -# ---------------- -m4_defun([_LT_CHECK_OBJDIR], -[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], -[rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - lt_cv_objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - lt_cv_objdir=_libs -fi -rmdir .libs 2>/dev/null]) -objdir=$lt_cv_objdir -_LT_DECL([], [objdir], [0], - [The name of the directory that contains temporary libtool files])dnl -m4_pattern_allow([LT_OBJDIR])dnl -AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", - [Define to the sub-directory in which libtool stores uninstalled libraries.]) -])# _LT_CHECK_OBJDIR - - -# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) -# -------------------------------------- -# Check hardcoding attributes. -m4_defun([_LT_LINKER_HARDCODE_LIBPATH], -[AC_MSG_CHECKING([how to hardcode library paths into programs]) -_LT_TAGVAR(hardcode_action, $1)= -if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || - test -n "$_LT_TAGVAR(runpath_var, $1)" || - test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then - - # We can hardcode non-existent directories. - if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && - test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then - # Linking always hardcodes the temporary library directory. - _LT_TAGVAR(hardcode_action, $1)=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - _LT_TAGVAR(hardcode_action, $1)=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - _LT_TAGVAR(hardcode_action, $1)=unsupported -fi -AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) - -if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || - test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi -_LT_TAGDECL([], [hardcode_action], [0], - [How to hardcode a shared library path into an executable]) -])# _LT_LINKER_HARDCODE_LIBPATH - - -# _LT_CMD_STRIPLIB -# ---------------- -m4_defun([_LT_CMD_STRIPLIB], -[m4_require([_LT_DECL_EGREP]) -striplib= -old_striplib= -AC_MSG_CHECKING([whether stripping libraries is possible]) -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - AC_MSG_RESULT([yes]) -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - old_striplib="$STRIP -S" - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - fi - ;; - *) - AC_MSG_RESULT([no]) - ;; - esac -fi -_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) -_LT_DECL([], [striplib], [1]) -])# _LT_CMD_STRIPLIB - - -# _LT_SYS_DYNAMIC_LINKER([TAG]) -# ----------------------------- -# PORTME Fill in your ld.so characteristics -m4_defun([_LT_SYS_DYNAMIC_LINKER], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_OBJDUMP])dnl -m4_require([_LT_DECL_SED])dnl -AC_MSG_CHECKING([dynamic linker characteristics]) -m4_if([$1], - [], [ -if test "$GCC" = yes; then - case $host_os in - darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; - *) lt_awk_arg="/^libraries:/" ;; - esac - lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` - else - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - # Ok, now we have the path, separated by spaces, we can step through it - # and add multilib dir if necessary. - lt_tmp_lt_search_path_spec= - lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` - for lt_sys_path in $lt_search_path_spec; do - if test -d "$lt_sys_path/$lt_multi_os_dir"; then - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" - else - test -d "$lt_sys_path" && \ - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" - fi - done - lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' -BEGIN {RS=" "; FS="/|\n";} { - lt_foo=""; - lt_count=0; - for (lt_i = NF; lt_i > 0; lt_i--) { - if ($lt_i != "" && $lt_i != ".") { - if ($lt_i == "..") { - lt_count++; - } else { - if (lt_count == 0) { - lt_foo="/" $lt_i lt_foo; - } else { - lt_count--; - } - } - } - } - if (lt_foo != "") { lt_freq[[lt_foo]]++; } - if (lt_freq[[lt_foo]] == 1) { print lt_foo; } -}'` - sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi]) -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix[[4-9]]*) - version_type=linux - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[[01]] | aix4.[[01]].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - case $host_cpu in - powerpc) - # Since July 2007 AmigaOS4 officially supports .so libraries. - # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - ;; - m68k) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - esac - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[[45]]*) - version_type=linux - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32* | cegcc*) - version_type=windows - shrext_cmds=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$host_os in - yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" - ;; - mingw* | cegcc*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then - # It is most probably a Windows format PATH printed by - # mingw gcc, but we are running on Cygwin. Gcc prints its search - # path with ; separators, and with drive letters. We can handle the - # drive letters (cygwin fileutils understands them), so leave them, - # especially as we might pass files found there to a mingw objdump, - # which wouldn't understand a cygwinified path. Ahh. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - ;; - esac - ;; - - *) - library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' - ;; - esac - dynamic_linker='Win32 ld.exe' - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' -m4_if([$1], [],[ - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd1*) - dynamic_linker=no - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[[123]]*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[[01]]* | freebsdelf3.[[01]]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ - freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - *) # from 4.6 on, and DragonFly - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555. - postinstall_cmds='chmod 555 $lib' - ;; - -interix[[3-9]]*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be Linux ELF. -linux* | k*bsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - # Some binutils ld are patched to set DT_RUNPATH - save_LDFLAGS=$LDFLAGS - save_libdir=$libdir - eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ - LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" - AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], - [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], - [shlibpath_overrides_runpath=yes])]) - LDFLAGS=$save_LDFLAGS - libdir=$save_libdir - - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsdelf*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='NetBSD ld.elf_so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -*nto* | *qnx*) - version_type=qnx - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='ldqnx.so' - ;; - -openbsd*) - version_type=sunos - sys_lib_dlsearch_path_spec="/usr/lib" - need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[[89]] | openbsd2.[[89]].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext_cmds=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -rdos*) - dynamic_linker=no - ;; - -solaris*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - version_type=freebsd-elf - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - if test "$with_gnu_ld" = yes; then - sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' - else - sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' - case $host_os in - sco3.2v5*) - sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" - ;; - esac - fi - sys_lib_dlsearch_path_spec='/usr/lib' - ;; - -tpf*) - # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -uts4*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -AC_MSG_RESULT([$dynamic_linker]) -test "$dynamic_linker" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then - sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" -fi -if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then - sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" -fi - -_LT_DECL([], [variables_saved_for_relink], [1], - [Variables whose values should be saved in libtool wrapper scripts and - restored at link time]) -_LT_DECL([], [need_lib_prefix], [0], - [Do we need the "lib" prefix for modules?]) -_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) -_LT_DECL([], [version_type], [0], [Library versioning type]) -_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) -_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) -_LT_DECL([], [shlibpath_overrides_runpath], [0], - [Is shlibpath searched before the hard-coded library search path?]) -_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) -_LT_DECL([], [library_names_spec], [1], - [[List of archive names. First name is the real one, the rest are links. - The last name is the one that the linker finds with -lNAME]]) -_LT_DECL([], [soname_spec], [1], - [[The coded name of the library, if different from the real name]]) -_LT_DECL([], [postinstall_cmds], [2], - [Command to use after installation of a shared archive]) -_LT_DECL([], [postuninstall_cmds], [2], - [Command to use after uninstallation of a shared archive]) -_LT_DECL([], [finish_cmds], [2], - [Commands used to finish a libtool library installation in a directory]) -_LT_DECL([], [finish_eval], [1], - [[As "finish_cmds", except a single script fragment to be evaled but - not shown]]) -_LT_DECL([], [hardcode_into_libs], [0], - [Whether we should hardcode library paths into libraries]) -_LT_DECL([], [sys_lib_search_path_spec], [2], - [Compile-time system search path for libraries]) -_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], - [Run-time system search path for libraries]) -])# _LT_SYS_DYNAMIC_LINKER - - -# _LT_PATH_TOOL_PREFIX(TOOL) -# -------------------------- -# find a file program which can recognize shared library -AC_DEFUN([_LT_PATH_TOOL_PREFIX], -[m4_require([_LT_DECL_EGREP])dnl -AC_MSG_CHECKING([for $1]) -AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, -[case $MAGIC_CMD in -[[\\/*] | ?:[\\/]*]) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR -dnl $ac_dummy forces splitting on constant user-supplied paths. -dnl POSIX.2 word splitting is done only on the output of word expansions, -dnl not every word. This closes a longstanding sh security hole. - ac_dummy="m4_if([$2], , $PATH, [$2])" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$1; then - lt_cv_path_MAGIC_CMD="$ac_dir/$1" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac]) -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - AC_MSG_RESULT($MAGIC_CMD) -else - AC_MSG_RESULT(no) -fi -_LT_DECL([], [MAGIC_CMD], [0], - [Used to examine libraries when file_magic_cmd begins with "file"])dnl -])# _LT_PATH_TOOL_PREFIX - -# Old name: -AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) - - -# _LT_PATH_MAGIC -# -------------- -# find a file program which can recognize a shared library -m4_defun([_LT_PATH_MAGIC], -[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) - else - MAGIC_CMD=: - fi -fi -])# _LT_PATH_MAGIC - - -# LT_PATH_LD -# ---------- -# find the pathname to the GNU or non-GNU linker -AC_DEFUN([LT_PATH_LD], -[AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_DECL_EGREP])dnl - -AC_ARG_WITH([gnu-ld], - [AS_HELP_STRING([--with-gnu-ld], - [assume the C compiler uses GNU ld @<:@default=no@:>@])], - [test "$withval" = no || with_gnu_ld=yes], - [with_gnu_ld=no])dnl - -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - AC_MSG_CHECKING([for ld used by $CC]) - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [[\\/]]* | ?:[[\\/]]*) - re_direlt='/[[^/]][[^/]]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` - while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do - ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - AC_MSG_CHECKING([for GNU ld]) -else - AC_MSG_CHECKING([for non-GNU ld]) -fi -AC_CACHE_VAL(lt_cv_path_LD, -[if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - else - lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - fi - ;; - -cegcc) - # use the weaker test based on 'objdump'. See mingw*. - lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - ;; - -darwin* | rhapsody*) - lt_cv_deplibs_check_method=pass_all - ;; - -freebsd* | dragonfly*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file - case $host_cpu in - ia64*) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' - lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so - ;; - hppa*64*) - [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] - lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl - ;; - *) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - esac - ;; - -interix[[3-9]]*) - # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' - ;; - -irix5* | irix6* | nonstopux*) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be Linux ELF. -linux* | k*bsd*-gnu) - lt_cv_deplibs_check_method=pass_all - ;; - -netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' - fi - ;; - -newos6*) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -*nto* | *qnx*) - lt_cv_deplibs_check_method=pass_all - ;; - -openbsd*) - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - fi - ;; - -osf3* | osf4* | osf5*) - lt_cv_deplibs_check_method=pass_all - ;; - -rdos*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.3*) - case $host_vendor in - motorola) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" - lt_cv_file_magic_test_file=/lib/libc.so - ;; - siemens) - lt_cv_deplibs_check_method=pass_all - ;; - pc) - lt_cv_deplibs_check_method=pass_all - ;; - esac - ;; - -tpf*) - lt_cv_deplibs_check_method=pass_all - ;; -esac -]) -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method -test -z "$deplibs_check_method" && deplibs_check_method=unknown - -_LT_DECL([], [deplibs_check_method], [1], - [Method to check whether dependent libraries are shared objects]) -_LT_DECL([], [file_magic_cmd], [1], - [Command to use when deplibs_check_method == "file_magic"]) -])# _LT_CHECK_MAGIC_METHOD - - -# LT_PATH_NM -# ---------- -# find the pathname to a BSD- or MS-compatible name lister -AC_DEFUN([LT_PATH_NM], -[AC_REQUIRE([AC_PROG_CC])dnl -AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, -[if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM="$NM" -else - lt_nm_to_check="${ac_tool_prefix}nm" - if test -n "$ac_tool_prefix" && test "$build" = "$host"; then - lt_nm_to_check="$lt_nm_to_check nm" - fi - for lt_tmp_nm in $lt_nm_to_check; do - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/$lt_tmp_nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" - break - ;; - *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - ;; - esac - ;; - esac - fi - done - IFS="$lt_save_ifs" - done - : ${lt_cv_path_NM=no} -fi]) -if test "$lt_cv_path_NM" != "no"; then - NM="$lt_cv_path_NM" -else - # Didn't find any BSD compatible name lister, look for dumpbin. - AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :) - AC_SUBST([DUMPBIN]) - if test "$DUMPBIN" != ":"; then - NM="$DUMPBIN" - fi -fi -test -z "$NM" && NM=nm -AC_SUBST([NM]) -_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl - -AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], - [lt_cv_nm_interface="BSD nm" - echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:__oline__: $ac_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$ac_compile" 2>conftest.err) - cat conftest.err >&AS_MESSAGE_LOG_FD - (eval echo "\"\$as_me:__oline__: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) - (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) - cat conftest.err >&AS_MESSAGE_LOG_FD - (eval echo "\"\$as_me:__oline__: output\"" >&AS_MESSAGE_LOG_FD) - cat conftest.out >&AS_MESSAGE_LOG_FD - if $GREP 'External.*some_variable' conftest.out > /dev/null; then - lt_cv_nm_interface="MS dumpbin" - fi - rm -f conftest*]) -])# LT_PATH_NM - -# Old names: -AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) -AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_PROG_NM], []) -dnl AC_DEFUN([AC_PROG_NM], []) - - -# LT_LIB_M -# -------- -# check for math library -AC_DEFUN([LT_LIB_M], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -LIBM= -case $host in -*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) - # These system don't have libm, or don't need it - ;; -*-ncr-sysv4.3*) - AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") - AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") - ;; -*) - AC_CHECK_LIB(m, cos, LIBM="-lm") - ;; -esac -AC_SUBST([LIBM]) -])# LT_LIB_M - -# Old name: -AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_CHECK_LIBM], []) - - -# _LT_COMPILER_NO_RTTI([TAGNAME]) -# ------------------------------- -m4_defun([_LT_COMPILER_NO_RTTI], -[m4_require([_LT_TAG_COMPILER])dnl - -_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= - -if test "$GCC" = yes; then - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' - - _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], - lt_cv_prog_compiler_rtti_exceptions, - [-fno-rtti -fno-exceptions], [], - [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) -fi -_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], - [Compiler flag to turn off builtin functions]) -])# _LT_COMPILER_NO_RTTI - - -# _LT_CMD_GLOBAL_SYMBOLS -# ---------------------- -m4_defun([_LT_CMD_GLOBAL_SYMBOLS], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([LT_PATH_NM])dnl -AC_REQUIRE([LT_PATH_LD])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_TAG_COMPILER])dnl - -# Check for command to grab the raw symbol name followed by C symbol from nm. -AC_MSG_CHECKING([command to parse $NM output from $compiler object]) -AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], -[ -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[[BCDEGRST]]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' - -# Define system-specific variables. -case $host_os in -aix*) - symcode='[[BCDT]]' - ;; -cygwin* | mingw* | pw32* | cegcc*) - symcode='[[ABCDGISTW]]' - ;; -hpux*) - if test "$host_cpu" = ia64; then - symcode='[[ABCDEGRST]]' - fi - ;; -irix* | nonstopux*) - symcode='[[BCDEGRST]]' - ;; -osf*) - symcode='[[BCDEGQRST]]' - ;; -solaris*) - symcode='[[BDRT]]' - ;; -sco3.2v5*) - symcode='[[DT]]' - ;; -sysv4.2uw2*) - symcode='[[DT]]' - ;; -sysv5* | sco5v6* | unixware* | OpenUNIX*) - symcode='[[ABDT]]' - ;; -sysv4) - symcode='[[DFNSTU]]' - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -case `$NM -V 2>&1` in -*GNU* | *'with BFD'*) - symcode='[[ABCDGIRSTW]]' ;; -esac - -# Transform an extracted symbol line into a proper C declaration. -# Some systems (esp. on ia64) link data and code symbols differently, -# so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" - -# Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" - -# Handle CRLF in mingw tool chain -opt_cr= -case $build_os in -mingw*) - opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# Try without a prefix underscore, then with it. -for ac_symprfx in "" "_"; do - - # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. - symxfrm="\\1 $ac_symprfx\\2 \\2" - - # Write the raw and C identifiers. - if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Fake it for dumpbin and say T for any non-static function - # and D for any global variable. - # Also find C++ and __fastcall symbols from MSVC++, - # which start with @ or ?. - lt_cv_sys_global_symbol_pipe="$AWK ['"\ -" {last_section=section; section=\$ 3};"\ -" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ -" \$ 0!~/External *\|/{next};"\ -" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ -" {if(hide[section]) next};"\ -" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ -" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ -" s[1]~/^[@?]/{print s[1], s[1]; next};"\ -" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ -" ' prfx=^$ac_symprfx]" - else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" - fi - - # Check to see that the pipe works correctly. - pipe_works=no - - rm -f conftest* - cat > conftest.$ac_ext <<_LT_EOF -#ifdef __cplusplus -extern "C" { -#endif -char nm_test_var; -void nm_test_func(void); -void nm_test_func(void){} -#ifdef __cplusplus -} -#endif -int main(){nm_test_var='a';nm_test_func();return(0);} -_LT_EOF - - if AC_TRY_EVAL(ac_compile); then - # Now try to grab the symbols. - nlist=conftest.nm - if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if $GREP ' nm_test_var$' "$nlist" >/dev/null; then - if $GREP ' nm_test_func$' "$nlist" >/dev/null; then - cat <<_LT_EOF > conftest.$ac_ext -#ifdef __cplusplus -extern "C" { -#endif - -_LT_EOF - # Now generate the symbol file. - eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' - - cat <<_LT_EOF >> conftest.$ac_ext - -/* The mapping between symbol names and symbols. */ -const struct { - const char *name; - void *address; -} -lt__PROGRAM__LTX_preloaded_symbols[[]] = -{ - { "@PROGRAM@", (void *) 0 }, -_LT_EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext - cat <<\_LT_EOF >> conftest.$ac_ext - {0, (void *) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt__PROGRAM__LTX_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif -_LT_EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - lt_save_LIBS="$LIBS" - lt_save_CFLAGS="$CFLAGS" - LIBS="conftstm.$ac_objext" - CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then - pipe_works=yes - fi - LIBS="$lt_save_LIBS" - CFLAGS="$lt_save_CFLAGS" - else - echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD - fi - else - echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD - cat conftest.$ac_ext >&5 - fi - rm -rf conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done -]) -if test -z "$lt_cv_sys_global_symbol_pipe"; then - lt_cv_sys_global_symbol_to_cdecl= -fi -if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then - AC_MSG_RESULT(failed) -else - AC_MSG_RESULT(ok) -fi - -_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], - [Take the output of nm and produce a listing of raw symbols and C names]) -_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], - [Transform the output of nm in a proper C declaration]) -_LT_DECL([global_symbol_to_c_name_address], - [lt_cv_sys_global_symbol_to_c_name_address], [1], - [Transform the output of nm in a C name address pair]) -_LT_DECL([global_symbol_to_c_name_address_lib_prefix], - [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], - [Transform the output of nm in a C name address pair when lib prefix is needed]) -]) # _LT_CMD_GLOBAL_SYMBOLS - - -# _LT_COMPILER_PIC([TAGNAME]) -# --------------------------- -m4_defun([_LT_COMPILER_PIC], -[m4_require([_LT_TAG_COMPILER])dnl -_LT_TAGVAR(lt_prog_compiler_wl, $1)= -_LT_TAGVAR(lt_prog_compiler_pic, $1)= -_LT_TAGVAR(lt_prog_compiler_static, $1)= - -AC_MSG_CHECKING([for $compiler option to produce PIC]) -m4_if([$1], [CXX], [ - # C++ specific cases for pic, static, wl, etc. - if test "$GXX" = yes; then - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - *djgpp*) - # DJGPP does not support shared libraries at all - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - interix[[3-9]]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - else - case $host_os in - aix[[4-9]]*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - chorus*) - case $cc_basename in - cxch68*) - # Green Hills C++ Compiler - # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" - ;; - esac - ;; - dgux*) - case $cc_basename in - ec++*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - ghcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - freebsd* | dragonfly*) - # FreeBSD uses GNU C++ - ;; - hpux9* | hpux10* | hpux11*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - if test "$host_cpu" != ia64; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - fi - ;; - aCC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - ;; - *) - ;; - esac - ;; - interix*) - # This is c89, which is MS Visual C++ (no shared libs) - # Anyone wants to do a port? - ;; - irix5* | irix6* | nonstopux*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - # CC pic flag -KPIC is the default. - ;; - *) - ;; - esac - ;; - linux* | k*bsd*-gnu) - case $cc_basename in - KCC*) - # KAI C++ Compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - ecpc* ) - # old Intel C++ for x86_64 which still supported -KPIC. - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - icpc* ) - # Intel C++, used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - pgCC* | pgcpp*) - # Portland Group C++ compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - cxx*) - # Compaq C++ - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - xlc* | xlC*) - # IBM XL 8.0 on PPC - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - esac - ;; - esac - ;; - lynxos*) - ;; - m88k*) - ;; - mvs*) - case $cc_basename in - cxx*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' - ;; - *) - ;; - esac - ;; - netbsd* | netbsdelf*-gnu) - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - ;; - RCC*) - # Rational C++ 2.4.1 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - cxx*) - # Digital/Compaq C++ - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - *) - ;; - esac - ;; - psos*) - ;; - solaris*) - case $cc_basename in - CC*) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - gcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - ;; - *) - ;; - esac - ;; - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - lcc*) - # Lucid - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - esac - ;; - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - *) - ;; - esac - ;; - vxworks*) - ;; - *) - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -], -[ - if test "$GCC" = yes; then - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - - interix[[3-9]]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - enable_shared=no - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - - hpux9* | hpux10* | hpux11*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC (with -KPIC) is the default. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - linux* | k*bsd*-gnu) - case $cc_basename in - # old Intel for x86_64 which still supported -KPIC. - ecc*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - # icc used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - icc* | ifort*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - # Lahey Fortran 8.1. - lf95*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' - _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' - ;; - pgcc* | pgf77* | pgf90* | pgf95*) - # Portland Group compilers (*not* the Pentium gcc compiler, - # which looks to be a dead project) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - ccc*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All Alpha code is PIC. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - xl*) - # IBM XL C 8.0/Fortran 10.1 on PPC - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C 5.9 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - ;; - *Sun\ F*) - # Sun Fortran 8.3 passes all unrecognized flags to the linker - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='' - ;; - esac - ;; - esac - ;; - - newsos6) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - - osf3* | osf4* | osf5*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All OSF/1 code is PIC. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - rdos*) - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - solaris*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - case $cc_basename in - f77* | f90* | f95*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; - *) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; - esac - ;; - - sunos4*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - unicos*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - - uts4*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - *) - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -]) -case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" - ;; -esac -AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) -_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], - [How to pass a linker flag through the compiler]) - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then - _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], - [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], - [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], - [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in - "" | " "*) ;; - *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; - esac], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) -fi -_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], - [Additional compiler flags for building library objects]) - -# -# Check to make sure the static flag actually works. -# -wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" -_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], - _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), - $lt_tmp_static_flag, - [], - [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) -_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], - [Compiler flag to prevent dynamic linking]) -])# _LT_COMPILER_PIC - - -# _LT_LINKER_SHLIBS([TAGNAME]) -# ---------------------------- -# See if the linker supports building shared libraries. -m4_defun([_LT_LINKER_SHLIBS], -[AC_REQUIRE([LT_PATH_LD])dnl -AC_REQUIRE([LT_PATH_NM])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl -m4_require([_LT_TAG_COMPILER])dnl -AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) -m4_if([$1], [CXX], [ - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - case $host_os in - aix[[4-9]]*) - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - else - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - fi - ;; - pw32*) - _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" - ;; - cygwin* | mingw* | cegcc*) - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' - ;; - linux* | k*bsd*-gnu) - _LT_TAGVAR(link_all_deplibs, $1)=no - ;; - *) - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - ;; - esac - _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] -], [ - runpath_var= - _LT_TAGVAR(allow_undefined_flag, $1)= - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(archive_cmds, $1)= - _LT_TAGVAR(archive_expsym_cmds, $1)= - _LT_TAGVAR(compiler_needs_object, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - _LT_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(hardcode_automatic, $1)=no - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= - _LT_TAGVAR(hardcode_libdir_separator, $1)= - _LT_TAGVAR(hardcode_minus_L, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_TAGVAR(inherit_rpath, $1)=no - _LT_TAGVAR(link_all_deplibs, $1)=unknown - _LT_TAGVAR(module_cmds, $1)= - _LT_TAGVAR(module_expsym_cmds, $1)= - _LT_TAGVAR(old_archive_from_new_cmds, $1)= - _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= - _LT_TAGVAR(thread_safe_flag_spec, $1)= - _LT_TAGVAR(whole_archive_flag_spec, $1)= - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - _LT_TAGVAR(include_expsyms, $1)= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. - _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - # Exclude shared library initialization/finalization symbols. -dnl Note also adjust exclude_expsyms for C++ above. - extract_expsyms_cmds= - - case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) - with_gnu_ld=yes - ;; - openbsd*) - with_gnu_ld=no - ;; - esac - - _LT_TAGVAR(ld_shlibs, $1)=yes - if test "$with_gnu_ld" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # Set some defaults for GNU ld with shared library support. These - # are reset later if shared libraries are not supported. Putting them - # here allows them to be overridden if necessary. - runpath_var=LD_RUN_PATH - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - supports_anon_versioning=no - case `$LD -v 2>&1` in - *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - - # See if GNU ld supports shared libraries. - case $host_os in - aix[[3-9]]*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: the GNU linker, at least up to release 2.9.1, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to modify your PATH -*** so that a non-GNU linker is found, and then restart. - -_LT_EOF - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='' - ;; - m68k) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - interix[[3-9]]*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - - gnu* | linux* | tpf* | k*bsd*-gnu) - tmp_diet=no - if test "$host_os" = linux-dietlibc; then - case $cc_basename in - diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) - esac - fi - if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ - && test "$tmp_diet" = no - then - tmp_addflag= - tmp_sharedflag='-shared' - case $cc_basename,$host_cpu in - pgcc*) # Portland Group C compiler - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag' - ;; - pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag -Mnomain' ;; - ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 - tmp_addflag=' -i_dynamic' ;; - efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 - tmp_addflag=' -i_dynamic -nofor_main' ;; - ifc* | ifort*) # Intel Fortran compiler - tmp_addflag=' -nofor_main' ;; - lf95*) # Lahey Fortran 8.1 - _LT_TAGVAR(whole_archive_flag_spec, $1)= - tmp_sharedflag='--shared' ;; - xl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) - tmp_sharedflag='-qmkshrobj' - tmp_addflag= ;; - esac - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) # Sun C 5.9 - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - tmp_sharedflag='-G' ;; - *Sun\ F*) # Sun Fortran 8.3 - tmp_sharedflag='-G' ;; - esac - _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - - case $cc_basename in - xlf*) - # IBM XL Fortran 10.1 on PPC cannot create shared libs itself - _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' - _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' - fi - ;; - esac - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris*) - if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) - case `$LD -v 2>&1` in - *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not -*** reliably create shared libraries on SCO systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.16.91.0.3 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - ;; - *) - # For security reasons, it is highly recommended that you always - # use absolute paths for naming shared libraries, and exclude the - # DT_RUNPATH tag from executables and libraries. But doing so - # requires that you compile everything twice, which is a pain. - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - sunos4*) - _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - - if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then - runpath_var= - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=yes - _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - _LT_TAGVAR(hardcode_direct, $1)=unsupported - fi - ;; - - aix[[4-9]]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - else - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_TAGVAR(archive_cmds, $1)='' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' - - if test "$GCC" = yes; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - _LT_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)= - fi - ;; - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - _LT_TAGVAR(link_all_deplibs, $1)=no - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - _LT_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(allow_undefined_flag, $1)='-berok' - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' - _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - # Exported symbols can be pulled into shared objects from archives - _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds its shared libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='' - ;; - m68k) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - ;; - - bsdi[[45]]*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' - # FIXME: Should let the user specify the lib program. - _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' - _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - ;; - - darwin* | rhapsody*) - _LT_DARWIN_LINKER_FEATURES($1) - ;; - - dgux*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - freebsd1*) - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - hpux9*) - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_direct, $1)=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - ;; - - hpux10*) - if test "$GCC" = yes -a "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - fi - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - fi - ;; - - hpux11*) - if test "$GCC" = yes -a "$with_gnu_ld" = no; then - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - fi - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - case $host_cpu in - hppa*64*|ia64*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - *) - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - # Try to use the -exported_symbol ld option, if it does not - # work, assume that -exports_file does not work either and - # implicitly export all symbols. - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" - AC_LINK_IFELSE(int foo(void) {}, - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' - ) - LDFLAGS="$save_LDFLAGS" - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(inherit_rpath, $1)=yes - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - newsos6) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *nto* | *qnx*) - ;; - - openbsd*) - if test -f /usr/libexec/ld.so; then - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - else - case $host_os in - openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - ;; - esac - fi - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - os2*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - else - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ - $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' - - # Both c and cxx compiler support -rpath directly - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - solaris*) - _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' - if test "$GCC" = yes; then - wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - else - case `$CC -V 2>&1` in - *"Compilers 5.0"*) - wlarc='' - _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' - ;; - *) - wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - ;; - esac - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. GCC discards it without `$wl', - # but is careful enough not to reorder. - # Supported since Solaris 2.6 (maybe 2.5.1?) - if test "$GCC" = yes; then - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' - fi - ;; - esac - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4) - case $host_vendor in - sni) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' - _LT_TAGVAR(hardcode_direct, $1)=no - ;; - motorola) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4.3*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - _LT_TAGVAR(ld_shlibs, $1)=yes - fi - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - uts4*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - - if test x$host_vendor = xsni; then - case $host in - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' - ;; - esac - fi - fi -]) -AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) -test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - -_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld - -_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl -_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl -_LT_DECL([], [extract_expsyms_cmds], [2], - [The commands to extract the exported symbol list from a shared archive]) - -# -# Do we need to explicitly link libc? -# -case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in -x|xyes) - # Assume -lc should be added - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $_LT_TAGVAR(archive_cmds, $1) in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - AC_MSG_CHECKING([whether -lc should be explicitly linked in]) - $RM conftest* - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - if AC_TRY_EVAL(ac_compile) 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) - pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) - _LT_TAGVAR(allow_undefined_flag, $1)= - if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) - then - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - else - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - fi - _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $RM conftest* - AC_MSG_RESULT([$_LT_TAGVAR(archive_cmds_need_lc, $1)]) - ;; - esac - fi - ;; -esac - -_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], - [Whether or not to add -lc for building shared libraries]) -_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], - [enable_shared_with_static_runtimes], [0], - [Whether or not to disallow shared libs when runtime libs are static]) -_LT_TAGDECL([], [export_dynamic_flag_spec], [1], - [Compiler flag to allow reflexive dlopens]) -_LT_TAGDECL([], [whole_archive_flag_spec], [1], - [Compiler flag to generate shared objects directly from archives]) -_LT_TAGDECL([], [compiler_needs_object], [1], - [Whether the compiler copes with passing no objects directly]) -_LT_TAGDECL([], [old_archive_from_new_cmds], [2], - [Create an old-style archive from a shared archive]) -_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], - [Create a temporary old-style archive to link instead of a shared archive]) -_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) -_LT_TAGDECL([], [archive_expsym_cmds], [2]) -_LT_TAGDECL([], [module_cmds], [2], - [Commands used to build a loadable module if different from building - a shared archive.]) -_LT_TAGDECL([], [module_expsym_cmds], [2]) -_LT_TAGDECL([], [with_gnu_ld], [1], - [Whether we are building with GNU ld or not]) -_LT_TAGDECL([], [allow_undefined_flag], [1], - [Flag that allows shared libraries with undefined symbols to be built]) -_LT_TAGDECL([], [no_undefined_flag], [1], - [Flag that enforces no undefined symbols]) -_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], - [Flag to hardcode $libdir into a binary during linking. - This must work even if $libdir does not exist]) -_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1], - [[If ld is used when linking, flag to hardcode $libdir into a binary - during linking. This must work even if $libdir does not exist]]) -_LT_TAGDECL([], [hardcode_libdir_separator], [1], - [Whether we need a single "-rpath" flag with a separated argument]) -_LT_TAGDECL([], [hardcode_direct], [0], - [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes - DIR into the resulting binary]) -_LT_TAGDECL([], [hardcode_direct_absolute], [0], - [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes - DIR into the resulting binary and the resulting library dependency is - "absolute", i.e impossible to change by setting ${shlibpath_var} if the - library is relocated]) -_LT_TAGDECL([], [hardcode_minus_L], [0], - [Set to "yes" if using the -LDIR flag during linking hardcodes DIR - into the resulting binary]) -_LT_TAGDECL([], [hardcode_shlibpath_var], [0], - [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR - into the resulting binary]) -_LT_TAGDECL([], [hardcode_automatic], [0], - [Set to "yes" if building a shared library automatically hardcodes DIR - into the library and all subsequent libraries and executables linked - against it]) -_LT_TAGDECL([], [inherit_rpath], [0], - [Set to yes if linker adds runtime paths of dependent libraries - to runtime path list]) -_LT_TAGDECL([], [link_all_deplibs], [0], - [Whether libtool must link a program against all its dependency libraries]) -_LT_TAGDECL([], [fix_srcfile_path], [1], - [Fix the shell variable $srcfile for the compiler]) -_LT_TAGDECL([], [always_export_symbols], [0], - [Set to "yes" if exported symbols are required]) -_LT_TAGDECL([], [export_symbols_cmds], [2], - [The commands to list exported symbols]) -_LT_TAGDECL([], [exclude_expsyms], [1], - [Symbols that should not be listed in the preloaded symbols]) -_LT_TAGDECL([], [include_expsyms], [1], - [Symbols that must always be exported]) -_LT_TAGDECL([], [prelink_cmds], [2], - [Commands necessary for linking programs (against libraries) with templates]) -_LT_TAGDECL([], [file_list_spec], [1], - [Specify filename containing input files]) -dnl FIXME: Not yet implemented -dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], -dnl [Compiler flag to generate thread safe objects]) -])# _LT_LINKER_SHLIBS - - -# _LT_LANG_C_CONFIG([TAG]) -# ------------------------ -# Ensure that the configuration variables for a C compiler are suitably -# defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to `libtool'. -m4_defun([_LT_LANG_C_CONFIG], -[m4_require([_LT_DECL_EGREP])dnl -lt_save_CC="$CC" -AC_LANG_PUSH(C) - -# Source file extension for C test sources. -ac_ext=c - -# Object file extension for compiled C test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}' - -_LT_TAG_COMPILER -# Save the default compiler, since it gets overwritten when the other -# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. -compiler_DEFAULT=$CC - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -## CAVEAT EMPTOR: -## There is no encapsulation within the following macros, do not change -## the running order or otherwise move them around unless you know exactly -## what you are doing... -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - LT_SYS_DLOPEN_SELF - _LT_CMD_STRIPLIB - - # Report which library types will actually be built - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_CONFIG($1) -fi -AC_LANG_POP -CC="$lt_save_CC" -])# _LT_LANG_C_CONFIG - - -# _LT_PROG_CXX -# ------------ -# Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++ -# compiler, we have our own version here. -m4_defun([_LT_PROG_CXX], -[ -pushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes]) -AC_PROG_CXX -if test -n "$CXX" && ( test "X$CXX" != "Xno" && - ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || - (test "X$CXX" != "Xg++"))) ; then - AC_PROG_CXXCPP -else - _lt_caught_CXX_error=yes -fi -popdef([AC_MSG_ERROR]) -])# _LT_PROG_CXX - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([_LT_PROG_CXX], []) - - -# _LT_LANG_CXX_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for a C++ compiler are suitably -# defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to `libtool'. -m4_defun([_LT_LANG_CXX_CONFIG], -[AC_REQUIRE([_LT_PROG_CXX])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_EGREP])dnl - -AC_LANG_PUSH(C++) -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(compiler_needs_object, $1)=no -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for C++ test sources. -ac_ext=cpp - -# Object file extension for compiled C++ test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the CXX compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_caught_CXX_error" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="int some_variable = 0;" - - # Code to be used in simple link tests - lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC=$CC - lt_save_LD=$LD - lt_save_GCC=$GCC - GCC=$GXX - lt_save_with_gnu_ld=$with_gnu_ld - lt_save_path_LD=$lt_cv_path_LD - if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then - lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx - else - $as_unset lt_cv_prog_gnu_ld - fi - if test -n "${lt_cv_path_LDCXX+set}"; then - lt_cv_path_LD=$lt_cv_path_LDCXX - else - $as_unset lt_cv_path_LD - fi - test -z "${LDCXX+set}" || LD=$LDCXX - CC=${CXX-"c++"} - compiler=$CC - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - - if test -n "$compiler"; then - # We don't want -fno-exception when compiling C++ code, so set the - # no_builtin_flag separately - if test "$GXX" = yes; then - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' - else - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= - fi - - if test "$GXX" = yes; then - # Set up default GNU C++ configuration - - LT_PATH_LD - - # Check if GNU C++ uses GNU ld as the underlying linker, since the - # archiving commands below assume that GNU ld is being used. - if test "$with_gnu_ld" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - - # If archive_cmds runs LD, not CC, wlarc should be empty - # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to - # investigate it a little bit more. (MM) - wlarc='${wl}' - - # ancient GNU ld didn't support --whole-archive et. al. - if eval "`$CC -print-prog-name=ld` --help 2>&1" | - $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - with_gnu_ld=no - wlarc= - - # A generic and very simple default shared library creation - # command for GNU C++ for the case where it uses the native - # linker, instead of GNU ld. If possible, this setting should - # overridden to take advantage of the native linker features on - # the platform it is being used on. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - fi - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' - - else - GXX=no - with_gnu_ld=no - wlarc= - fi - - # PORTME: fill in a description of your system's C++ link characteristics - AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) - _LT_TAGVAR(ld_shlibs, $1)=yes - case $host_os in - aix3*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aix[[4-9]]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) - for ld_flag in $LDFLAGS; do - case $ld_flag in - *-brtl*) - aix_use_runtimelinking=yes - break - ;; - esac - done - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_TAGVAR(archive_cmds, $1)='' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' - - if test "$GXX" = yes; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - _LT_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)= - fi - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to - # export. - _LT_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(allow_undefined_flag, $1)='-berok' - # Determine the default libpath from the value encoded in an empty - # executable. - _LT_SYS_MODULE_PATH_AIX - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' - _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - # Exported symbols can be pulled into shared objects from archives - _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds its shared - # libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - chorus*) - case $cc_basename in - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - darwin* | rhapsody*) - _LT_DARWIN_LINKER_FEATURES($1) - ;; - - dgux*) - case $cc_basename in - ec++*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - ghcx*) - # Green Hills C++ Compiler - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - freebsd[[12]]*) - # C++ shared libraries reported to be fairly broken before - # switch to ELF - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - freebsd-elf*) - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - ;; - - freebsd* | dragonfly*) - # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF - # conventions - _LT_TAGVAR(ld_shlibs, $1)=yes - ;; - - gnu*) - ;; - - hpux9*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aCC*) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' - ;; - *) - if test "$GXX" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - hpux10*|hpux11*) - if test $with_gnu_ld = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - case $host_cpu in - hppa*64*|ia64*) - ;; - *) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - ;; - esac - fi - case $host_cpu in - hppa*64*|ia64*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - *) - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; - esac - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aCC*) - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' - ;; - *) - if test "$GXX" = yes; then - if test $with_gnu_ld = no; then - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - fi - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - interix[[3-9]]*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - irix5* | irix6*) - case $cc_basename in - CC*) - # SGI C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - - # Archives containing C++ object files must be created using - # "CC -ar", where "CC" is the IRIX C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' - ;; - *) - if test "$GXX" = yes; then - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib' - fi - fi - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - esac - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(inherit_rpath, $1)=yes - ;; - - linux* | k*bsd*-gnu) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - - # Archives containing C++ object files must be created using - # "CC -Bstatic", where "CC" is the KAI C++ compiler. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' - ;; - icpc* | ecpc* ) - # Intel C++ - with_gnu_ld=yes - # version 8.0 and above of icpc choke on multiply defined symbols - # if we add $predep_objects and $postdep_objects, however 7.1 and - # earlier do not add the objects themselves. - case `$CC -V 2>&1` in - *"Version 7."*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - *) # Version 8.0 or newer - tmp_idyn= - case $host_cpu in - ia64*) tmp_idyn=' -i_dynamic';; - esac - _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - esac - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - ;; - pgCC* | pgcpp*) - # Portland Group C++ compiler - case `$CC -V` in - *pgCC\ [[1-5]]* | *pgcpp\ [[1-5]]*) - _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ - compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"' - _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ - $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~ - $RANLIB $oldlib' - _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' - ;; - *) # Version 6 will use weak symbols - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' - ;; - cxx*) - # Compaq C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' - - runpath_var=LD_RUN_PATH - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' - ;; - xl*) - # IBM XL 8.0 on PPC, with GNU ld - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - - # Not sure whether something based on - # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 - # would be better. - output_verbose_link_cmd='echo' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' - ;; - esac - ;; - esac - ;; - - lynxos*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - m88k*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - mvs*) - case $cc_basename in - cxx*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' - wlarc= - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - fi - # Workaround some broken pre-1.5 toolchains - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' - ;; - - *nto* | *qnx*) - _LT_TAGVAR(ld_shlibs, $1)=yes - ;; - - openbsd2*) - # C++ shared libraries are fairly broken - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - openbsd*) - if test -f /usr/libexec/ld.so; then - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - fi - output_verbose_link_cmd=echo - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Archives containing C++ object files must be created using - # the KAI C++ compiler. - case $host in - osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; - *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; - esac - ;; - RCC*) - # Rational C++ 2.4.1 - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - cxx*) - case $host in - osf3*) - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - ;; - *) - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ - echo "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~ - $RM $lib.exp' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' - ;; - *) - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - case $host in - osf3*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' - - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - psos*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - lcc*) - # Lucid - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - solaris*) - case $cc_basename in - CC*) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_TAGVAR(archive_cmds_need_lc,$1)=yes - _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. - # Supported since Solaris 2.6 (maybe 2.5.1?) - _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' - ;; - esac - _LT_TAGVAR(link_all_deplibs, $1)=yes - - output_verbose_link_cmd='echo' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' - ;; - gcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - - # The C++ compiler must be used to create the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' - ;; - *) - # GNU C++ compiler with Solaris linker - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' - if $CC --version | $GREP -v '^2\.7' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' - else - # g++ 2.7 appears to require `-G' NOT `-shared' on this - # platform. - _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' - fi - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - ;; - esac - fi - ;; - esac - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var='LD_RUN_PATH' - - case $cc_basename in - CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' - runpath_var='LD_RUN_PATH' - - case $cc_basename in - CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - vxworks*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - - AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) - test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - - _LT_TAGVAR(GCC, $1)="$GXX" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_SYS_HIDDEN_LIBDEPS($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - CC=$lt_save_CC - LDCXX=$LD - LD=$lt_save_LD - GCC=$lt_save_GCC - with_gnu_ld=$lt_save_with_gnu_ld - lt_cv_path_LDCXX=$lt_cv_path_LD - lt_cv_path_LD=$lt_save_path_LD - lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld - lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld -fi # test "$_lt_caught_CXX_error" != yes - -AC_LANG_POP -])# _LT_LANG_CXX_CONFIG - - -# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) -# --------------------------------- -# Figure out "hidden" library dependencies from verbose -# compiler output when linking a shared library. -# Parse the compiler output and extract the necessary -# objects, libraries and library flags. -m4_defun([_LT_SYS_HIDDEN_LIBDEPS], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -# Dependencies to place before and after the object being linked: -_LT_TAGVAR(predep_objects, $1)= -_LT_TAGVAR(postdep_objects, $1)= -_LT_TAGVAR(predeps, $1)= -_LT_TAGVAR(postdeps, $1)= -_LT_TAGVAR(compiler_lib_search_path, $1)= - -dnl we can't use the lt_simple_compile_test_code here, -dnl because it contains code intended for an executable, -dnl not a library. It's possible we should let each -dnl tag define a new lt_????_link_test_code variable, -dnl but it's only used here... -m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF -int a; -void foo (void) { a = 0; } -_LT_EOF -], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF -class Foo -{ -public: - Foo (void) { a = 0; } -private: - int a; -}; -_LT_EOF -], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF - subroutine foo - implicit none - integer*4 a - a=0 - return - end -_LT_EOF -], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF - subroutine foo - implicit none - integer a - a=0 - return - end -_LT_EOF -], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF -public class foo { - private int a; - public void bar (void) { - a = 0; - } -}; -_LT_EOF -]) -dnl Parse the compiler output and extract the necessary -dnl objects, libraries and library flags. -if AC_TRY_EVAL(ac_compile); then - # Parse the compiler output and extract the necessary - # objects, libraries and library flags. - - # Sentinel used to keep track of whether or not we are before - # the conftest object file. - pre_test_object_deps_done=no - - for p in `eval "$output_verbose_link_cmd"`; do - case $p in - - -L* | -R* | -l*) - # Some compilers place space between "-{L,R}" and the path. - # Remove the space. - if test $p = "-L" || - test $p = "-R"; then - prev=$p - continue - else - prev= - fi - - if test "$pre_test_object_deps_done" = no; then - case $p in - -L* | -R*) - # Internal compiler library paths should come after those - # provided the user. The postdeps already come after the - # user supplied libs so there is no need to process them. - if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then - _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" - else - _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" - fi - ;; - # The "-l" case would never come before the object being - # linked, so don't bother handling this case. - esac - else - if test -z "$_LT_TAGVAR(postdeps, $1)"; then - _LT_TAGVAR(postdeps, $1)="${prev}${p}" - else - _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" - fi - fi - ;; - - *.$objext) - # This assumes that the test object file only shows up - # once in the compiler output. - if test "$p" = "conftest.$objext"; then - pre_test_object_deps_done=yes - continue - fi - - if test "$pre_test_object_deps_done" = no; then - if test -z "$_LT_TAGVAR(predep_objects, $1)"; then - _LT_TAGVAR(predep_objects, $1)="$p" - else - _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" - fi - else - if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then - _LT_TAGVAR(postdep_objects, $1)="$p" - else - _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" - fi - fi - ;; - - *) ;; # Ignore the rest. - - esac - done - - # Clean up. - rm -f a.out a.exe -else - echo "libtool.m4: error: problem compiling $1 test program" -fi - -$RM -f confest.$objext - -# PORTME: override above test on systems where it is broken -m4_if([$1], [CXX], -[case $host_os in -interix[[3-9]]*) - # Interix 3.5 installs completely hosed .la files for C++, so rather than - # hack all around it, let's just trust "g++" to DTRT. - _LT_TAGVAR(predep_objects,$1)= - _LT_TAGVAR(postdep_objects,$1)= - _LT_TAGVAR(postdeps,$1)= - ;; - -linux*) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - if test "$solaris_use_stlport4" != yes; then - _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' - fi - ;; - esac - ;; - -solaris*) - case $cc_basename in - CC*) - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - # Adding this requires a known-good setup of shared libraries for - # Sun compiler versions before 5.6, else PIC objects from an old - # archive will be linked into the output, leading to subtle bugs. - if test "$solaris_use_stlport4" != yes; then - _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' - fi - ;; - esac - ;; -esac -]) - -case " $_LT_TAGVAR(postdeps, $1) " in -*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; -esac - _LT_TAGVAR(compiler_lib_search_dirs, $1)= -if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then - _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` -fi -_LT_TAGDECL([], [compiler_lib_search_dirs], [1], - [The directories searched by this compiler when creating a shared library]) -_LT_TAGDECL([], [predep_objects], [1], - [Dependencies to place before and after the objects being linked to - create a shared library]) -_LT_TAGDECL([], [postdep_objects], [1]) -_LT_TAGDECL([], [predeps], [1]) -_LT_TAGDECL([], [postdeps], [1]) -_LT_TAGDECL([], [compiler_lib_search_path], [1], - [The library search path used internally by the compiler when linking - a shared library]) -])# _LT_SYS_HIDDEN_LIBDEPS - - -# _LT_PROG_F77 -# ------------ -# Since AC_PROG_F77 is broken, in that it returns the empty string -# if there is no fortran compiler, we have our own version here. -m4_defun([_LT_PROG_F77], -[ -pushdef([AC_MSG_ERROR], [_lt_disable_F77=yes]) -AC_PROG_F77 -if test -z "$F77" || test "X$F77" = "Xno"; then - _lt_disable_F77=yes -fi -popdef([AC_MSG_ERROR]) -])# _LT_PROG_F77 - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([_LT_PROG_F77], []) - - -# _LT_LANG_F77_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for a Fortran 77 compiler are -# suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_F77_CONFIG], -[AC_REQUIRE([_LT_PROG_F77])dnl -AC_LANG_PUSH(Fortran 77) - -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for f77 test sources. -ac_ext=f - -# Object file extension for compiled f77 test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the F77 compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_disable_F77" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="\ - subroutine t - return - end -" - - # Code to be used in simple link tests - lt_simple_link_test_code="\ - program t - end -" - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC="$CC" - lt_save_GCC=$GCC - CC=${F77-"f77"} - compiler=$CC - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - GCC=$G77 - if test -n "$compiler"; then - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_TAGVAR(GCC, $1)="$G77" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - GCC=$lt_save_GCC - CC="$lt_save_CC" -fi # test "$_lt_disable_F77" != yes - -AC_LANG_POP -])# _LT_LANG_F77_CONFIG - - -# _LT_PROG_FC -# ----------- -# Since AC_PROG_FC is broken, in that it returns the empty string -# if there is no fortran compiler, we have our own version here. -m4_defun([_LT_PROG_FC], -[ -pushdef([AC_MSG_ERROR], [_lt_disable_FC=yes]) -AC_PROG_FC -if test -z "$FC" || test "X$FC" = "Xno"; then - _lt_disable_FC=yes -fi -popdef([AC_MSG_ERROR]) -])# _LT_PROG_FC - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([_LT_PROG_FC], []) - - -# _LT_LANG_FC_CONFIG([TAG]) -# ------------------------- -# Ensure that the configuration variables for a Fortran compiler are -# suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_FC_CONFIG], -[AC_REQUIRE([_LT_PROG_FC])dnl -AC_LANG_PUSH(Fortran) - -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for fc test sources. -ac_ext=${ac_fc_srcext-f} - -# Object file extension for compiled fc test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the FC compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_disable_FC" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="\ - subroutine t - return - end -" - - # Code to be used in simple link tests - lt_simple_link_test_code="\ - program t - end -" - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC="$CC" - lt_save_GCC=$GCC - CC=${FC-"f95"} - compiler=$CC - GCC=$ac_cv_fc_compiler_gnu - - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - - if test -n "$compiler"; then - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_SYS_HIDDEN_LIBDEPS($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - GCC=$lt_save_GCC - CC="$lt_save_CC" -fi # test "$_lt_disable_FC" != yes - -AC_LANG_POP -])# _LT_LANG_FC_CONFIG - - -# _LT_LANG_GCJ_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for the GNU Java Compiler compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_GCJ_CONFIG], -[AC_REQUIRE([LT_PROG_GCJ])dnl -AC_LANG_SAVE - -# Source file extension for Java test sources. -ac_ext=java - -# Object file extension for compiled Java test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="class foo {}" - -# Code to be used in simple link tests -lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC="$CC" -lt_save_GCC=$GCC -GCC=yes -CC=${GCJ-"gcj"} -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_TAGVAR(LD, $1)="$LD" -_LT_CC_BASENAME([$compiler]) - -# GCJ did not exist at the time GCC didn't implicitly link libc in. -_LT_TAGVAR(archive_cmds_need_lc, $1)=no - -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds - -## CAVEAT EMPTOR: -## There is no encapsulation within the following macros, do not change -## the running order or otherwise move them around unless you know exactly -## what you are doing... -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) -fi - -AC_LANG_RESTORE - -GCC=$lt_save_GCC -CC="$lt_save_CC" -])# _LT_LANG_GCJ_CONFIG - - -# _LT_LANG_RC_CONFIG([TAG]) -# ------------------------- -# Ensure that the configuration variables for the Windows resource compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_RC_CONFIG], -[AC_REQUIRE([LT_PROG_RC])dnl -AC_LANG_SAVE - -# Source file extension for RC test sources. -ac_ext=rc - -# Object file extension for compiled RC test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' - -# Code to be used in simple link tests -lt_simple_link_test_code="$lt_simple_compile_test_code" - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC="$CC" -lt_save_GCC=$GCC -GCC= -CC=${RC-"windres"} -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_CC_BASENAME([$compiler]) -_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes - -if test -n "$compiler"; then - : - _LT_CONFIG($1) -fi - -GCC=$lt_save_GCC -AC_LANG_RESTORE -CC="$lt_save_CC" -])# _LT_LANG_RC_CONFIG - - -# LT_PROG_GCJ -# ----------- -AC_DEFUN([LT_PROG_GCJ], -[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], - [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], - [AC_CHECK_TOOL(GCJ, gcj,) - test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" - AC_SUBST(GCJFLAGS)])])[]dnl -]) - -# Old name: -AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_GCJ], []) - - -# LT_PROG_RC -# ---------- -AC_DEFUN([LT_PROG_RC], -[AC_CHECK_TOOL(RC, windres,) -]) - -# Old name: -AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_RC], []) - - -# _LT_DECL_EGREP -# -------------- -# If we don't have a new enough Autoconf to choose the best grep -# available, choose the one first in the user's PATH. -m4_defun([_LT_DECL_EGREP], -[AC_REQUIRE([AC_PROG_EGREP])dnl -AC_REQUIRE([AC_PROG_FGREP])dnl -test -z "$GREP" && GREP=grep -_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) -_LT_DECL([], [EGREP], [1], [An ERE matcher]) -_LT_DECL([], [FGREP], [1], [A literal string matcher]) -dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too -AC_SUBST([GREP]) -]) - - -# _LT_DECL_OBJDUMP -# -------------- -# If we don't have a new enough Autoconf to choose the best objdump -# available, choose the one first in the user's PATH. -m4_defun([_LT_DECL_OBJDUMP], -[AC_CHECK_TOOL(OBJDUMP, objdump, false) -test -z "$OBJDUMP" && OBJDUMP=objdump -_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) -AC_SUBST([OBJDUMP]) -]) - - -# _LT_DECL_SED -# ------------ -# Check for a fully-functional sed program, that truncates -# as few characters as possible. Prefer GNU sed if found. -m4_defun([_LT_DECL_SED], -[AC_PROG_SED -test -z "$SED" && SED=sed -Xsed="$SED -e 1s/^X//" -_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) -_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], - [Sed that helps us avoid accidentally triggering echo(1) options like -n]) -])# _LT_DECL_SED - -m4_ifndef([AC_PROG_SED], [ -############################################################ -# NOTE: This macro has been submitted for inclusion into # -# GNU Autoconf as AC_PROG_SED. When it is available in # -# a released version of Autoconf we should remove this # -# macro and use it instead. # -############################################################ - -m4_defun([AC_PROG_SED], -[AC_MSG_CHECKING([for a sed that does not truncate output]) -AC_CACHE_VAL(lt_cv_path_SED, -[# Loop through the user's path and test for sed and gsed. -# Then use that list of sed's as ones to test for truncation. -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for lt_ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then - lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" - fi - done - done -done -IFS=$as_save_IFS -lt_ac_max=0 -lt_ac_count=0 -# Add /usr/xpg4/bin/sed as it is typically found on Solaris -# along with /bin/sed that truncates output. -for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do - test ! -f $lt_ac_sed && continue - cat /dev/null > conftest.in - lt_ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >conftest.in - # Check for GNU sed and select it if it is found. - if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then - lt_cv_path_SED=$lt_ac_sed - break - fi - while true; do - cat conftest.in conftest.in >conftest.tmp - mv conftest.tmp conftest.in - cp conftest.in conftest.nl - echo >>conftest.nl - $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break - cmp -s conftest.out conftest.nl || break - # 10000 chars as input seems more than enough - test $lt_ac_count -gt 10 && break - lt_ac_count=`expr $lt_ac_count + 1` - if test $lt_ac_count -gt $lt_ac_max; then - lt_ac_max=$lt_ac_count - lt_cv_path_SED=$lt_ac_sed - fi - done -done -]) -SED=$lt_cv_path_SED -AC_SUBST([SED]) -AC_MSG_RESULT([$SED]) -])#AC_PROG_SED -])#m4_ifndef - -# Old name: -AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_SED], []) - - -# _LT_CHECK_SHELL_FEATURES -# ------------------------ -# Find out whether the shell is Bourne or XSI compatible, -# or has some other useful features. -m4_defun([_LT_CHECK_SHELL_FEATURES], -[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) -# Try some XSI features -xsi_shell=no -( _lt_dummy="a/b/c" - test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ - = c,a/b,, \ - && eval 'test $(( 1 + 1 )) -eq 2 \ - && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ - && xsi_shell=yes -AC_MSG_RESULT([$xsi_shell]) -_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) - -AC_MSG_CHECKING([whether the shell understands "+="]) -lt_shell_append=no -( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ - >/dev/null 2>&1 \ - && lt_shell_append=yes -AC_MSG_RESULT([$lt_shell_append]) -_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) - -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - lt_unset=unset -else - lt_unset=false -fi -_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl - -# test EBCDIC or ASCII -case `echo X|tr X '\101'` in - A) # ASCII based system - # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr - lt_SP2NL='tr \040 \012' - lt_NL2SP='tr \015\012 \040\040' - ;; - *) # EBCDIC based system - lt_SP2NL='tr \100 \n' - lt_NL2SP='tr \r\n \100\100' - ;; -esac -_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl -_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl -])# _LT_CHECK_SHELL_FEATURES - - -# _LT_PROG_XSI_SHELLFNS -# --------------------- -# Bourne and XSI compatible variants of some useful shell functions. -m4_defun([_LT_PROG_XSI_SHELLFNS], -[case $xsi_shell in - yes) - cat << \_LT_EOF >> "$cfgfile" - -# func_dirname file append nondir_replacement -# Compute the dirname of FILE. If nonempty, add APPEND to the result, -# otherwise set result to NONDIR_REPLACEMENT. -func_dirname () -{ - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac -} - -# func_basename file -func_basename () -{ - func_basename_result="${1##*/}" -} - -# func_dirname_and_basename file append nondir_replacement -# perform func_basename and func_dirname in a single function -# call: -# dirname: Compute the dirname of FILE. If nonempty, -# add APPEND to the result, otherwise set result -# to NONDIR_REPLACEMENT. -# value returned in "$func_dirname_result" -# basename: Compute filename of FILE. -# value retuned in "$func_basename_result" -# Implementation must be kept synchronized with func_dirname -# and func_basename. For efficiency, we do not delegate to -# those functions but instead duplicate the functionality here. -func_dirname_and_basename () -{ - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac - func_basename_result="${1##*/}" -} - -# func_stripname prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -func_stripname () -{ - # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are - # positional parameters, so assign one to ordinary parameter first. - func_stripname_result=${3} - func_stripname_result=${func_stripname_result#"${1}"} - func_stripname_result=${func_stripname_result%"${2}"} -} - -# func_opt_split -func_opt_split () -{ - func_opt_split_opt=${1%%=*} - func_opt_split_arg=${1#*=} -} - -# func_lo2o object -func_lo2o () -{ - case ${1} in - *.lo) func_lo2o_result=${1%.lo}.${objext} ;; - *) func_lo2o_result=${1} ;; - esac -} - -# func_xform libobj-or-source -func_xform () -{ - func_xform_result=${1%.*}.lo -} - -# func_arith arithmetic-term... -func_arith () -{ - func_arith_result=$(( $[*] )) -} - -# func_len string -# STRING may not start with a hyphen. -func_len () -{ - func_len_result=${#1} -} - -_LT_EOF - ;; - *) # Bourne compatible functions. - cat << \_LT_EOF >> "$cfgfile" - -# func_dirname file append nondir_replacement -# Compute the dirname of FILE. If nonempty, add APPEND to the result, -# otherwise set result to NONDIR_REPLACEMENT. -func_dirname () -{ - # Extract subdirectory from the argument. - func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` - if test "X$func_dirname_result" = "X${1}"; then - func_dirname_result="${3}" - else - func_dirname_result="$func_dirname_result${2}" - fi -} - -# func_basename file -func_basename () -{ - func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` -} - -dnl func_dirname_and_basename -dnl A portable version of this function is already defined in general.m4sh -dnl so there is no need for it here. - -# func_stripname prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -# func_strip_suffix prefix name -func_stripname () -{ - case ${2} in - .*) func_stripname_result=`$ECHO "X${3}" \ - | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "X${3}" \ - | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; - esac -} - -# sed scripts: -my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q' -my_sed_long_arg='1s/^-[[^=]]*=//' - -# func_opt_split -func_opt_split () -{ - func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` - func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` -} - -# func_lo2o object -func_lo2o () -{ - func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` -} - -# func_xform libobj-or-source -func_xform () -{ - func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'` -} - -# func_arith arithmetic-term... -func_arith () -{ - func_arith_result=`expr "$[@]"` -} - -# func_len string -# STRING may not start with a hyphen. -func_len () -{ - func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len` -} - -_LT_EOF -esac - -case $lt_shell_append in - yes) - cat << \_LT_EOF >> "$cfgfile" - -# func_append var value -# Append VALUE to the end of shell variable VAR. -func_append () -{ - eval "$[1]+=\$[2]" -} -_LT_EOF - ;; - *) - cat << \_LT_EOF >> "$cfgfile" - -# func_append var value -# Append VALUE to the end of shell variable VAR. -func_append () -{ - eval "$[1]=\$$[1]\$[2]" -} - -_LT_EOF - ;; - esac -]) diff --git a/config/ltoptions.m4 b/config/ltoptions.m4 deleted file mode 100644 index 34151a3..0000000 --- a/config/ltoptions.m4 +++ /dev/null @@ -1,368 +0,0 @@ -# Helper functions for option handling. -*- Autoconf -*- -# -# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. -# Written by Gary V. Vaughan, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 6 ltoptions.m4 - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) - - -# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) -# ------------------------------------------ -m4_define([_LT_MANGLE_OPTION], -[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) - - -# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) -# --------------------------------------- -# Set option OPTION-NAME for macro MACRO-NAME, and if there is a -# matching handler defined, dispatch to it. Other OPTION-NAMEs are -# saved as a flag. -m4_define([_LT_SET_OPTION], -[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl -m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), - _LT_MANGLE_DEFUN([$1], [$2]), - [m4_warning([Unknown $1 option `$2'])])[]dnl -]) - - -# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) -# ------------------------------------------------------------ -# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. -m4_define([_LT_IF_OPTION], -[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) - - -# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) -# ------------------------------------------------------- -# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME -# are set. -m4_define([_LT_UNLESS_OPTIONS], -[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), - [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), - [m4_define([$0_found])])])[]dnl -m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 -])[]dnl -]) - - -# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) -# ---------------------------------------- -# OPTION-LIST is a space-separated list of Libtool options associated -# with MACRO-NAME. If any OPTION has a matching handler declared with -# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about -# the unknown option and exit. -m4_defun([_LT_SET_OPTIONS], -[# Set options -m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), - [_LT_SET_OPTION([$1], _LT_Option)]) - -m4_if([$1],[LT_INIT],[ - dnl - dnl Simply set some default values (i.e off) if boolean options were not - dnl specified: - _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no - ]) - _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no - ]) - dnl - dnl If no reference was made to various pairs of opposing options, then - dnl we run the default mode handler for the pair. For example, if neither - dnl `shared' nor `disable-shared' was passed, we enable building of shared - dnl archives by default: - _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) - _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) - _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) - _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], - [_LT_ENABLE_FAST_INSTALL]) - ]) -])# _LT_SET_OPTIONS - - -## --------------------------------- ## -## Macros to handle LT_INIT options. ## -## --------------------------------- ## - -# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) -# ----------------------------------------- -m4_define([_LT_MANGLE_DEFUN], -[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) - - -# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) -# ----------------------------------------------- -m4_define([LT_OPTION_DEFINE], -[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl -])# LT_OPTION_DEFINE - - -# dlopen -# ------ -LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes -]) - -AU_DEFUN([AC_LIBTOOL_DLOPEN], -[_LT_SET_OPTION([LT_INIT], [dlopen]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `dlopen' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) - - -# win32-dll -# --------- -# Declare package support for building win32 dll's. -LT_OPTION_DEFINE([LT_INIT], [win32-dll], -[enable_win32_dll=yes - -case $host in -*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*) - AC_CHECK_TOOL(AS, as, false) - AC_CHECK_TOOL(DLLTOOL, dlltool, false) - AC_CHECK_TOOL(OBJDUMP, objdump, false) - ;; -esac - -test -z "$AS" && AS=as -_LT_DECL([], [AS], [0], [Assembler program])dnl - -test -z "$DLLTOOL" && DLLTOOL=dlltool -_LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl - -test -z "$OBJDUMP" && OBJDUMP=objdump -_LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl -])# win32-dll - -AU_DEFUN([AC_LIBTOOL_WIN32_DLL], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -_LT_SET_OPTION([LT_INIT], [win32-dll]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `win32-dll' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) - - -# _LT_ENABLE_SHARED([DEFAULT]) -# ---------------------------- -# implement the --enable-shared flag, and supports the `shared' and -# `disable-shared' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -m4_define([_LT_ENABLE_SHARED], -[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([shared], - [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], - [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_shared=yes ;; - no) enable_shared=no ;; - *) - enable_shared=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_shared=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) - - _LT_DECL([build_libtool_libs], [enable_shared], [0], - [Whether or not to build shared libraries]) -])# _LT_ENABLE_SHARED - -LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) - -# Old names: -AC_DEFUN([AC_ENABLE_SHARED], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) -]) - -AC_DEFUN([AC_DISABLE_SHARED], -[_LT_SET_OPTION([LT_INIT], [disable-shared]) -]) - -AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) -AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_ENABLE_SHARED], []) -dnl AC_DEFUN([AM_DISABLE_SHARED], []) - - - -# _LT_ENABLE_STATIC([DEFAULT]) -# ---------------------------- -# implement the --enable-static flag, and support the `static' and -# `disable-static' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -m4_define([_LT_ENABLE_STATIC], -[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([static], - [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], - [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_static=yes ;; - no) enable_static=no ;; - *) - enable_static=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_static=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_static=]_LT_ENABLE_STATIC_DEFAULT) - - _LT_DECL([build_old_libs], [enable_static], [0], - [Whether or not to build static libraries]) -])# _LT_ENABLE_STATIC - -LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) - -# Old names: -AC_DEFUN([AC_ENABLE_STATIC], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) -]) - -AC_DEFUN([AC_DISABLE_STATIC], -[_LT_SET_OPTION([LT_INIT], [disable-static]) -]) - -AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) -AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_ENABLE_STATIC], []) -dnl AC_DEFUN([AM_DISABLE_STATIC], []) - - - -# _LT_ENABLE_FAST_INSTALL([DEFAULT]) -# ---------------------------------- -# implement the --enable-fast-install flag, and support the `fast-install' -# and `disable-fast-install' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -m4_define([_LT_ENABLE_FAST_INSTALL], -[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([fast-install], - [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], - [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_fast_install=yes ;; - no) enable_fast_install=no ;; - *) - enable_fast_install=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_fast_install=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) - -_LT_DECL([fast_install], [enable_fast_install], [0], - [Whether or not to optimize for fast installation])dnl -])# _LT_ENABLE_FAST_INSTALL - -LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) - -# Old names: -AU_DEFUN([AC_ENABLE_FAST_INSTALL], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you put -the `fast-install' option into LT_INIT's first parameter.]) -]) - -AU_DEFUN([AC_DISABLE_FAST_INSTALL], -[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you put -the `disable-fast-install' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) -dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) - - -# _LT_WITH_PIC([MODE]) -# -------------------- -# implement the --with-pic flag, and support the `pic-only' and `no-pic' -# LT_INIT options. -# MODE is either `yes' or `no'. If omitted, it defaults to `both'. -m4_define([_LT_WITH_PIC], -[AC_ARG_WITH([pic], - [AS_HELP_STRING([--with-pic], - [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], - [pic_mode="$withval"], - [pic_mode=default]) - -test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) - -_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl -])# _LT_WITH_PIC - -LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) -LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) - -# Old name: -AU_DEFUN([AC_LIBTOOL_PICMODE], -[_LT_SET_OPTION([LT_INIT], [pic-only]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `pic-only' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) - -## ----------------- ## -## LTDL_INIT Options ## -## ----------------- ## - -m4_define([_LTDL_MODE], []) -LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], - [m4_define([_LTDL_MODE], [nonrecursive])]) -LT_OPTION_DEFINE([LTDL_INIT], [recursive], - [m4_define([_LTDL_MODE], [recursive])]) -LT_OPTION_DEFINE([LTDL_INIT], [subproject], - [m4_define([_LTDL_MODE], [subproject])]) - -m4_define([_LTDL_TYPE], []) -LT_OPTION_DEFINE([LTDL_INIT], [installable], - [m4_define([_LTDL_TYPE], [installable])]) -LT_OPTION_DEFINE([LTDL_INIT], [convenience], - [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/config/ltsugar.m4 b/config/ltsugar.m4 deleted file mode 100644 index 9000a05..0000000 --- a/config/ltsugar.m4 +++ /dev/null @@ -1,123 +0,0 @@ -# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- -# -# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. -# Written by Gary V. Vaughan, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 6 ltsugar.m4 - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) - - -# lt_join(SEP, ARG1, [ARG2...]) -# ----------------------------- -# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their -# associated separator. -# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier -# versions in m4sugar had bugs. -m4_define([lt_join], -[m4_if([$#], [1], [], - [$#], [2], [[$2]], - [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) -m4_define([_lt_join], -[m4_if([$#$2], [2], [], - [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) - - -# lt_car(LIST) -# lt_cdr(LIST) -# ------------ -# Manipulate m4 lists. -# These macros are necessary as long as will still need to support -# Autoconf-2.59 which quotes differently. -m4_define([lt_car], [[$1]]) -m4_define([lt_cdr], -[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], - [$#], 1, [], - [m4_dquote(m4_shift($@))])]) -m4_define([lt_unquote], $1) - - -# lt_append(MACRO-NAME, STRING, [SEPARATOR]) -# ------------------------------------------ -# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. -# Note that neither SEPARATOR nor STRING are expanded; they are appended -# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). -# No SEPARATOR is output if MACRO-NAME was previously undefined (different -# than defined and empty). -# -# This macro is needed until we can rely on Autoconf 2.62, since earlier -# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. -m4_define([lt_append], -[m4_define([$1], - m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) - - - -# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) -# ---------------------------------------------------------- -# Produce a SEP delimited list of all paired combinations of elements of -# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list -# has the form PREFIXmINFIXSUFFIXn. -# Needed until we can rely on m4_combine added in Autoconf 2.62. -m4_define([lt_combine], -[m4_if(m4_eval([$# > 3]), [1], - [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl -[[m4_foreach([_Lt_prefix], [$2], - [m4_foreach([_Lt_suffix], - ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, - [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) - - -# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) -# ----------------------------------------------------------------------- -# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited -# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. -m4_define([lt_if_append_uniq], -[m4_ifdef([$1], - [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], - [lt_append([$1], [$2], [$3])$4], - [$5])], - [lt_append([$1], [$2], [$3])$4])]) - - -# lt_dict_add(DICT, KEY, VALUE) -# ----------------------------- -m4_define([lt_dict_add], -[m4_define([$1($2)], [$3])]) - - -# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) -# -------------------------------------------- -m4_define([lt_dict_add_subkey], -[m4_define([$1($2:$3)], [$4])]) - - -# lt_dict_fetch(DICT, KEY, [SUBKEY]) -# ---------------------------------- -m4_define([lt_dict_fetch], -[m4_ifval([$3], - m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), - m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) - - -# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) -# ----------------------------------------------------------------- -m4_define([lt_if_dict_fetch], -[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], - [$5], - [$6])]) - - -# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) -# -------------------------------------------------------------- -m4_define([lt_dict_filter], -[m4_if([$5], [], [], - [lt_join(m4_quote(m4_default([$4], [[, ]])), - lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), - [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl -]) diff --git a/config/ltversion.m4 b/config/ltversion.m4 deleted file mode 100644 index b8e154f..0000000 --- a/config/ltversion.m4 +++ /dev/null @@ -1,23 +0,0 @@ -# ltversion.m4 -- version numbers -*- Autoconf -*- -# -# Copyright (C) 2004 Free Software Foundation, Inc. -# Written by Scott James Remnant, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# Generated from ltversion.in. - -# serial 3012 ltversion.m4 -# This file is part of GNU Libtool - -m4_define([LT_PACKAGE_VERSION], [2.2.6]) -m4_define([LT_PACKAGE_REVISION], [1.3012]) - -AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.2.6' -macro_revision='1.3012' -_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) -_LT_DECL(, macro_revision, 0) -]) diff --git a/config/lt~obsolete.m4 b/config/lt~obsolete.m4 deleted file mode 100644 index 637bb20..0000000 --- a/config/lt~obsolete.m4 +++ /dev/null @@ -1,92 +0,0 @@ -# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- -# -# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc. -# Written by Scott James Remnant, 2004. -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 4 lt~obsolete.m4 - -# These exist entirely to fool aclocal when bootstrapping libtool. -# -# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) -# which have later been changed to m4_define as they aren't part of the -# exported API, or moved to Autoconf or Automake where they belong. -# -# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN -# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us -# using a macro with the same name in our local m4/libtool.m4 it'll -# pull the old libtool.m4 in (it doesn't see our shiny new m4_define -# and doesn't know about Autoconf macros at all.) -# -# So we provide this file, which has a silly filename so it's always -# included after everything else. This provides aclocal with the -# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything -# because those macros already exist, or will be overwritten later. -# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. -# -# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. -# Yes, that means every name once taken will need to remain here until -# we give up compatibility with versions before 1.7, at which point -# we need to keep only those names which we still refer to. - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) - -m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) -m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) -m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) -m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) -m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) -m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) -m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) -m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) -m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) -m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) -m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) -m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) -m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) -m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) -m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) -m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) -m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) -m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) -m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) -m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) -m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) -m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) -m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) -m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) -m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) -m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) -m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) -m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) -m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) -m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) -m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) -m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) -m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) -m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) -m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) -m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) -m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) -m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) -m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) -m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) -m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) -m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) -m4_ifndef([AC_LIBTOOL_RC], [AC_DEFUN([AC_LIBTOOL_RC])]) -m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) -m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) -m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) -m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) -m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) -m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) -m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) -m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) diff --git a/src/lib/gsm_receiver_config.cc b/src/lib/gsm_receiver_config.cc new file mode 100644 index 0000000..1d4cf1d --- /dev/null +++ b/src/lib/gsm_receiver_config.cc @@ -0,0 +1,11 @@ +// +// C++ Implementation: gsm_receiver_config +// +// Description: +// +// +// Author: Piotr Krysik , (C) 2009 +// +// Copyright: See COPYING file that comes with this distribution +// +// diff --git a/src/lib/gsm_receiver_config.h b/src/lib/gsm_receiver_config.h new file mode 100644 index 0000000..1d4cf1d --- /dev/null +++ b/src/lib/gsm_receiver_config.h @@ -0,0 +1,11 @@ +// +// C++ Implementation: gsm_receiver_config +// +// Description: +// +// +// Author: Piotr Krysik , (C) 2009 +// +// Copyright: See COPYING file that comes with this distribution +// +// -- cgit v1.2.3 From e09ae11f04130d2666ffb5442cb8ce204e3ac3d8 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Sat, 6 Jun 2009 23:10:21 +0200 Subject: next code cleanup, two functions introduced, should be removed before the end of this branch --- src/lib/Makefile.am | 10 +- src/lib/gsm_constants.h | 9 +- src/lib/gsm_receiver_cf.cc | 272 ++++++++++++++++++++++++----------------- src/lib/gsm_receiver_cf.h | 203 +----------------------------- src/lib/gsm_receiver_config.cc | 63 +++++++++- src/lib/gsm_receiver_config.h | 143 +++++++++++++++++++++- src/lib/viterbi_detector.h | 5 + 7 files changed, 386 insertions(+), 319 deletions(-) diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 78c7511..59504c4 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -66,7 +66,9 @@ _gsm_la_SOURCES = \ gsm.cc libgsmdemod_la_SOURCES = \ - gsm_receiver_cf.cc + gsm_receiver_cf.cc \ + gsm_receiver_config.cc \ + viterbi_detector.cc # magic flags _gsm_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version @@ -87,7 +89,11 @@ gsm.cc gsm.py: $(LOCAL_IFILES) $(ALL_IFILES) # These headers get installed in ${prefix}/include/gnuradio grinclude_HEADERS = \ - gsm_receiver_cf.h + gsm_receiver_cf.h \ + gsm_receiver_config.h + +noinst_HEADERS = \ + viterbi_detector.h # These swig headers get installed in ${prefix}/include/gnuradio/swig swiginclude_HEADERS = \ diff --git a/src/lib/gsm_constants.h b/src/lib/gsm_constants.h index 520ff4f..bc16902 100644 --- a/src/lib/gsm_constants.h +++ b/src/lib/gsm_constants.h @@ -22,7 +22,7 @@ #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 + 5 //first 5 bits of a training sequence +#define TRAIN_POS ( TAIL_BITS + DATA_BITS + 5) //first 5 bits of a training sequence //aren't used for channel impulse response estimation #define TRAIN_BEGINNING 5 #define SAFETY_MARGIN 6 // @@ -41,9 +41,12 @@ static const unsigned char SYNC_BITS[] = { }; 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}; +const unsigned SCH_FRAMES[] = {1,11,21,31,41}; +const unsigned BCCH_FRAMES[] = {2,3,4,5}; //!!the receiver shouldn't care about logical +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}; + //!!channels so this will be removed from this header +const unsigned TEST[] = {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}; // Sync : .+...++.+..+++.++++++.++++++....++.+..+.+.+++.+.+...+..++++..+.. // Diff Encoded Sync: .++..+.+++.+..++.....++.....+...+.+++.+++++..+++++..++.+...+.++. diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index c1280f4..1ee823c 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -39,9 +39,54 @@ #define SYNC_SEARCH_RANGE 30 #define TRAIN_SEARCH_RANGE 40 -//TODO !! - move this methods to some else place +//tutaj umieściłem funkcję która dostaje normalny pakiet + numer +//numer pakietu to numer ramki + numer szczeliny czasowej +//w tym przykładzie po prostu wyrzuca zawartość pakietu na wyjście +//ps. pakiety które nie mają trzech zer na początku zazwyczaj są błędnie odebrane +//ewentulanie innego typu (np. obierasz dummy jako normalny) +void gsm_receiver_cf::przetwarzaj_normalny_pakiet(burst_counter burst_nr, unsigned char * pakiet) +{ + if (burst_nr.get_timeslot_nr() == 6) { + printf("burst = [ "); + for (int i = 0; i < BURST_SIZE ; i++) { + printf(" %d", pakiet[i]); + } + printf("];\n"); +// std::cout << " t2: " << burst_nr.get_t2() << "\n"; + } +} + +// Tutaj ustawia się jekie rodzaje pakietów przypadają na dane stany licznika. +// Licznik ramek składa składa się z trzech części: t3,t2,t1. +// T3 liczy modulo 51, a t2 liczy modulo 26. +// Ja zakładam, że dla danej szczeliny do określenia jaki typ pakietu przypada +// dla danej chwili może być używany tylko jeden z tych liczników. Z dokumentu +// 3gpp 04.03 wynika, że to jest prawda w warstwie fizycznej. +void gsm_receiver_cf::konfiguruj_odbiornik() +{ + // poniżej jest przykład jak się konfiguruje odbiornik + // najpierw mówię mu, że szczelina w szczelinie nr.0 typy pakietów zmieniają się wg. + // licznika t3, czyli modulo 51: + + d_channel_conf.set_multiframe_type(TSC0, multiframe_51); + // tutaj mówię mu, gdzie ma szukać pakietów korekcji częstotliwości FCCH + // w gsm_constants jest definicja: const unsigned FCCH_FRAMES[] = {0, 10, 20, 30, 40}; + // kanał fcch jest nadawany zawsze w w szczelinie nr.0 więc podaję najapierw TSC0 + // potem wartości licznika z tej wcześniej zdefiniowanej tablicy, dalej ilość elementów tablicy, + // a na końcu typ pakietu + // typy są zdefiniowane w gsm_receiver_config.h + d_channel_conf.set_burst_types(TSC0, FCCH_FRAMES, sizeof(FCCH_FRAMES) / sizeof(unsigned), fcch_burst); + + //w plikach z danymi są opisy i tam można znaleźć nr. szczeliny, w której nadawany był głos + //w pierwszym to jest: + //Traffic channel timeslot: 6 + //mogę skonfigurować żeby odbiornik na ślepo szukał tam pakietów normalnych, bez uciekania + //się do dekodowania informacji sterującej: +// d_channel_conf.set_multiframe_type(TSC6, multiframe_26); +// d_channel_conf.set_burst_types(TSC6, TRAFFIC_CHANNEL_F, sizeof(TRAFFIC_CHANNEL_F) / sizeof(unsigned), normal_burst); +} + -// - move it to some else place !! typedef std::list list_float; typedef std::vector vector_float; @@ -71,8 +116,8 @@ gsm_receiver_cf::gsm_receiver_cf(gr_feval_dd *tuner, int osr) d_counter(0), d_fcch_start_pos(0), d_freq_offset(0), - d_state(first_fcch_search), - d_burst_nr(osr) + d_burst_nr(osr), + d_state(first_fcch_search) { int i; gmsk_mapper(SYNC_BITS, N_SYNC_BITS, d_sch_training_seq, gr_complex(0.0, -1.0)); @@ -133,101 +178,106 @@ gsm_receiver_cf::general_work(int noutput_items, break; case sch_search: { - gr_complex chan_imp_resp[CHAN_IMP_RESP_LENGTH*d_OSR]; - int t1, t2, t3; - int burst_start = 0; - unsigned char output_binary[BURST_SIZE]; - - if (find_sch_burst(in, ninput_items[0], out)) { - burst_start = get_sch_chan_imp_resp(in, chan_imp_resp); - detect_burst(in, chan_imp_resp, burst_start, output_binary); - if (decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc) == 0) { - DCOUT("sch burst_start: " << burst_start); - d_burst_nr.set(t1, t2, t3, 0); - DCOUT("bcc: " << d_bcc << " ncc: " << d_ncc << " t1: " << t1 << " t2: " << t2 << " t3: " << t3); - d_channel_conf.set_multiframe_type(TSC0, multiframe_51); - d_channel_conf.set_burst_types(TSC0, FCCH_FRAMES, sizeof(FCCH_FRAMES) / sizeof(unsigned), fcch_burst); - d_channel_conf.set_burst_types(TSC0, SCH_FRAMES, sizeof(SCH_FRAMES) / sizeof(unsigned), sch_burst); - d_channel_conf.set_burst_types(TSC0, BCCH_FRAMES, sizeof(BCCH_FRAMES) / sizeof(unsigned), normal_burst); - d_burst_nr++; - - consume_each(burst_start + BURST_SIZE * d_OSR); - d_state = synchronized; + gr_complex chan_imp_resp[CHAN_IMP_RESP_LENGTH*d_OSR]; + int t1, t2, t3; + int burst_start = 0; + unsigned char output_binary[BURST_SIZE]; + + if (find_sch_burst(in, ninput_items[0], out)) { + burst_start = get_sch_chan_imp_resp(in, chan_imp_resp); + detect_burst(in, chan_imp_resp, burst_start, output_binary); + if (decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc) == 0) { + DCOUT("sch burst_start: " << burst_start); + d_burst_nr.set(t1, t2, t3, 0); + DCOUT("bcc: " << d_bcc << " ncc: " << d_ncc << " t1: " << t1 << " t2: " << t2 << " t3: " << t3); + d_channel_conf.set_multiframe_type(TSC0, multiframe_51); + konfiguruj_odbiornik();//!! + d_channel_conf.set_burst_types(TSC0, FCCH_FRAMES, sizeof(FCCH_FRAMES) / sizeof(unsigned), fcch_burst); + d_channel_conf.set_burst_types(TSC0, SCH_FRAMES, sizeof(SCH_FRAMES) / sizeof(unsigned), sch_burst); + d_channel_conf.set_burst_types(TSC0, BCCH_FRAMES, sizeof(BCCH_FRAMES) / sizeof(unsigned), normal_burst); + d_burst_nr++; + + consume_each(burst_start + BURST_SIZE * d_OSR); + d_state = synchronized; + } else { + d_state = next_fcch_search; + } } else { - d_state = next_fcch_search; + d_state = sch_search; } - } else { - d_state = sch_search; + break; } - break; - } - //in this state receiver is synchronized and it processes bursts according to burst type for given burst number + //in this state receiver is synchronized and it processes bursts according to burst type for given burst number case synchronized: { - gr_complex chan_imp_resp[d_chan_imp_length*d_OSR]; - burst_type b_type = d_channel_conf.get_burst_type(d_burst_nr); - int burst_start; - int offset = 0; - int to_consume = 0; - unsigned char output_binary[BURST_SIZE]; - - switch (b_type) { - case fcch_burst: { - int ii; - int first_sample = ceil((GUARD_PERIOD + 2 * TAIL_BITS) * d_OSR) + 1; - int last_sample = first_sample + USEFUL_BITS * d_OSR; - double phase_sum = 0; - for (ii = first_sample; ii < last_sample; ii++) { - double phase_diff = compute_phase_diff(in[ii], in[ii-1]) - (M_PI / 2) / d_OSR; - phase_sum += phase_diff; - } - double freq_offset = compute_freq_offset(phase_sum, last_sample - first_sample); - if (abs(freq_offset) > FCCH_MAX_FREQ_OFFSET) { - d_freq_offset -= freq_offset; - set_frequency(d_freq_offset); - DCOUT("adjusting frequency, new frequency offset: " << d_freq_offset << "\n"); - } - } - break; + gr_complex chan_imp_resp[d_chan_imp_length*d_OSR]; + burst_type b_type = d_channel_conf.get_burst_type(d_burst_nr); + int burst_start; + int offset = 0; + int to_consume = 0; + unsigned char output_binary[BURST_SIZE]; + + switch (b_type) { + case fcch_burst: { + int ii; + int first_sample = ceil((GUARD_PERIOD + 2 * TAIL_BITS) * d_OSR) + 1; + int last_sample = first_sample + USEFUL_BITS * d_OSR; + double phase_sum = 0; + for (ii = first_sample; ii < last_sample; ii++) { + double phase_diff = compute_phase_diff(in[ii], in[ii-1]) - (M_PI / 2) / d_OSR; + phase_sum += phase_diff; + } + double freq_offset = compute_freq_offset(phase_sum, last_sample - first_sample); + if (abs(freq_offset) > FCCH_MAX_FREQ_OFFSET) { + d_freq_offset -= freq_offset; + set_frequency(d_freq_offset); + DCOUT("adjusting frequency, new frequency offset: " << d_freq_offset << "\n"); + } + } + break; - case sch_burst: { - int t1, t2, t3, d_ncc, d_bcc; - burst_start = get_sch_chan_imp_resp(in, chan_imp_resp); - detect_burst(in, &d_channel_imp_resp[0], burst_start, output_binary); - if (decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc) == 0) { + case sch_burst: { + int t1, t2, t3, d_ncc, d_bcc; + burst_start = get_sch_chan_imp_resp(in, chan_imp_resp); + detect_burst(in, &d_channel_imp_resp[0], burst_start, output_binary); + if (decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc) == 0) { // d_burst_nr.set(t1, t2, t3, 0); - DCOUT("bcc: " << d_bcc << " ncc: " << d_ncc << " t1: " << t1 << " t2: " << t2 << " t3: " << t3); - offset = burst_start - floor((GUARD_PERIOD) * d_OSR); - DCOUT(offset); - to_consume += offset; - } + DCOUT("bcc: " << d_bcc << " ncc: " << d_ncc << " t1: " << t1 << " t2: " << t2 << " t3: " << t3); + offset = burst_start - floor((GUARD_PERIOD) * d_OSR); + DCOUT(offset); + to_consume += offset; + } + } + break; + + case normal_burst: + burst_start = get_norm_chan_imp_resp(in, chan_imp_resp, TRAIN_SEARCH_RANGE, d_bcc); + detect_burst(in, &d_channel_imp_resp[0], burst_start, output_binary); + przetwarzaj_normalny_pakiet(d_burst_nr, output_binary); + break; + + 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: + burst_start = get_norm_chan_imp_resp(in, chan_imp_resp, TRAIN_SEARCH_RANGE, 8); + detect_burst(in, &d_channel_imp_resp[0], burst_start, output_binary); + break; + case empty: + break; } - break; - case normal_burst: - burst_start = get_norm_chan_imp_resp(in, chan_imp_resp, TRAIN_SEARCH_RANGE); - detect_burst(in, &d_channel_imp_resp[0], burst_start, output_binary); - printf("burst = [ "); - for (int i = 0; i < BURST_SIZE ; i++) { - printf(" %d", output_binary[i]); - } - printf("];\n"); - break; - - case rach_burst: - break; - case dummy: - break; - case empty: - break; - } + d_burst_nr++; - d_burst_nr++; - to_consume += TS_BITS * d_OSR + d_burst_nr.get_offset(); - consume_each(to_consume); - } - break; + to_consume += TS_BITS * d_OSR + d_burst_nr.get_offset(); + consume_each(to_consume); + } + break; } return produced_out; @@ -244,7 +294,7 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) int start_pos = -1; float min_phase_diff; float max_phase_diff; - double best_sum; + double best_sum = 0; float lowest_max_min_diff = 99999; int to_consume = 0; @@ -388,7 +438,7 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl int to_consume = 0; bool end = false; bool result = false; - int sample_nr_near_sch_start = d_fcch_start_pos + (FRAME_BITS - SAFETY_MARGIN) * d_OSR; + unsigned sample_nr_near_sch_start = d_fcch_start_pos + (FRAME_BITS - SAFETY_MARGIN) * d_OSR; enum states { start, reach_sch, search_not_finished, sch_found @@ -442,7 +492,7 @@ int gsm_receiver_cf::get_sch_chan_imp_resp(const gr_complex *in, gr_complex * ch int strongest_window_nr; int burst_start = 0; - int chan_imp_resp_center; + int chan_imp_resp_center = 0; float max_correlation = 0; float energy = 0; @@ -564,7 +614,6 @@ inline void gsm_receiver_cf::autocorrelation(const gr_complex * input, gr_comple } //TODO consider use of some generalized function for filtering and placing it in a separate class for signal processing -//funkcja matched filter inline void gsm_receiver_cf::mafi(const gr_complex * input, int input_length, gr_complex * filter, int filter_length, gr_complex * output) { int ii = 0, n, a; @@ -583,7 +632,7 @@ inline void gsm_receiver_cf::mafi(const gr_complex * input, int input_length, gr } } -int gsm_receiver_cf::get_norm_chan_imp_resp(const gr_complex *in, gr_complex * chan_imp_resp, unsigned search_range) +int gsm_receiver_cf::get_norm_chan_imp_resp(const gr_complex *in, gr_complex * chan_imp_resp, unsigned search_range, int bcc) { vector_complex correlation_buffer; vector_float power_buffer; @@ -591,16 +640,16 @@ int gsm_receiver_cf::get_norm_chan_imp_resp(const gr_complex *in, gr_complex * c int strongest_window_nr; int burst_start = 0; - int chan_imp_resp_center; + 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_stop_pos = search_center + d_chan_imp_length * d_OSR + 2*d_OSR; + int search_start_pos = search_center + 1; + 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[d_bcc][TRAIN_BEGINNING], &in[ii], N_TRAIN_BITS - 10); + gr_complex correlation = correlate_sequence(&d_norm_training_seq[bcc][TRAIN_BEGINNING], &in[ii], N_TRAIN_BITS - 10); correlation_buffer.push_back(correlation); power_buffer.push_back(pow(abs(correlation), 2)); @@ -614,27 +663,22 @@ int gsm_receiver_cf::get_norm_chan_imp_resp(const gr_complex *in, gr_complex * c energy = 0; for (int ii = 0; ii < (d_chan_imp_length)*d_OSR; ii++, iter_ii++) { -// for (int ii = 0; ii < (d_chan_imp_length); ii++) { if (iter_ii == power_buffer.end()) { loop_end = true; break; } energy += (*iter_ii); -// iter_ii = iter_ii + d_OSR; } if (loop_end) { break; } iter++; -// std::cout << energy << "\n"; window_energy_buffer.push_back(energy); } -// std::cout << window_energy_buffer.size() << "\n"; strongest_window_nr = max_element(window_energy_buffer.begin(), window_energy_buffer.end()) - window_energy_buffer.begin(); d_channel_imp_resp.clear(); -// strongest_window_nr = 3; max_correlation = 0; for (int ii = 0; ii < (d_chan_imp_length)*d_OSR; ii++) { @@ -646,20 +690,22 @@ int gsm_receiver_cf::get_norm_chan_imp_resp(const gr_complex *in, gr_complex * c 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. + // 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; - burst_start = search_start_pos + chan_imp_resp_center + strongest_window_nr - 66 * d_OSR - 2 * d_OSR + 2; -// COMPENSATING FOR THE 2 Tb DELAY INTRODUCED IN THE GMSK MODULATOR. -// EACH BIT IS STRECHED OVER A PERIOD OF 3 Tb WITH ITS MAXIMUM VALUE -// IN THE LAST BIT PERIOD. HENCE, burst_start IS 2 * OSR -//compute burst start - std::cout << " burst_start: " << (float)burst_start/(float)d_OSR<< " center: " << ((float)(search_start_pos + strongest_window_nr + chan_imp_resp_center))/d_OSR << " stronegest window nr: " << strongest_window_nr << "\n"; + // 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 index e07eb60..8e30b42 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -22,206 +22,12 @@ #ifndef INCLUDED_GSM_RECEIVER_CF_H #define INCLUDED_GSM_RECEIVER_CF_H +#include #include #include #include #include -#include - - -//TODO !! - move this classes to some other place -#include -#include -#include -typedef enum {empty, fcch_burst, sch_burst, normal_burst, rach_burst, dummy} burst_type; -typedef enum {unknown, multiframe_26, multiframe_51} multiframe_type; - -class multiframe_configuration -{ - private: - multiframe_type d_type; - std::vector d_burst_types; - public: - multiframe_configuration() { - d_type = unknown; - fill(d_burst_types.begin(), d_burst_types.end(), empty); - } - -// multiframe_configuration(multiframe_type type, const std::vector & burst_types): -// d_type(type) { -// d_burst_types.resize(burst_types.size()); -// copy(burst_types.begin(), burst_types.end(), d_burst_types.begin()); -// } - -// multiframe_configuration(multiframe_configuration & conf) { -// d_type = conf.d_type; -// copy(conf.d_burst_types.begin(), conf.d_burst_types.end(), d_burst_types.begin()); -// } - - ~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_first_sample_offset; - double d_offset; - public: - burst_counter(int osr): - d_OSR(osr), - d_t1(0), - d_t2(0), - d_t3(0), - d_timeslot_nr(0), - d_first_sample_offset(0), - d_offset(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(0) { - double first_sample_position = (get_frame_nr()*8+timeslot_nr)*TS_BITS; - d_first_sample_offset = first_sample_position - floor(first_sample_position); - } - - 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; - } - - d_first_sample_offset += GUARD_FRACTIONAL * d_OSR; - d_offset = floor(d_first_sample_offset); - d_first_sample_offset = d_first_sample_offset - d_offset; - return (*this); - } - - void 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_first_sample_offset = first_sample_position - floor(first_sample_position); - d_offset = 0; - } - - 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; - } - - unsigned get_offset(){ - return (unsigned)d_offset; - } - //!! - float get_first_sample_offset(){ - return d_first_sample_offset; - } -}; - -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_timeslot_desc(int timeslot_nr, multiframe_configuration conf){ -// d_timeslots_descriptions[timeslot_nr] = conf; -// } - 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); -}; - -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); -} -// move it to some other place !! +#include class gsm_receiver_cf; @@ -245,7 +51,6 @@ gsm_receiver_cf_sptr gsm_make_receiver_cf(gr_feval_dd *tuner, int osr); class gsm_receiver_cf : public gr_block { - private: const int d_OSR; const int d_chan_imp_length; @@ -288,7 +93,9 @@ class gsm_receiver_cf : public gr_block gr_complex correlate_sequence(const gr_complex * sequence, const gr_complex * input_signal, int ninput); inline void autocorrelation(const gr_complex * input, gr_complex * out, int length); inline void mafi(const gr_complex * input, int input_length, gr_complex * filter, int filter_length, gr_complex * output); - int get_norm_chan_imp_resp(const gr_complex *in, gr_complex * chan_imp_resp, unsigned search_range); + int get_norm_chan_imp_resp(const gr_complex *in, gr_complex * chan_imp_resp, unsigned search_range, int bcc); + void przetwarzaj_normalny_pakiet(burst_counter burst_nr, unsigned char * pakiet); + void konfiguruj_odbiornik(); public: ~gsm_receiver_cf(); diff --git a/src/lib/gsm_receiver_config.cc b/src/lib/gsm_receiver_config.cc index 1d4cf1d..1eaff7f 100644 --- a/src/lib/gsm_receiver_config.cc +++ b/src/lib/gsm_receiver_config.cc @@ -1,7 +1,10 @@ // // C++ Implementation: gsm_receiver_config // -// Description: +// 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 // // // Author: Piotr Krysik , (C) 2009 @@ -9,3 +12,61 @@ // Copyright: See COPYING file that comes with this distribution // // +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +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 index 1d4cf1d..9222602 100644 --- a/src/lib/gsm_receiver_config.h +++ b/src/lib/gsm_receiver_config.h @@ -1,11 +1,150 @@ // // C++ Implementation: gsm_receiver_config // -// Description: -// +// 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 // // Author: Piotr Krysik , (C) 2009 // // Copyright: See COPYING file that comes with this distribution // // +#ifndef INCLUDED_GSM_RECEIVER_CONFIG_H +#define INCLUDED_GSM_RECEIVER_CONFIG_H + +#include +#include +#include +#include +#include + +typedef enum {empty, fcch_burst, sch_burst, normal_burst, rach_burst, dummy} burst_type; +typedef enum {unknown, multiframe_26, multiframe_51} multiframe_type; + +class multiframe_configuration +{ + private: + multiframe_type d_type; + std::vector 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; + } + + 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.h b/src/lib/viterbi_detector.h index 9ecb2a0..03f483f 100644 --- a/src/lib/viterbi_detector.h +++ b/src/lib/viterbi_detector.h @@ -53,4 +53,9 @@ ** 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 */ -- cgit v1.2.3 From aaacbc47c96d8474e36203090f11c403510b1c93 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Tue, 9 Jun 2009 12:00:47 +0200 Subject: little change --- src/lib/gsm_receiver_cf.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 1ee823c..3f8602a 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -46,7 +46,7 @@ //ewentulanie innego typu (np. obierasz dummy jako normalny) void gsm_receiver_cf::przetwarzaj_normalny_pakiet(burst_counter burst_nr, unsigned char * pakiet) { - if (burst_nr.get_timeslot_nr() == 6) { + if (burst_nr.get_timeslot_nr() == 0) { printf("burst = [ "); for (int i = 0; i < BURST_SIZE ; i++) { printf(" %d", pakiet[i]); -- cgit v1.2.3 From 5ee04473f323252d8a8df7af8f84f91f07409bab Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Tue, 9 Jun 2009 12:01:40 +0200 Subject: Added Doxyfile --- Doxyfile | 316 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 316 insertions(+) create mode 100644 Doxyfile diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 0000000..b478858 --- /dev/null +++ b/Doxyfile @@ -0,0 +1,316 @@ +# Doxyfile 1.5.6-KDevelop + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = gsm_receiver +PROJECT_NUMBER = 0.0.1 +OUTPUT_DIRECTORY = +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = /home/piotr/ +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_OUTPUT_VHDL = NO +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +IDL_PROPERTY_SUPPORT = YES +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +TYPEDEF_HIDES_STRUCT = NO +SYMBOL_CACHE_SIZE = 0 +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_GROUP_NAMES = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = NO +SHOW_FILES = YES +SHOW_NAMESPACES = YES +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = /home/piotr/MiejscePracy/gsm-receiver +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox \ + *.py \ + *.f90 \ + *.f \ + *.vhd \ + *.vhdl \ + *.C \ + *.CC \ + *.C++ \ + *.II \ + *.I++ \ + *.H \ + *.HH \ + *.H++ \ + *.CS \ + *.PHP \ + *.PHP3 \ + *.M \ + *.MM \ + *.PY \ + *.F90 \ + *.F \ + *.VHD \ + *.VHDL \ + *.C \ + *.H \ + *.tlh \ + *.diff \ + *.patch \ + *.moc \ + *.xpm \ + *.dox +RECURSIVE = yes +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +REFERENCES_LINK_SOURCE = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +GENERATE_DOCSET = NO +DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_BUNDLE_ID = org.doxygen.Project +HTML_DYNAMIC_SECTIONS = NO +CHM_FILE = +HHC_LOCATION = +QTHELP_FILE = +QTHELP_CONFIG = +DOXYGEN2QTHELP_LOC = +GENERATE_CHI = NO +CHM_INDEX_ENCODING = +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NONE +TREEVIEW_WIDTH = 250 +FORMULA_FONTSIZE = 10 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = YES +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = yes +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = gsm_receiver.tag +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +MSCGEN_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +DOT_FONTNAME = FreeSans +DOT_FONTPATH = +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 1000 +DOT_TRANSPARENT = YES +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO -- cgit v1.2.3 From 5849d695cdc49247a4066028c00966894b8f490b Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Tue, 9 Jun 2009 12:03:15 +0200 Subject: turn on autobrief for doxygen --- Doxyfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doxyfile b/Doxyfile index b478858..afb9946 100644 --- a/Doxyfile +++ b/Doxyfile @@ -28,7 +28,7 @@ FULL_PATH_NAMES = YES STRIP_FROM_PATH = /home/piotr/ STRIP_FROM_INC_PATH = SHORT_NAMES = NO -JAVADOC_AUTOBRIEF = NO +JAVADOC_AUTOBRIEF = YES QT_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO DETAILS_AT_TOP = NO -- cgit v1.2.3 From b873c75e3aa74c2c4e8ff17127c89ba06a19aba0 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Thu, 11 Jun 2009 12:13:19 +0200 Subject: doxygen coments - start, changes to sch search process --- src/lib/Assert.h | 2 +- src/lib/gsm_receiver_cf.cc | 27 +++++----- src/lib/gsm_receiver_cf.h | 132 ++++++++++++++++++++++++++++++++++++++------- 3 files changed, 129 insertions(+), 32 deletions(-) diff --git a/src/lib/Assert.h b/src/lib/Assert.h index acfb3f7..dd222b0 100644 --- a/src/lib/Assert.h +++ b/src/lib/Assert.h @@ -26,7 +26,7 @@ #include "stdio.h" #include -#define NDEBUG +// #define NDEBUG /**@name Macros for standard messages. */ //@{ diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 3f8602a..827c600 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -113,8 +113,8 @@ gsm_receiver_cf::gsm_receiver_cf(gr_feval_dd *tuner, int osr) d_OSR(osr), d_chan_imp_length(CHAN_IMP_RESP_LENGTH), d_tuner(tuner), - d_counter(0), - d_fcch_start_pos(0), + d_samples_counter(0), +// d_fcch_start_pos(0), d_freq_offset(0), d_burst_nr(osr), d_state(first_fcch_search) @@ -166,9 +166,10 @@ gsm_receiver_cf::general_work(int noutput_items, case next_fcch_search: prev_freq_offset = d_freq_offset; if (find_fcch_burst(in, ninput_items[0])) { - if (abs(d_freq_offset) > 100) { + if (abs(d_freq_offset) > 100.0) { set_frequency(d_freq_offset); } + d_samples_counter = 0; produced_out = 0; d_state = sch_search; } else { @@ -389,10 +390,11 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) break; case fcch_found: - DCOUT("fcch found on position: " << d_counter + start_pos); +// DCOUT("fcch found on position: " << d_samples_counter + start_pos); + DCOUT("fcch found on position: " << start_pos); to_consume = start_pos + FCCH_HITS_NEEDED * d_OSR + 1; - d_fcch_start_pos = d_counter + start_pos; +// d_fcch_start_pos = d_samples_counter + start_pos; freq_offset = compute_freq_offset(best_sum, FCCH_HITS_NEEDED); d_freq_offset -= freq_offset; DCOUT("freq_offset: " << d_freq_offset); @@ -408,7 +410,7 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) } } - d_counter += to_consume; +// d_samples_counter += to_consume; consume_each(to_consume); return result; @@ -438,8 +440,9 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl int to_consume = 0; bool end = false; bool result = false; - unsigned sample_nr_near_sch_start = d_fcch_start_pos + (FRAME_BITS - SAFETY_MARGIN) * d_OSR; - +// unsigned sample_nr_near_sch_start = d_fcch_start_pos + (FRAME_BITS - SAFETY_MARGIN) * d_OSR; + const unsigned sample_nr_near_sch_start = (FRAME_BITS - SAFETY_MARGIN + TS_BITS) * d_OSR; + enum states { start, reach_sch, search_not_finished, sch_found } sch_search_state; @@ -450,7 +453,7 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl switch (sch_search_state) { case start: - if (d_counter < sample_nr_near_sch_start) { + if (d_samples_counter < sample_nr_near_sch_start) { sch_search_state = reach_sch; } else { sch_search_state = sch_found; @@ -458,8 +461,8 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl break; case reach_sch: - if (d_counter + nitems >= sample_nr_near_sch_start) { - to_consume = sample_nr_near_sch_start - d_counter; + if (d_samples_counter + nitems >= sample_nr_near_sch_start) { + to_consume = sample_nr_near_sch_start - d_samples_counter; } else { to_consume = nitems; } @@ -479,7 +482,7 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl } } - d_counter += to_consume; + d_samples_counter += to_consume; consume_each(to_consume); return result; } diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index 8e30b42..ce05b81 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -1,8 +1,8 @@ /* -*- c++ -*- */ /* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio + * @file + * @author Piotr Krysik + * @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 @@ -34,35 +34,30 @@ class gsm_receiver_cf; typedef boost::shared_ptr gsm_receiver_cf_sptr; typedef std::vector vector_complex; -/*! - * \brief Return a shared_ptr to a new instance of gsm_receiver_cf. - * - * To avoid accidental use of raw pointers, gsm_receiver_cf's - * constructor is private. howto_make_square_ff is the public - * interface for creating new instances. - */ gsm_receiver_cf_sptr gsm_make_receiver_cf(gr_feval_dd *tuner, int osr); -/*! - * \brief Receives fcch +/** 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 - * \sa */ class gsm_receiver_cf : public gr_block { private: + const int d_OSR; const int d_chan_imp_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]; - - gr_feval_dd *d_tuner; - unsigned d_counter; + gr_complex d_sch_training_seq[N_SYNC_BITS]; /// Date: Fri, 12 Jun 2009 09:58:14 +0200 Subject: new comments to gsm_receiver_cf.cc --- src/lib/gsm_receiver_cf.cc | 322 +++++++++++++++++++++++---------------------- 1 file changed, 163 insertions(+), 159 deletions(-) diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 827c600..e624450 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -1,21 +1,21 @@ /* -*- c++ -*- */ /* - * Copyright 2004 Free Software Foundation, Inc. + * @file + * @author Piotr Krysik + * @section LICENSE * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify + * 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. * - * GNU Radio is distributed in the hope that it will be useful, + * 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 GNU Radio; see the file COPYING. If not, write to + * 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. */ @@ -39,7 +39,7 @@ #define SYNC_SEARCH_RANGE 30 #define TRAIN_SEARCH_RANGE 40 -//tutaj umieściłem funkcję która dostaje normalny pakiet + numer +//tutaj umieściłem funkcję która dostaje normalny pakiet + numer //numer pakietu to numer ramki + numer szczeliny czasowej //w tym przykładzie po prostu wyrzuca zawartość pakietu na wyjście //ps. pakiety które nie mają trzech zer na początku zazwyczaj są błędnie odebrane @@ -113,8 +113,8 @@ gsm_receiver_cf::gsm_receiver_cf(gr_feval_dd *tuner, int osr) d_OSR(osr), d_chan_imp_length(CHAN_IMP_RESP_LENGTH), d_tuner(tuner), - d_samples_counter(0), -// d_fcch_start_pos(0), + d_counter(0), + d_fcch_start_pos(0), d_freq_offset(0), d_burst_nr(osr), d_state(first_fcch_search) @@ -134,74 +134,76 @@ gsm_receiver_cf::~gsm_receiver_cf() { } -void gsm_receiver_cf::forecast(int noutput_items, gr_vector_int &ninput_items_required) +void gsm_receiver_cf::forecast(int noutput_items, gr_vector_int &nitems_items_required) { - ninput_items_required[0] = noutput_items * floor((TS_BITS + 2 * GUARD_PERIOD) * d_OSR); + 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 &ninput_items, + gr_vector_int &nitems_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - const gr_complex *in = (const gr_complex *) input_items[0]; + const gr_complex *input = (const gr_complex *) input_items[0]; float *out = (float *) output_items[0]; - int produced_out = 0; - float prev_freq_offset; + 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 + //bootstrapping case first_fcch_search: - if (find_fcch_burst(in, ninput_items[0])) { - set_frequency(d_freq_offset); - produced_out = 0; + 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; + //produced_out = 0; d_state = first_fcch_search; } break; - case next_fcch_search: - prev_freq_offset = d_freq_offset; - if (find_fcch_burst(in, ninput_items[0])) { - if (abs(d_freq_offset) > 100.0) { - set_frequency(d_freq_offset); + case next_fcch_search: { //this state is used because it takes a bunch of buffered samples + //before previous set_frequqency cause change + float prev_freq_offset = d_freq_offset; + 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 } - d_samples_counter = 0; - produced_out = 0; + //produced_out = 0; d_state = sch_search; } else { - produced_out = 0; + //produced_out = 0; d_state = next_fcch_search; } break; - + } case sch_search: { - gr_complex chan_imp_resp[CHAN_IMP_RESP_LENGTH*d_OSR]; + 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 (find_sch_burst(in, ninput_items[0], out)) { - burst_start = get_sch_chan_imp_resp(in, chan_imp_resp); - detect_burst(in, chan_imp_resp, burst_start, output_binary); - if (decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc) == 0) { + if (find_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); - d_burst_nr.set(t1, t2, t3, 0); - DCOUT("bcc: " << d_bcc << " ncc: " << d_ncc << " t1: " << t1 << " t2: " << t2 << " t3: " << t3); - d_channel_conf.set_multiframe_type(TSC0, multiframe_51); - konfiguruj_odbiornik();//!! - d_channel_conf.set_burst_types(TSC0, FCCH_FRAMES, sizeof(FCCH_FRAMES) / sizeof(unsigned), fcch_burst); - d_channel_conf.set_burst_types(TSC0, SCH_FRAMES, sizeof(SCH_FRAMES) / sizeof(unsigned), sch_burst); - d_channel_conf.set_burst_types(TSC0, BCCH_FRAMES, sizeof(BCCH_FRAMES) / sizeof(unsigned), normal_burst); + 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(TSC0, multiframe_51); //in the timeslot nr.0 (TSC0) bursts changes according to t3 counter + konfiguruj_odbiornik();//TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready + d_channel_conf.set_burst_types(TSC0, FCCH_FRAMES, sizeof(FCCH_FRAMES) / sizeof(unsigned), fcch_burst); //tell where to find fcch bursts + d_channel_conf.set_burst_types(TSC0, SCH_FRAMES, sizeof(SCH_FRAMES) / sizeof(unsigned), sch_burst); //sch bursts + d_channel_conf.set_burst_types(TSC0, 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_each(burst_start + BURST_SIZE * d_OSR); //consume samples up to next guard period d_state = synchronized; } else { - d_state = next_fcch_search; + d_state = next_fcch_search; //if there is error in the sch burst go back to fcch search phase } } else { d_state = sch_search; @@ -211,38 +213,32 @@ gsm_receiver_cf::general_work(int noutput_items, //in this state receiver is synchronized and it processes bursts according to burst type for given burst number case synchronized: { - gr_complex chan_imp_resp[d_chan_imp_length*d_OSR]; - burst_type b_type = d_channel_conf.get_burst_type(d_burst_nr); + 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: { - int ii; - int first_sample = ceil((GUARD_PERIOD + 2 * TAIL_BITS) * d_OSR) + 1; - int last_sample = first_sample + USEFUL_BITS * d_OSR; - double phase_sum = 0; - for (ii = first_sample; ii < last_sample; ii++) { - double phase_diff = compute_phase_diff(in[ii], in[ii-1]) - (M_PI / 2) / d_OSR; - phase_sum += phase_diff; - } - double freq_offset = compute_freq_offset(phase_sum, last_sample - first_sample); + const unsigned first_sample = ceil((GUARD_PERIOD + 2 * TAIL_BITS) * d_OSR) + 1; + const unsigned last_sample = first_sample + USEFUL_BITS * d_OSR; + double freq_offset = compute_freq_offset(input, first_sample, last_sample); if (abs(freq_offset) > FCCH_MAX_FREQ_OFFSET) { d_freq_offset -= freq_offset; set_frequency(d_freq_offset); - DCOUT("adjusting frequency, new frequency offset: " << d_freq_offset << "\n"); + DCOUT("Adjusting frequency, new frequency offset: " << d_freq_offset << "\n"); } } break; - - case sch_burst: { + case sch_burst: { int t1, t2, t3, d_ncc, d_bcc; - burst_start = get_sch_chan_imp_resp(in, chan_imp_resp); - detect_burst(in, &d_channel_imp_resp[0], burst_start, output_binary); + burst_start = get_sch_chan_imp_resp(input, &channel_imp_resp[0]); + detect_burst(input, &channel_imp_resp[0], burst_start, output_binary); if (decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc) == 0) { -// d_burst_nr.set(t1, t2, t3, 0); + // d_burst_nr.set(t1, t2, t3, 0); DCOUT("bcc: " << d_bcc << " ncc: " << d_ncc << " t1: " << t1 << " t2: " << t2 << " t3: " << t3); offset = burst_start - floor((GUARD_PERIOD) * d_OSR); DCOUT(offset); @@ -251,10 +247,10 @@ gsm_receiver_cf::general_work(int noutput_items, } break; - case normal_burst: - burst_start = get_norm_chan_imp_resp(in, chan_imp_resp, TRAIN_SEARCH_RANGE, d_bcc); - detect_burst(in, &d_channel_imp_resp[0], burst_start, output_binary); - przetwarzaj_normalny_pakiet(d_burst_nr, output_binary); + case normal_burst: //? + burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], TRAIN_SEARCH_RANGE, d_bcc); + detect_burst(input, &channel_imp_resp[0], burst_start, output_binary); + przetwarzaj_normalny_pakiet(d_burst_nr, output_binary); //TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready break; case rach_burst: @@ -264,18 +260,17 @@ gsm_receiver_cf::general_work(int noutput_items, //to C0 (where sch is) back and forth break; - case dummy: - burst_start = get_norm_chan_imp_resp(in, chan_imp_resp, TRAIN_SEARCH_RANGE, 8); - detect_burst(in, &d_channel_imp_resp[0], burst_start, output_binary); + case dummy: //? + burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], TRAIN_SEARCH_RANGE, 8); + detect_burst(input, &channel_imp_resp[0], burst_start, output_binary); break; case empty: break; } - d_burst_nr++; - + d_burst_nr++; //? - to_consume += TS_BITS * d_OSR + d_burst_nr.get_offset(); + to_consume += TS_BITS * d_OSR + d_burst_nr.get_offset(); //? consume_each(to_consume); } break; @@ -284,29 +279,28 @@ gsm_receiver_cf::general_work(int noutput_items, return produced_out; } -bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) +bool gsm_receiver_cf::find_fcch_burst(const gr_complex *input, const int nitems) { circular_buffer_float phase_diff_buffer(FCCH_BUFFER_SIZE * d_OSR); float phase_diff = 0; gr_complex conjprod; + int start_pos = -1; int hit_count = 0; int miss_count = 0; - int start_pos = -1; 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; - double freq_offset; circular_buffer_float::iterator buffer_iter; + //? enum states { - init, search, found_something, fcch_found, search_fail + init, search, found_something, fcch_found, search_fail //? } fcch_search_state; fcch_search_state = init; @@ -331,7 +325,7 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) to_consume = sample_number; fcch_search_state = search_fail; } else { - phase_diff = compute_phase_diff(in[sample_number], in[sample_number-1]); + phase_diff = compute_phase_diff(input[sample_number], input[sample_number-1]); if (phase_diff > 0) { to_consume = sample_number; @@ -343,65 +337,69 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) break; - case found_something: - if (phase_diff > 0) { - hit_count++; - } else { - miss_count++; - } + case found_something: { - if ((miss_count >= FCCH_MAX_MISSES * d_OSR) && (hit_count <= FCCH_HITS_NEEDED * d_OSR)) { - fcch_search_state = 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)) { - 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; - 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; - } + if (phase_diff > 0) { + hit_count++; + } else { + miss_count++; } - } - sample_number++; + if ((miss_count >= FCCH_MAX_MISSES * d_OSR) && (hit_count <= FCCH_HITS_NEEDED * d_OSR)) { + fcch_search_state = 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)) { + 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; + 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; + } + } + } - if (sample_number >= nitems) { - fcch_search_state = search_fail; - continue; - } + sample_number++; - phase_diff = compute_phase_diff(in[sample_number], in[sample_number-1]); - phase_diff_buffer.push_back(phase_diff); - fcch_search_state = found_something; + if (sample_number >= nitems) { + fcch_search_state = search_fail; + 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_samples_counter + start_pos); - DCOUT("fcch found on position: " << start_pos); - to_consume = start_pos + FCCH_HITS_NEEDED * d_OSR + 1; + case fcch_found: { + DCOUT("fcch found on position: " << d_counter + start_pos); + to_consume = start_pos + FCCH_HITS_NEEDED * d_OSR + 1; -// d_fcch_start_pos = d_samples_counter + start_pos; - freq_offset = compute_freq_offset(best_sum, FCCH_HITS_NEEDED); - d_freq_offset -= freq_offset; - DCOUT("freq_offset: " << d_freq_offset); + d_fcch_start_pos = d_counter + start_pos; - end = true; - result = true; - break; + //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; @@ -410,17 +408,24 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems) } } -// d_samples_counter += to_consume; + d_counter += to_consume; consume_each(to_consume); return result; } -double gsm_receiver_cf::compute_freq_offset(double best_sum, unsigned denominator) +double gsm_receiver_cf::compute_freq_offset(const gr_complex * input, unsigned first_sample, unsigned last_sample) { - float phase_offset, freq_offset; - phase_offset = best_sum / denominator; - freq_offset = phase_offset * 1625000.0 / (12.0 * M_PI); + 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; } @@ -435,14 +440,13 @@ inline float gsm_receiver_cf::compute_phase_diff(gr_complex val1, gr_complex val return gr_fast_atan2f(imag(conjprod), real(conjprod)); } -bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , float *out) +bool gsm_receiver_cf::find_sch_burst(const int nitems) { int to_consume = 0; bool end = false; bool result = false; -// unsigned sample_nr_near_sch_start = d_fcch_start_pos + (FRAME_BITS - SAFETY_MARGIN) * d_OSR; - const unsigned sample_nr_near_sch_start = (FRAME_BITS - SAFETY_MARGIN + TS_BITS) * d_OSR; - + unsigned sample_nr_near_sch_start = d_fcch_start_pos + (FRAME_BITS - SAFETY_MARGIN) * d_OSR; + enum states { start, reach_sch, search_not_finished, sch_found } sch_search_state; @@ -453,7 +457,7 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl switch (sch_search_state) { case start: - if (d_samples_counter < sample_nr_near_sch_start) { + if (d_counter < sample_nr_near_sch_start) { sch_search_state = reach_sch; } else { sch_search_state = sch_found; @@ -461,8 +465,8 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl break; case reach_sch: - if (d_samples_counter + nitems >= sample_nr_near_sch_start) { - to_consume = sample_nr_near_sch_start - d_samples_counter; + if (d_counter + nitems >= sample_nr_near_sch_start) { + to_consume = sample_nr_near_sch_start - d_counter; } else { to_consume = nitems; } @@ -482,12 +486,12 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl } } - d_samples_counter += to_consume; + d_counter += to_consume; consume_each(to_consume); return result; } -int gsm_receiver_cf::get_sch_chan_imp_resp(const gr_complex *in, gr_complex * chan_imp_resp) +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; @@ -500,7 +504,7 @@ int gsm_receiver_cf::get_sch_chan_imp_resp(const gr_complex *in, gr_complex * ch 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], &in[ii], N_SYNC_BITS - 10); + 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)); } @@ -527,7 +531,7 @@ int gsm_receiver_cf::get_sch_chan_imp_resp(const gr_complex *in, gr_complex * ch } strongest_window_nr = max_element(window_energy_buffer.begin(), window_energy_buffer.end()) - window_energy_buffer.begin(); - d_channel_imp_resp.clear(); +// d_channel_imp_resp.clear(); max_correlation = 0; for (int ii = 0; ii < (d_chan_imp_length) *d_OSR; ii++) { @@ -536,7 +540,7 @@ int gsm_receiver_cf::get_sch_chan_imp_resp(const gr_complex *in, gr_complex * ch chan_imp_resp_center = ii; max_correlation = abs(correlation); } - d_channel_imp_resp.push_back(correlation); +// d_channel_imp_resp.push_back(correlation); chan_imp_resp[ii] = correlation; } @@ -544,7 +548,7 @@ int gsm_receiver_cf::get_sch_chan_imp_resp(const gr_complex *in, gr_complex * ch return burst_start; } -void gsm_receiver_cf::detect_burst(const gr_complex * in, gr_complex * chan_imp_resp, int burst_start, unsigned char * output_binary) +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]; @@ -558,7 +562,7 @@ void gsm_receiver_cf::detect_burst(const gr_complex * in, gr_complex * chan_imp_ rhh[ii] = conj(rhh_temp[ii*d_OSR]); } - mafi(&in[burst_start], BURST_SIZE, chan_imp_resp, d_chan_imp_length*d_OSR, filtered_burst); + 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); @@ -568,7 +572,7 @@ void gsm_receiver_cf::detect_burst(const gr_complex * in, gr_complex * chan_imp_ } //TODO consider placing this funtion in a separate class for signal processing -void gsm_receiver_cf::gmsk_mapper(const unsigned char * input, int ninput, gr_complex * gmsk_output, gr_complex start_point) +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); @@ -577,7 +581,7 @@ void gsm_receiver_cf::gmsk_mapper(const unsigned char * input, int ninput, gr_co int previous_symbol = 2 * input[0] - 1; gmsk_output[0] = start_point; - for (int i = 1; i < ninput; i++) { + for (int i = 1; i < nitems; i++) { //change bits representation to NRZ current_symbol = 2 * input[i] - 1; //differentially encode @@ -589,45 +593,45 @@ void gsm_receiver_cf::gmsk_mapper(const unsigned char * input, int ninput, gr_co } //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, const gr_complex * input_signal, int length) +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_signal[sample_number]); + result += sequence[ii] * conj(input[sample_number]); } result = result / gr_complex(length, 0); return result; } -//computes autocorrelation for positive values +//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 length) +inline void gsm_receiver_cf::autocorrelation(const gr_complex * input, gr_complex * out, int nitems) { int i, k; - for (k = length - 1; k >= 0; k--) { + for (k = nitems - 1; k >= 0; k--) { out[k] = gr_complex(0, 0); - for (i = k; i < length; i++) { + 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 input_length, gr_complex * filter, int filter_length, gr_complex * output) +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 < input_length; n++) { + for (n = 0; n < nitems; n++) { a = n * d_OSR; output[n] = 0; ii = 0; while (ii < filter_length) { - if ((a + ii) >= input_length*d_OSR) + if ((a + ii) >= nitems*d_OSR) break; output[n] += input[a+ii] * filter[ii]; ii++; @@ -635,7 +639,7 @@ inline void gsm_receiver_cf::mafi(const gr_complex * input, int input_length, gr } } -int gsm_receiver_cf::get_norm_chan_imp_resp(const gr_complex *in, gr_complex * chan_imp_resp, unsigned search_range, int bcc) +int gsm_receiver_cf::get_norm_chan_imp_resp(const gr_complex *input, gr_complex * chan_imp_resp, unsigned search_range, int bcc) { vector_complex correlation_buffer; vector_float power_buffer; @@ -652,7 +656,7 @@ int gsm_receiver_cf::get_norm_chan_imp_resp(const gr_complex *in, gr_complex * c 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], &in[ii], N_TRAIN_BITS - 10); + 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)); @@ -681,7 +685,7 @@ int gsm_receiver_cf::get_norm_chan_imp_resp(const gr_complex *in, gr_complex * c } strongest_window_nr = max_element(window_energy_buffer.begin(), window_energy_buffer.end()) - window_energy_buffer.begin(); - d_channel_imp_resp.clear(); +// d_channel_imp_resp.clear(); max_correlation = 0; for (int ii = 0; ii < (d_chan_imp_length)*d_OSR; ii++) { @@ -690,7 +694,7 @@ int gsm_receiver_cf::get_norm_chan_imp_resp(const gr_complex *in, gr_complex * c chan_imp_resp_center = ii; max_correlation = abs(correlation); } - d_channel_imp_resp.push_back(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 -- cgit v1.2.3 From 463778d5aafdc222a1b7aec2fbd5509f61e2a498 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Fri, 12 Jun 2009 10:00:28 +0200 Subject: do not include directories with compiled documentation: html latex xml --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 58a5903..91f0ff0 100644 --- a/.gitignore +++ b/.gitignore @@ -19,4 +19,7 @@ compile build *~ autom4te.cache -debug \ No newline at end of file +debug +html +latex +xml -- cgit v1.2.3 From 3fefa82742a92037995f2d217294a1ab5fa30373 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Fri, 12 Jun 2009 10:02:30 +0200 Subject: changed license to GPL3 to be compatible with GNU Radio's license --- COPYING | 912 ++++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 623 insertions(+), 289 deletions(-) diff --git a/COPYING b/COPYING index 623b625..94a9ed0 100644 --- a/COPYING +++ b/COPYING @@ -1,285 +1,626 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. - Preamble + Preamble - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of this License. - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it @@ -287,15 +628,15 @@ free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least +state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) - This program is free software; you can redistribute it and/or modify + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + 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, @@ -304,37 +645,30 @@ the "copyright" line and a pointer to where the full notice is found. 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 - + along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. -- cgit v1.2.3 From d02dec217944d276fda1cb8d6e6d9e4cf4cda096 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Fri, 12 Jun 2009 10:04:21 +0200 Subject: changed licenses in files --- src/lib/gsm.i | 20 ++++++++ src/lib/gsm_receiver_cf.h | 8 ++-- src/lib/gsm_receiver_config.cc | 40 ++++++++++------ src/lib/gsm_receiver_config.h | 39 ++++++++++----- src/lib/viterbi_detector.cc | 106 +++++++++++++++++++++-------------------- src/lib/viterbi_detector.h | 106 +++++++++++++++++++++-------------------- 6 files changed, 184 insertions(+), 135 deletions(-) diff --git a/src/lib/gsm.i b/src/lib/gsm.i index dac7602..dc0be34 100644 --- a/src/lib/gsm.i +++ b/src/lib/gsm.i @@ -1,4 +1,24 @@ /* -*- c++ -*- */ +/* + * @file + * @author Piotr Krysik + * @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 diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index ce05b81..d35e4da 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -2,20 +2,20 @@ /* * @file * @author Piotr Krysik - * @section LICENSE + * @section LICENSE * - * GNU Radio is free software; you can redistribute it and/or modify + * 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. * - * GNU Radio is distributed in the hope that it will be useful, + * 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 GNU Radio; see the file COPYING. If not, write to + * 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. */ diff --git a/src/lib/gsm_receiver_config.cc b/src/lib/gsm_receiver_config.cc index 1eaff7f..44344f7 100644 --- a/src/lib/gsm_receiver_config.cc +++ b/src/lib/gsm_receiver_config.cc @@ -1,17 +1,29 @@ -// -// C++ Implementation: gsm_receiver_config -// -// 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 -// -// -// Author: Piotr Krysik , (C) 2009 -// -// Copyright: See COPYING file that comes with this distribution -// -// +/* -*- c++ -*- */ +/* + * @file + * @author Piotr Krysik + * @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 diff --git a/src/lib/gsm_receiver_config.h b/src/lib/gsm_receiver_config.h index 9222602..ebeedf7 100644 --- a/src/lib/gsm_receiver_config.h +++ b/src/lib/gsm_receiver_config.h @@ -1,16 +1,29 @@ -// -// C++ Implementation: gsm_receiver_config -// -// 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 -// -// Author: Piotr Krysik , (C) 2009 -// -// Copyright: See COPYING file that comes with this distribution -// -// +/* -*- c++ -*- */ +/* + * @file + * @author Piotr Krysik + * @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 diff --git a/src/lib/viterbi_detector.cc b/src/lib/viterbi_detector.cc index 2a2fede..f3445cf 100644 --- a/src/lib/viterbi_detector.cc +++ b/src/lib/viterbi_detector.cc @@ -1,57 +1,59 @@ -/*************************************************************************** - * Copyright (C) 2008 by Piotr Krysik * - * pkrysik@stud.elka.pw.edu.pl * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ +/* -*- c++ -*- */ +/* + * @file + * @author Piotr Krysik + * @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. -*/ + * 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 #include diff --git a/src/lib/viterbi_detector.h b/src/lib/viterbi_detector.h index 03f483f..0360f83 100644 --- a/src/lib/viterbi_detector.h +++ b/src/lib/viterbi_detector.h @@ -1,57 +1,59 @@ -/*************************************************************************** - * Copyright (C) 2008 by Piotr Krysik * - * pkrysik@stud.elka.pw.edu.pl * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ +/* -*- c++ -*- */ +/* + * @file + * @author Piotr Krysik + * @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. -*/ + * 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 -- cgit v1.2.3 From 36d94733571d5dd96fbd941cab3e9c2ca351accc Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Fri, 12 Jun 2009 10:04:37 +0200 Subject: other changes --- Doxyfile | 4 +- src/lib/Assert.h | 2 +- src/lib/gsm.i | 7 -- src/lib/gsm_constants.h | 14 +-- src/lib/gsm_receiver_cf.h | 246 +++++++++++++++++++++++++--------------------- 5 files changed, 144 insertions(+), 129 deletions(-) diff --git a/Doxyfile b/Doxyfile index afb9946..2c5110c 100644 --- a/Doxyfile +++ b/Doxyfile @@ -52,8 +52,8 @@ SYMBOL_CACHE_SIZE = 0 # Build related configuration options #--------------------------------------------------------------------------- EXTRACT_ALL = NO -EXTRACT_PRIVATE = NO -EXTRACT_STATIC = NO +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES EXTRACT_LOCAL_CLASSES = YES EXTRACT_LOCAL_METHODS = NO EXTRACT_ANON_NSPACES = NO diff --git a/src/lib/Assert.h b/src/lib/Assert.h index dd222b0..acfb3f7 100644 --- a/src/lib/Assert.h +++ b/src/lib/Assert.h @@ -26,7 +26,7 @@ #include "stdio.h" #include -// #define NDEBUG +#define NDEBUG /**@name Macros for standard messages. */ //@{ diff --git a/src/lib/gsm.i b/src/lib/gsm.i index dc0be34..9a9e8ea 100644 --- a/src/lib/gsm.i +++ b/src/lib/gsm.i @@ -36,13 +36,6 @@ // ---------------------------------------------------------------- -/* - * First arg is the package prefix. - * Second arg is the name of the class minus the prefix. - * - * This does some behind-the-scenes magic so we can - * access howto_square_ff from python as howto.square_ff - */ GR_SWIG_BLOCK_MAGIC(gsm,receiver_cf); gsm_receiver_cf_sptr gsm_make_receiver_cf ( gr_feval_dd *tuner, int osr); diff --git a/src/lib/gsm_constants.h b/src/lib/gsm_constants.h index bc16902..cf9f059 100644 --- a/src/lib/gsm_constants.h +++ b/src/lib/gsm_constants.h @@ -23,7 +23,7 @@ #define FCCH_POS TAIL_BITS #define SYNC_POS 39 #define TRAIN_POS ( TAIL_BITS + DATA_BITS + 5) //first 5 bits of a training sequence -//aren't used for channel impulse response estimation + //aren't used for channel impulse response estimation #define TRAIN_BEGINNING 5 #define SAFETY_MARGIN 6 // @@ -41,11 +41,11 @@ static const unsigned char SYNC_BITS[] = { }; const unsigned FCCH_FRAMES[] = {0, 10, 20, 30, 40}; -const unsigned SCH_FRAMES[] = {1,11,21,31,41}; +const unsigned SCH_FRAMES[] = {1, 11, 21, 31, 41}; -const unsigned BCCH_FRAMES[] = {2,3,4,5}; //!!the receiver shouldn't care about logical -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}; - //!!channels so this will be removed from this header +const unsigned BCCH_FRAMES[] = {2, 3, 4, 5}; //!!the receiver shouldn't care about logical +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}; +//!!channels so this will be removed from this header const unsigned TEST[] = {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}; // Sync : .+...++.+..+++.++++++.++++++....++.+..+.+.+++.+.+...+..++++..+.. // Diff Encoded Sync: .++..+.+++.+..++.....++.....+...+.+++.+++++..+++++..++.+...+.++. @@ -106,8 +106,8 @@ static const unsigned char dummy_burst[] = { * 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 +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, diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index d35e4da..b937f76 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -37,8 +37,9 @@ typedef std::vector vector_complex; gsm_receiver_cf_sptr gsm_make_receiver_cf(gr_feval_dd *tuner, int osr); /** GSM Receiver GNU Radio block + * * GSM Receiver class supports frequency correction, synchronisation and - * MLSE (Maximum Likelihood Sequence Estimation) estimation of synchronisation + * MLSE (Maximum Likelihood Sequence Estimation) estimation of synchronisation * bursts and normal bursts. * \ingroup block */ @@ -46,148 +47,169 @@ gsm_receiver_cf_sptr gsm_make_receiver_cf(gr_feval_dd *tuner, int osr); class gsm_receiver_cf : public gr_block { private: - - const int d_OSR; - const int d_chan_imp_length; + + /**@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]; /// Date: Fri, 12 Jun 2009 11:36:39 +0200 Subject: new comments to gsm_receiver_cf.cc --- src/lib/gsm_receiver_cf.cc | 194 +++++++++++++++++++++------------------------ 1 file changed, 91 insertions(+), 103 deletions(-) diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index e624450..48be74a 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -35,7 +35,7 @@ #include #include -#define FCCH_BUFFER_SIZE (FCCH_HITS_NEEDED) +// #define FCCH_BUFFER_SIZE () #define SYNC_SEARCH_RANGE 30 #define TRAIN_SEARCH_RANGE 40 @@ -82,8 +82,8 @@ void gsm_receiver_cf::konfiguruj_odbiornik() //Traffic channel timeslot: 6 //mogę skonfigurować żeby odbiornik na ślepo szukał tam pakietów normalnych, bez uciekania //się do dekodowania informacji sterującej: -// d_channel_conf.set_multiframe_type(TSC6, multiframe_26); -// d_channel_conf.set_burst_types(TSC6, TRAFFIC_CHANNEL_F, sizeof(TRAFFIC_CHANNEL_F) / sizeof(unsigned), normal_burst); +// 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), normal_burst); } @@ -148,10 +148,10 @@ gsm_receiver_cf::general_work(int noutput_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 + //probably the gsm receiver will be changed into sink so this variable won't be necessary switch (d_state) { - //bootstrapping + //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 @@ -164,40 +164,40 @@ gsm_receiver_cf::general_work(int noutput_items, break; case next_fcch_search: { //this state is used because it takes a bunch of buffered samples - //before previous set_frequqency cause change - float prev_freq_offset = d_freq_offset; - 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 + //before previous set_frequqency cause change + float prev_freq_offset = d_freq_offset; + 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; } - //produced_out = 0; - d_state = sch_search; - } else { - //produced_out = 0; - d_state = next_fcch_search; + break; } - break; - } case sch_search: { - vector_complex channel_imp_resp(CHAN_IMP_RESP_LENGTH*d_OSR); + 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 (find_sch_burst(nitems_items[0])) { //wait for a SCH burst + 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); + 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(TSC0, multiframe_51); //in the timeslot nr.0 (TSC0) bursts changes according to t3 counter + d_channel_conf.set_multiframe_type(TIMESLOT0, multiframe_51); //in the timeslot nr.0 bursts changes according to t3 counter konfiguruj_odbiornik();//TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready - d_channel_conf.set_burst_types(TSC0, FCCH_FRAMES, sizeof(FCCH_FRAMES) / sizeof(unsigned), fcch_burst); //tell where to find fcch bursts - d_channel_conf.set_burst_types(TSC0, SCH_FRAMES, sizeof(SCH_FRAMES) / sizeof(unsigned), sch_burst); //sch bursts - d_channel_conf.set_burst_types(TSC0, BCCH_FRAMES, sizeof(BCCH_FRAMES) / sizeof(unsigned), normal_burst);//!and maybe normal bursts of the BCCH logical channel + 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 @@ -222,34 +222,34 @@ gsm_receiver_cf::general_work(int noutput_items, 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: { + 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; - double freq_offset = compute_freq_offset(input, first_sample, last_sample); + double freq_offset = compute_freq_offset(input, first_sample, last_sample); //extract frequency offset from it if (abs(freq_offset) > FCCH_MAX_FREQ_OFFSET) { - d_freq_offset -= freq_offset; - set_frequency(d_freq_offset); + d_freq_offset -= freq_offset; //and adjust frequency if it have changed beyond + set_frequency(d_freq_offset); //some limit DCOUT("Adjusting frequency, new frequency offset: " << d_freq_offset << "\n"); } } break; - case sch_burst: { + 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]); - detect_burst(input, &channel_imp_resp[0], burst_start, output_binary); - if (decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc) == 0) { - // d_burst_nr.set(t1, t2, t3, 0); + 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 DCOUT("bcc: " << d_bcc << " ncc: " << d_ncc << " t1: " << t1 << " t2: " << t2 << " t3: " << t3); - offset = burst_start - floor((GUARD_PERIOD) * d_OSR); + 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; + to_consume += offset; //adjust with offset number of samples to be consumed } } break; - case normal_burst: //? - burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], TRAIN_SEARCH_RANGE, d_bcc); - detect_burst(input, &channel_imp_resp[0], burst_start, output_binary); + case normal_burst: //if it's normal burst + burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], TRAIN_SEARCH_RANGE, 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 przetwarzaj_normalny_pakiet(d_burst_nr, output_binary); //TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready break; @@ -260,17 +260,21 @@ gsm_receiver_cf::general_work(int noutput_items, //to C0 (where sch is) back and forth break; - case dummy: //? - burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], TRAIN_SEARCH_RANGE, 8); - detect_burst(input, &channel_imp_resp[0], burst_start, output_binary); - break; - case empty: + case dummy: //if it's dummy + burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], TRAIN_SEARCH_RANGE, 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++; //? + d_burst_nr++; //go to next burst - to_consume += TS_BITS * d_OSR + d_burst_nr.get_offset(); //? + 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; @@ -281,8 +285,8 @@ gsm_receiver_cf::general_work(int noutput_items, bool gsm_receiver_cf::find_fcch_burst(const gr_complex *input, const int nitems) { - circular_buffer_float phase_diff_buffer(FCCH_BUFFER_SIZE * d_OSR); - + 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; @@ -292,23 +296,30 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *input, const int nitems) 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, search, found_something, fcch_found, search_fail //? + 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: + case init: //initialize variables hit_count = 0; miss_count = 0; start_pos = -1; @@ -318,18 +329,20 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *input, const int nitems) break; - case search: + case search: // search for positive samples sample_number++; - if (sample_number > nitems - FCCH_BUFFER_SIZE * d_OSR) { - to_consume = 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 (phase_diff > 0) { //if a positive phase difference was found to_consume = sample_number; - fcch_search_state = found_something; + fcch_search_state = found_something; //switch to state in which searches for FCCH } else { fcch_search_state = search; } @@ -337,18 +350,19 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *input, const int nitems) break; - case found_something: { - + case found_something: {// search for FCCH and the best position of it if (phase_diff > 0) { - hit_count++; + hit_count++; //positive phase differencies increases hits_count } else { - miss_count++; + miss_count++; //negative increases miss_count } if ((miss_count >= FCCH_MAX_MISSES * d_OSR) && (hit_count <= FCCH_HITS_NEEDED * d_OSR)) { - fcch_search_state = init; + //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)) { @@ -360,21 +374,21 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *input, const int nitems) 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; + 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; + best_sum += *buffer_iter - (M_PI / 2) / d_OSR; //store best value of phase offset sum } } } sample_number++; - if (sample_number >= nitems) { - fcch_search_state = search_fail; + if (sample_number >= nitems) { //if there's no single sample left to check + fcch_search_state = search_fail;//FCCH search failed continue; } @@ -440,50 +454,24 @@ inline float gsm_receiver_cf::compute_phase_diff(gr_complex val1, gr_complex val return gr_fast_atan2f(imag(conjprod), real(conjprod)); } -bool gsm_receiver_cf::find_sch_burst(const int nitems) +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 end = false; bool result = false; unsigned sample_nr_near_sch_start = d_fcch_start_pos + (FRAME_BITS - SAFETY_MARGIN) * d_OSR; - enum states { - start, reach_sch, search_not_finished, sch_found - } sch_search_state; - - sch_search_state = start; - - while (!end) { - switch (sch_search_state) { - - case start: - if (d_counter < sample_nr_near_sch_start) { - sch_search_state = reach_sch; - } else { - sch_search_state = sch_found; - } - break; - - case reach_sch: - if (d_counter + nitems >= sample_nr_near_sch_start) { - to_consume = sample_nr_near_sch_start - d_counter; - } else { - to_consume = nitems; - } - sch_search_state = search_not_finished; - break; - - case search_not_finished: - result = false; - end = true; - break; - - case sch_found: - to_consume = 0; - result = true; - end = true; - break; + //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; -- cgit v1.2.3 From 986421483892618223b230078dbcdd958da92404 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Fri, 12 Jun 2009 11:40:15 +0200 Subject: little changes to gsm_constants - added timeslots, removed some comments --- src/lib/Assert.h | 2 +- src/lib/gsm_constants.h | 28 ++++++++++++---------------- src/lib/gsm_receiver_cf.h | 4 ++-- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/lib/Assert.h b/src/lib/Assert.h index acfb3f7..dd222b0 100644 --- a/src/lib/Assert.h +++ b/src/lib/Assert.h @@ -26,7 +26,7 @@ #include "stdio.h" #include -#define NDEBUG +// #define NDEBUG /**@name Macros for standard messages. */ //@{ diff --git a/src/lib/gsm_constants.h b/src/lib/gsm_constants.h index cf9f059..6eecbb1 100644 --- a/src/lib/gsm_constants.h +++ b/src/lib/gsm_constants.h @@ -44,11 +44,9 @@ 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 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}; -//!!channels so this will be removed from this header -const unsigned TEST[] = {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}; -// Sync : .+...++.+..+++.++++++.++++++....++.+..+.+.+++.+.+...+..++++..+.. -// Diff Encoded Sync: .++..+.+++.+..++.....++.....+...+.+++.+++++..+++++..++.+...+.++. +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 @@ -62,6 +60,16 @@ const unsigned TEST[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1 #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}, @@ -130,17 +138,5 @@ static const unsigned char fc_compact_fb[] = { 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 }; -//Diff encoded train_seq -//TSC0: +.++.+++..+...++..++.+++.. -//TSC1: +.+++.++..++...+..++.+++.. -//TSC2: +++...+..++..+++.++...+..+ -//TSC3: +++..+...++.+++..++..+...+ -//TSC4: +..+.++++..+.++....+.++++. -//TSC5: +++.+..++++.+....++.+..+++ -//TSC6: .+++.+....++.+..++++.+.... -//TSC7: ...++...+..++.+++..++...+. -//TSC8: .......................... -//TSC9: ++..+..+++..+..+++..+..+++ - #endif /* INCLUDED_GSM_CONSTANTS_H */ diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index b937f76..ef9a8bb 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -61,7 +61,7 @@ class gsm_receiver_cf : public gr_block /** Countes samples consumed by the receiver * - * It is used in beetween find_fcch_burst and find_sch_burst calls. + * 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. @@ -135,7 +135,7 @@ class gsm_receiver_cf : public gr_block * @param nitems number of samples in the gsm_receiver's buffer * @return true if SCH burst is near, false otherwise */ - bool find_sch_burst(const int nitems); + bool reach_sch_burst(const int nitems); /** Extracts channel impulse response from a SCH burst and computes first sample number of this burst * -- cgit v1.2.3 From 6cf10db5cd610309a9fef840824e1aa5ac9a59f5 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Fri, 12 Jun 2009 12:01:47 +0200 Subject: little update to Makefile.am --- src/lib/Makefile.am | 1 + src/lib/gsm.i | 4 ++-- src/lib/gsm_receiver_cf.cc | 9 ++++----- src/lib/gsm_receiver_cf.h | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 59504c4..91819fa 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -93,6 +93,7 @@ grinclude_HEADERS = \ gsm_receiver_config.h noinst_HEADERS = \ + gsm_constants.h \ viterbi_detector.h # These swig headers get installed in ${prefix}/include/gnuradio/swig diff --git a/src/lib/gsm.i b/src/lib/gsm.i index 9a9e8ea..8c4d79a 100644 --- a/src/lib/gsm.i +++ b/src/lib/gsm.i @@ -25,13 +25,13 @@ %include "exception.i" %import "gnuradio.i" // the common stuff -%include "gsm_constants.h" +/* %include "gsm_constants.h" */ %{ #include "gnuradio_swig_bug_workaround.h" // mandatory bug fix #include "gsm_receiver_cf.h" #include -#include "gsm_constants.h" +/* #include "gsm_constants.h" */ %} // ---------------------------------------------------------------- diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 48be74a..64f7d29 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -35,7 +35,6 @@ #include #include -// #define FCCH_BUFFER_SIZE () #define SYNC_SEARCH_RANGE 30 #define TRAIN_SEARCH_RANGE 40 @@ -44,7 +43,7 @@ //w tym przykładzie po prostu wyrzuca zawartość pakietu na wyjście //ps. pakiety które nie mają trzech zer na początku zazwyczaj są błędnie odebrane //ewentulanie innego typu (np. obierasz dummy jako normalny) -void gsm_receiver_cf::przetwarzaj_normalny_pakiet(burst_counter burst_nr, unsigned char * pakiet) +void gsm_receiver_cf::process_normal_burst(burst_counter burst_nr, unsigned char * pakiet) { if (burst_nr.get_timeslot_nr() == 0) { printf("burst = [ "); @@ -62,7 +61,7 @@ void gsm_receiver_cf::przetwarzaj_normalny_pakiet(burst_counter burst_nr, unsign // Ja zakładam, że dla danej szczeliny do określenia jaki typ pakietu przypada // dla danej chwili może być używany tylko jeden z tych liczników. Z dokumentu // 3gpp 04.03 wynika, że to jest prawda w warstwie fizycznej. -void gsm_receiver_cf::konfiguruj_odbiornik() +void gsm_receiver_cf::configure_receiver() { // poniżej jest przykład jak się konfiguruje odbiornik // najpierw mówię mu, że szczelina w szczelinie nr.0 typy pakietów zmieniają się wg. @@ -194,7 +193,7 @@ gsm_receiver_cf::general_work(int noutput_items, //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 - konfiguruj_odbiornik();//TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready + 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 @@ -250,7 +249,7 @@ gsm_receiver_cf::general_work(int noutput_items, case normal_burst: //if it's normal burst burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], TRAIN_SEARCH_RANGE, 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 - przetwarzaj_normalny_pakiet(d_burst_nr, output_binary); //TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready + 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 rach_burst: diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index ef9a8bb..e48feb6 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -206,12 +206,12 @@ class gsm_receiver_cf : public gr_block * @param burst_nr * @param pakiet */ - void przetwarzaj_normalny_pakiet(burst_counter burst_nr, unsigned char * pakiet); + void process_normal_burst(burst_counter burst_nr, unsigned char * pakiet); /** * */ - void konfiguruj_odbiornik(); + void configure_receiver(); public: ~gsm_receiver_cf(); -- cgit v1.2.3 From 672b1796513e9e49fefb114f4fb77e83504c3d9d Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Fri, 12 Jun 2009 12:25:10 +0200 Subject: added files for cch decoding, trying to make them compile --- src/lib/decoder/Makefile.am | 13 +- src/lib/decoder/cch.c | 481 +++++++++++++++++++++++++++++++++++++++++++ src/lib/decoder/cch.h | 56 +++++ src/lib/decoder/fire_crc.c | 179 ++++++++++++++++ src/lib/decoder/fire_crc.h | 47 +++++ src/lib/decoder/gsmstack.c | 197 ++++++++++++++++++ src/lib/decoder/gsmstack.h | 43 ++++ src/lib/decoder/interleave.c | 47 +++++ src/lib/decoder/interleave.h | 19 ++ 9 files changed, 1080 insertions(+), 2 deletions(-) create mode 100644 src/lib/decoder/cch.c create mode 100644 src/lib/decoder/cch.h create mode 100644 src/lib/decoder/fire_crc.c create mode 100644 src/lib/decoder/fire_crc.h create mode 100644 src/lib/decoder/gsmstack.c create mode 100644 src/lib/decoder/gsmstack.h create mode 100644 src/lib/decoder/interleave.c create mode 100644 src/lib/decoder/interleave.h diff --git a/src/lib/decoder/Makefile.am b/src/lib/decoder/Makefile.am index 32b55e0..3a3e3f5 100644 --- a/src/lib/decoder/Makefile.am +++ b/src/lib/decoder/Makefile.am @@ -26,9 +26,18 @@ AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) -I$(MAIN_INCLUDEDIR) noinst_LTLIBRARIES = libdecoder.la libdecoder_la_SOURCES = \ - sch.c + sch.c \ + cch.c \ + fire_crc.c \ + gsmstack.c \ + interleave.c noinst_HEADERS = \ sch.h \ - burst_types.h \ + cch.h \ + fire_crc.h \ + gsmstack.h \ + interleave.h \ system.h + +# burst_types.h diff --git a/src/lib/decoder/cch.c b/src/lib/decoder/cch.c new file mode 100644 index 0000000..468c1f3 --- /dev/null +++ b/src/lib/decoder/cch.c @@ -0,0 +1,481 @@ +//TODO: this file shouldn't be part of the GSM Receiver +#include "system.h" +#include +#include +#include +#include +#include + +//#include +//#include +#include +//#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 new file mode 100644 index 0000000..a642721 --- /dev/null +++ b/src/lib/decoder/cch.h @@ -0,0 +1,56 @@ +//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 new file mode 100644 index 0000000..7cdfc0b --- /dev/null +++ b/src/lib/decoder/fire_crc.c @@ -0,0 +1,179 @@ +//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 +#include + +#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 new file mode 100644 index 0000000..aa6319c --- /dev/null +++ b/src/lib/decoder/fire_crc.h @@ -0,0 +1,47 @@ +//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 new file mode 100644 index 0000000..0f2aca6 --- /dev/null +++ b/src/lib/decoder/gsmstack.c @@ -0,0 +1,197 @@ +//TODO: this file shouldn't be part of the GSM Receiver +/* + * Invoke gsmstack() with any kind of burst. Automaticly decode and retrieve + * information. + */ +#include "system.h" +#include +#include +#include +#include +#include "gsmstack.h" +#include "gsm_constants.h" +#include "gsm_receiver_config.h" +#include "interleave.h" +#include "sch.h" +#include "cch.h" + +//#include "out_pcap.h" + +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("tvoid.pcap"); + if (ctx->pcap_fd < 0) + fprintf(stderr, "cannot open PCAP file: %s\n", strerror(errno)); + + ctx->burst_pcap_fd = open_pcap_file("tvoid-burst.pcap"); + if (ctx->burst_pcap_fd < 0) + fprintf(stderr, "cannot open burst PCAP file: %s\n", strerror(errno)); + + return 0; +} + +#define BURST_BYTES ((USEFUL_BITS/8)+1) +/* + * 142 bit + */ +int +GS_process(GS_CTX *ctx, int ts, int type, const unsigned char *src) +{ + 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_burst) { + 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++; + } + + if (type == normal_burst) { + /* 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_burst, 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 new file mode 100644 index 0000000..9c5730e --- /dev/null +++ b/src/lib/decoder/gsmstack.h @@ -0,0 +1,43 @@ +//TODO: this file shouldn't be part of the GSM Receiver +#ifndef __GSMSTACK_H__ +#define __GSMSTACK_H__ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "interleave.h" + +struct gs_ts_ctx { + /* FIXME: later do this per each ts per each arfcn */ + unsigned char burst[4 * 58 * 2]; + int burst_count; +}; + +typedef struct +{ + int flags; + int fn; + int bsic; + char msg[23]; /* last decoded message */ + + INTERLEAVE_CTX interleave_ctx; + + 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); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/lib/decoder/interleave.c b/src/lib/decoder/interleave.c new file mode 100644 index 0000000..7b45927 --- /dev/null +++ b/src/lib/decoder/interleave.c @@ -0,0 +1,47 @@ +//TODO: this file shouldn't be part of the GSM Receiver +#include +#include +#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 new file mode 100644 index 0000000..fa1912f --- /dev/null +++ b/src/lib/decoder/interleave.h @@ -0,0 +1,19 @@ +//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 -- cgit v1.2.3 From f19e4b58d3ae359539b73612bf8509ccc9889ac2 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Sat, 13 Jun 2009 12:38:16 +0200 Subject: removed polish comments --- src/lib/gsm_receiver_cf.cc | 43 ++++++++----------------------------------- 1 file changed, 8 insertions(+), 35 deletions(-) diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 64f7d29..8f99209 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -38,11 +38,7 @@ #define SYNC_SEARCH_RANGE 30 #define TRAIN_SEARCH_RANGE 40 -//tutaj umieściłem funkcję która dostaje normalny pakiet + numer -//numer pakietu to numer ramki + numer szczeliny czasowej -//w tym przykładzie po prostu wyrzuca zawartość pakietu na wyjście -//ps. pakiety które nie mają trzech zer na początku zazwyczaj są błędnie odebrane -//ewentulanie innego typu (np. obierasz dummy jako normalny) +//TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready void gsm_receiver_cf::process_normal_burst(burst_counter burst_nr, unsigned char * pakiet) { if (burst_nr.get_timeslot_nr() == 0) { @@ -54,35 +50,13 @@ void gsm_receiver_cf::process_normal_burst(burst_counter burst_nr, unsigned char // std::cout << " t2: " << burst_nr.get_t2() << "\n"; } } - -// Tutaj ustawia się jekie rodzaje pakietów przypadają na dane stany licznika. -// Licznik ramek składa składa się z trzech części: t3,t2,t1. -// T3 liczy modulo 51, a t2 liczy modulo 26. -// Ja zakładam, że dla danej szczeliny do określenia jaki typ pakietu przypada -// dla danej chwili może być używany tylko jeden z tych liczników. Z dokumentu -// 3gpp 04.03 wynika, że to jest prawda w warstwie fizycznej. +//TODO: this shouldn't be here also - the same reason void gsm_receiver_cf::configure_receiver() { - // poniżej jest przykład jak się konfiguruje odbiornik - // najpierw mówię mu, że szczelina w szczelinie nr.0 typy pakietów zmieniają się wg. - // licznika t3, czyli modulo 51: - d_channel_conf.set_multiframe_type(TSC0, multiframe_51); - // tutaj mówię mu, gdzie ma szukać pakietów korekcji częstotliwości FCCH - // w gsm_constants jest definicja: const unsigned FCCH_FRAMES[] = {0, 10, 20, 30, 40}; - // kanał fcch jest nadawany zawsze w w szczelinie nr.0 więc podaję najapierw TSC0 - // potem wartości licznika z tej wcześniej zdefiniowanej tablicy, dalej ilość elementów tablicy, - // a na końcu typ pakietu - // typy są zdefiniowane w gsm_receiver_config.h d_channel_conf.set_burst_types(TSC0, FCCH_FRAMES, sizeof(FCCH_FRAMES) / sizeof(unsigned), fcch_burst); - - //w plikach z danymi są opisy i tam można znaleźć nr. szczeliny, w której nadawany był głos - //w pierwszym to jest: - //Traffic channel timeslot: 6 - //mogę skonfigurować żeby odbiornik na ślepo szukał tam pakietów normalnych, bez uciekania - //się do dekodowania informacji sterującej: -// 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), normal_burst); + 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), normal_burst); } @@ -115,8 +89,8 @@ gsm_receiver_cf::gsm_receiver_cf(gr_feval_dd *tuner, int osr) d_counter(0), d_fcch_start_pos(0), d_freq_offset(0), - d_burst_nr(osr), - d_state(first_fcch_search) + d_state(first_fcch_search), + d_burst_nr(osr) { int i; gmsk_mapper(SYNC_BITS, N_SYNC_BITS, d_sch_training_seq, gr_complex(0.0, -1.0)); @@ -145,7 +119,7 @@ gsm_receiver_cf::general_work(int noutput_items, gr_vector_void_star &output_items) { const gr_complex *input = (const gr_complex *) input_items[0]; - float *out = (float *) output_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 @@ -209,7 +183,6 @@ gsm_receiver_cf::general_work(int noutput_items, } 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); @@ -399,7 +372,7 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *input, const int nitems) case fcch_found: { DCOUT("fcch found on position: " << d_counter + start_pos); - to_consume = start_pos + FCCH_HITS_NEEDED * d_OSR + 1; + to_consume = start_pos + FCCH_HITS_NEEDED * d_OSR + 1; //consume one FCCH burst d_fcch_start_pos = d_counter + start_pos; -- cgit v1.2.3 From 8d22cd691b045295fd2de22e37868346ab0b0c45 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Sat, 13 Jun 2009 12:39:25 +0200 Subject: cch decoding works now - should be removed in the future, it shouldn't be done in receiver which works in physical layer --- src/lib/decoder/burst_types.h | 1 + src/lib/decoder/cch.c | 1 + src/lib/decoder/gsmstack.c | 54 +++++++++++++++++++++++++------------------ src/lib/decoder/gsmstack.h | 4 ++-- src/lib/decoder/sch.c | 2 +- 5 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/lib/decoder/burst_types.h b/src/lib/decoder/burst_types.h index 990e8f1..ee51f9a 100644 --- a/src/lib/decoder/burst_types.h +++ b/src/lib/decoder/burst_types.h @@ -17,6 +17,7 @@ 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 diff --git a/src/lib/decoder/cch.c b/src/lib/decoder/cch.c index 468c1f3..f1da56d 100644 --- a/src/lib/decoder/cch.c +++ b/src/lib/decoder/cch.c @@ -13,6 +13,7 @@ #include "cch.h" #include "fire_crc.h" + /* * GSM SACCH -- Slow Associated Control Channel * diff --git a/src/lib/decoder/gsmstack.c b/src/lib/decoder/gsmstack.c index 0f2aca6..cf94939 100644 --- a/src/lib/decoder/gsmstack.c +++ b/src/lib/decoder/gsmstack.c @@ -1,4 +1,3 @@ -//TODO: this file shouldn't be part of the GSM Receiver /* * Invoke gsmstack() with any kind of burst. Automaticly decode and retrieve * information. @@ -9,14 +8,25 @@ #include #include #include "gsmstack.h" -#include "gsm_constants.h" -#include "gsm_receiver_config.h" +//#include "gsm_constants.h" #include "interleave.h" -#include "sch.h" +//#include "sch.h" #include "cch.h" -//#include "out_pcap.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 */ @@ -74,17 +84,17 @@ GS_new(GS_CTX *ctx) 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->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("tvoid.pcap"); - if (ctx->pcap_fd < 0) - fprintf(stderr, "cannot open PCAP file: %s\n", strerror(errno)); +// ctx->pcap_fd = open_pcap_file("tvoid.pcap"); +// if (ctx->pcap_fd < 0) +// fprintf(stderr, "cannot open PCAP file: %s\n", strerror(errno)); - ctx->burst_pcap_fd = open_pcap_file("tvoid-burst.pcap"); - if (ctx->burst_pcap_fd < 0) - fprintf(stderr, "cannot open burst PCAP file: %s\n", strerror(errno)); +// ctx->burst_pcap_fd = open_pcap_file("tvoid-burst.pcap"); +// if (ctx->burst_pcap_fd < 0) +// fprintf(stderr, "cannot open burst PCAP file: %s\n", strerror(errno)); return 0; } @@ -108,8 +118,8 @@ GS_process(GS_CTX *ctx, int ts, int type, const unsigned char *src) /* 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); +// write_pcap_packet(ctx->burst_pcap_fd, 0 /* arfcn */, ts, ctx->fn, +// 1, type, octified, BURST_BYTES); #if 0 if (ts != 0) { @@ -117,13 +127,13 @@ GS_process(GS_CTX *ctx, int ts, int type, const unsigned char *src) 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); +// write_pcap_packet(ctx->pcap_fd, 0 /* arfcn */, ts, ctx->fn, data, len); return; } #endif if (ts == 0) { - if (type == sch_burst) { + if (type == SCH) { ret = decode_sch(src, &fn, &bsic); if (ret != 0) return 0; @@ -144,7 +154,7 @@ GS_process(GS_CTX *ctx, int ts, int type, const unsigned char *src) ctx->fn++; } - if (type == normal_burst) { + 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 @@ -167,9 +177,9 @@ GS_process(GS_CTX *ctx, int ts, int type, const unsigned char *src) //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_burst, 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; diff --git a/src/lib/decoder/gsmstack.h b/src/lib/decoder/gsmstack.h index 9c5730e..fb88334 100644 --- a/src/lib/decoder/gsmstack.h +++ b/src/lib/decoder/gsmstack.h @@ -29,8 +29,8 @@ typedef struct int tun_fd; unsigned char ether_addr[ETH_ALEN]; - int pcap_fd; - int burst_pcap_fd; +// int pcap_fd; +// int burst_pcap_fd; } GS_CTX; int GS_new(GS_CTX *ctx); diff --git a/src/lib/decoder/sch.c b/src/lib/decoder/sch.c index e16d14b..6f141dd 100644 --- a/src/lib/decoder/sch.c +++ b/src/lib/decoder/sch.c @@ -3,7 +3,7 @@ #include #include #include -#include +#include "gsm_constants.h" /* * Synchronization channel. -- cgit v1.2.3 From d406d48293c998567d628d950c66da1ca8ded39c Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Sat, 13 Jun 2009 17:28:03 +0200 Subject: cch decoding now works! but I have to remove it in the future :) --- src/lib/Assert.h | 2 +- src/lib/decoder/gsmstack.c | 24 ++++++++++++------------ src/lib/decoder/gsmstack.h | 2 +- src/lib/decoder/sch.h | 4 ++-- src/lib/gsm_constants.h | 5 +++++ src/lib/gsm_receiver_cf.cc | 23 +++++++++++++++-------- src/lib/gsm_receiver_cf.h | 9 +++++++-- src/lib/gsm_receiver_config.h | 3 --- 8 files changed, 43 insertions(+), 29 deletions(-) diff --git a/src/lib/Assert.h b/src/lib/Assert.h index dd222b0..acfb3f7 100644 --- a/src/lib/Assert.h +++ b/src/lib/Assert.h @@ -26,7 +26,7 @@ #include "stdio.h" #include -// #define NDEBUG +#define NDEBUG /**@name Macros for standard messages. */ //@{ diff --git a/src/lib/decoder/gsmstack.c b/src/lib/decoder/gsmstack.c index cf94939..ceda6c5 100644 --- a/src/lib/decoder/gsmstack.c +++ b/src/lib/decoder/gsmstack.c @@ -104,9 +104,9 @@ GS_new(GS_CTX *ctx) * 142 bit */ int -GS_process(GS_CTX *ctx, int ts, int type, const unsigned char *src) +GS_process(GS_CTX *ctx, int ts, int type, const unsigned char *src, int fn) { - int fn; +// int fn; int bsic; int ret; unsigned char *data; @@ -132,9 +132,9 @@ GS_process(GS_CTX *ctx, int ts, int type, const unsigned char *src) } #endif - if (ts == 0) { +/* if (ts == 0) { if (type == SCH) { - ret = decode_sch(src, &fn, &bsic); +// ret = decode_sch(src, &fn, &bsic); if (ret != 0) return 0; if ((ctx->bsic > 0) && (bsic != ctx->bsic)) @@ -143,17 +143,17 @@ GS_process(GS_CTX *ctx, int ts, int type, const unsigned char *src) ctx->fn = fn; ctx->bsic = bsic; /* Reset message concatenator */ - ts_ctx->burst_count = 0; - return 0; - } +// 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++; - } +// 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 diff --git a/src/lib/decoder/gsmstack.h b/src/lib/decoder/gsmstack.h index fb88334..7295b08 100644 --- a/src/lib/decoder/gsmstack.h +++ b/src/lib/decoder/gsmstack.h @@ -34,7 +34,7 @@ typedef struct } GS_CTX; int GS_new(GS_CTX *ctx); -int GS_process(GS_CTX *ctx, int ts, int type, const unsigned char *src); +int GS_process(GS_CTX *ctx, int ts, int type, const unsigned char *src, int fn); #ifdef __cplusplus } diff --git a/src/lib/decoder/sch.h b/src/lib/decoder/sch.h index 199d739..4d47eb5 100644 --- a/src/lib/decoder/sch.h +++ b/src/lib/decoder/sch.h @@ -1,6 +1,6 @@ -#ifndef __GSMSTACK_H__ -#define __GSMSTACK_H__ 1 +#ifndef __SCH_H__ +#define __SCH_H__ 1 #ifdef __cplusplus extern "C" diff --git a/src/lib/gsm_constants.h b/src/lib/gsm_constants.h index 6eecbb1..3f7ef04 100644 --- a/src/lib/gsm_constants.h +++ b/src/lib/gsm_constants.h @@ -33,6 +33,9 @@ #define CHAN_IMP_RESP_LENGTH 5 +typedef enum {empty, fcch_burst, sch_burst, normal_burst, rach_burst, dummy} 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, @@ -45,9 +48,11 @@ 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 diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 8f99209..7f91fa8 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -39,24 +39,28 @@ #define TRAIN_SEARCH_RANGE 40 //TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready -void gsm_receiver_cf::process_normal_burst(burst_counter burst_nr, unsigned char * pakiet) +void gsm_receiver_cf::process_normal_burst(burst_counter burst_nr, const unsigned char * burst_binary) { if (burst_nr.get_timeslot_nr() == 0) { - printf("burst = [ "); - for (int i = 0; i < BURST_SIZE ; i++) { - printf(" %d", pakiet[i]); - } - printf("];\n"); +// printf("burst = [ "); +// for (int i = 0; i < BURST_SIZE ; i++) { +// printf(" %d", burst_binary[i]); +// } +// printf("];\n"); // std::cout << " t2: " << burst_nr.get_t2() << "\n"; + 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(TIMESLOT6, multiframe_26); - d_channel_conf.set_burst_types(TIMESLOT6, TRAFFIC_CHANNEL_F, sizeof(TRAFFIC_CHANNEL_F) / sizeof(unsigned), normal_burst); + +// 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), normal_burst); } @@ -98,6 +102,9 @@ gsm_receiver_cf::gsm_receiver_cf(gr_feval_dd *tuner, int osr) for (i = 0; i < TRAIN_SEQ_NUM; i++) { gmsk_mapper(train_seq[i], N_TRAIN_BITS, d_norm_training_seq[i], gr_complex(1.0, 0.0)); } + + /* Initialize GSM Stack */ + GS_new(&d_gs_ctx); //TODO: remove it! it'a not right place for a decoder } /* diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index e48feb6..af13618 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -29,6 +29,8 @@ #include #include +#include //TODO: remember to remove this line in the future! + class gsm_receiver_cf; typedef boost::shared_ptr gsm_receiver_cf_sptr; @@ -93,6 +95,9 @@ class gsm_receiver_cf : public gr_block burst_counter d_burst_nr; ///< frame number and timeslot number channel_configuration d_channel_conf; ///< mapping of burst_counter to burst_type //@} + + // 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, int osr); gsm_receiver_cf(gr_feval_dd *tuner, int osr); @@ -204,9 +209,9 @@ class gsm_receiver_cf : public gr_block /** * * @param burst_nr - * @param pakiet + * @param burst_binary */ - void process_normal_burst(burst_counter burst_nr, unsigned char * pakiet); + void process_normal_burst(burst_counter burst_nr, const unsigned char * burst_binary); /** * diff --git a/src/lib/gsm_receiver_config.h b/src/lib/gsm_receiver_config.h index ebeedf7..25a3efc 100644 --- a/src/lib/gsm_receiver_config.h +++ b/src/lib/gsm_receiver_config.h @@ -33,9 +33,6 @@ #include #include -typedef enum {empty, fcch_burst, sch_burst, normal_burst, rach_burst, dummy} burst_type; -typedef enum {unknown, multiframe_26, multiframe_51} multiframe_type; - class multiframe_configuration { private: -- cgit v1.2.3 From f719ae292068d6ef0ec3aa1dffad837cb6ab9b1a Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Sat, 13 Jun 2009 18:10:43 +0200 Subject: removed unneded line from gsm_receive.py --- src/python/gsm_receive.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/python/gsm_receive.py b/src/python/gsm_receive.py index 449f7d8..22a71e0 100755 --- a/src/python/gsm_receive.py +++ b/src/python/gsm_receive.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -#!/usr/bin/env python from gnuradio import gr, gru, blks2 #, gsm -- cgit v1.2.3 From c473876ed253c3c70143991e35f9faa9c34c6290 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Sat, 13 Jun 2009 19:30:40 +0200 Subject: changed polish names of functions to english --- src/python/gsm_receive.py | 40 ++++++------ src/python/gsm_receive_usrp.py | 138 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+), 21 deletions(-) create mode 100755 src/python/gsm_receive_usrp.py diff --git a/src/python/gsm_receive.py b/src/python/gsm_receive.py index 22a71e0..c7aad62 100755 --- a/src/python/gsm_receive.py +++ b/src/python/gsm_receive.py @@ -24,32 +24,31 @@ class tune(gr.feval_dd): class gsm_receiver_first_blood(gr.top_block): def __init__(self): gr.top_block.__init__(self) - (options, args) = self._przetworz_opcje() + (options, args) = self._process_options() self.tune_callback = tune(self) self.options = options self.args = args - self._ustaw_taktowanie() - self.zrodlo = self._ustaw_zrodlo() - self.filtr = self._ustaw_filtr() - self.interpolator = self._ustaw_interpolator() - self.odbiornik = self._ustaw_odbiornik() - self.konwerter = self._ustaw_konwerter() - self.ujscie = self._ustaw_ujscie() + self._set_rates() + self.source = self._set_source() + self.filtr = self._set_filter() + self.interpolator = self._set_interpolator() + self.receiver = self._set_receiver() + self.converter = self._set_converter() + self.sink = self._set_sink() - self.connect(self.zrodlo, self.filtr, self.interpolator, self.odbiornik, self.konwerter, self.ujscie) -# self.connect(self.zrodlo, self.ujscie) + self.connect(self.source, self.filtr, self.interpolator, self.receiver, self.converter, self.sink) - def _ustaw_ujscie(self): + def _set_sink(self): nazwa_pliku_wy = self.options.outputfile ujscie = gr.file_sink(gr.sizeof_float, nazwa_pliku_wy) return ujscie - def _ustaw_zrodlo(self): + def _set_source(self): nazwa_pliku = self.options.inputfile zrodlo = gr.file_source(gr.sizeof_gr_complex, nazwa_pliku, False) return zrodlo - def _ustaw_taktowanie(self): + def _set_rates(self): options = self.options clock_rate = 64e6 self.clock_rate = clock_rate @@ -57,7 +56,7 @@ class gsm_receiver_first_blood(gr.top_block): self.gsm_symb_rate = 1625000.0 / 6.0 self.sps = self.input_rate / self.gsm_symb_rate / self.options.osr - def _ustaw_filtr(self): + def _set_filter(self): filter_cutoff = 145e3 filter_t_width = 10e3 offset = 0 @@ -66,20 +65,19 @@ class gsm_receiver_first_blood(gr.top_block): filtr = gr.freq_xlating_fir_filter_ccf(1, filter_taps, offset, self.input_rate) return filtr - def _ustaw_konwerter(self): + def _set_converter(self): v2s = gr.vector_to_stream(gr.sizeof_float, 142) return v2s - def _ustaw_interpolator(self): + def _set_interpolator(self): interpolator = gr.fractional_interpolator_cc(0, self.sps) -# interpolator = blks2.rational_resampler_ccf(13, 6) return interpolator - def _ustaw_odbiornik(self): - odbiornik = gsm.receiver_cf(self.tune_callback, self.options.osr) - return odbiornik + def _set_receiver(self): + receiver = gsm.receiver_cf(self.tune_callback, self.options.osr) + return receiver - def _przetworz_opcje(self): + def _process_options(self): parser = OptionParser(option_class=eng_option) parser.add_option("-d", "--decim", type="int", default=128, help="Set USRP decimation rate to DECIM [default=%default]") diff --git a/src/python/gsm_receive_usrp.py b/src/python/gsm_receive_usrp.py new file mode 100755 index 0000000..2633775 --- /dev/null +++ b/src/python/gsm_receive_usrp.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python + +from gnuradio import gr, gru, blks2 +#, gsm +from gnuradio import usrp +from gnuradio.eng_option import eng_option +from optparse import OptionParser +from os import sys + +for extdir in ['../../debug/src/lib','../../debug/src/lib/.libs']: + if extdir not in sys.path: + sys.path.append(extdir) +import gsm + +def pick_subdevice(u): + if u.db[0][0].dbid() >= 0: + return (0, 0) + if u.db[1][0].dbid() >= 0: + return (1, 0) + return (0, 0) + +class tune(gr.feval_dd): + def __init__(self, top_block): + gr.feval_dd.__init__(self) + self.top_block = top_block + # self.center_freq = 0 + def eval(self, freq_offet): + # self.center_freq = self.center_freq - freq_offet + self.top_block.set_frequency(freq_offet) + return freq_offet + +class gsm_receiver_first_blood(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + (options, args) = self._process_options() + self.tune_callback = tune(self) + self.options = options + self.args = args + self._set_rates() + self.source = self._set_source() + self.filtr = self._set_filter() + self.interpolator = self._set_interpolator() + self.receiver = self._set_receiver() + self.converter = self._set_converter() + self.sink = self._set_sink() + + self.connect(self.source, self.filtr, self.interpolator, self.receiver, self.converter, self.sink) + + def _set_sink(self): + nazwa_pliku_wy = self.options.outputfile + ujscie = gr.file_sink(gr.sizeof_float, nazwa_pliku_wy) + return ujscie + + def _set_source(self): + options = self.options + fusb_block_size = gr.prefs().get_long('fusb', 'block_size', 4096) + fusb_nblocks = gr.prefs().get_long('fusb', 'nblocks', 16) + self.usrp = usrp.source_c(decim_rate=options.decim, fusb_block_size=fusb_block_size, fusb_nblocks=fusb_nblocks) + + if options.rx_subdev_spec is None: + options.rx_subdev_spec = pick_subdevice(self.usrp) + + self.usrp.set_mux(usrp.determine_rx_mux_value(self.usrp, options.rx_subdev_spec)) + # determine the daughterboard subdevice + self.subdev = usrp.selected_subdev(self.usrp, options.rx_subdev_spec) + input_rate = self.usrp.adc_freq() / self.usrp.decim_rate() + + # set initial values + if options.gain is None: + # if no gain was specified, use the mid-point in dB + g = self.subdev.gain_range() + options.gain = float(g[0]+g[1])/2 + + r = self.usrp.tune(0, self.subdev, options.freq) + self.subdev.set_gain(options.gain) + return self.usrp + + def _set_rates(self): + options = self.options + clock_rate = 64e6 + self.clock_rate = clock_rate + self.input_rate = clock_rate / options.decim + self.gsm_symb_rate = 1625000.0 / 6.0 + self.sps = self.input_rate / self.gsm_symb_rate / self.options.osr + + def _set_filter(self): + filter_cutoff = 145e3 + filter_t_width = 10e3 + offset = 0 +# print "input_rate:", self.input_rate, "sample rate:", self.sps, " filter_cutoff:", filter_cutoff, " filter_t_width:", filter_t_width + filter_taps = gr.firdes.low_pass(1.0, self.input_rate, filter_cutoff, filter_t_width, gr.firdes.WIN_HAMMING) + filtr = gr.freq_xlating_fir_filter_ccf(1, filter_taps, offset, self.input_rate) + return filtr + + def _set_converter(self): + v2s = gr.vector_to_stream(gr.sizeof_float, 142) + return v2s + + def _set_interpolator(self): + interpolator = gr.fractional_interpolator_cc(0, self.sps) + return interpolator + + def _set_receiver(self): + receiver = gsm.receiver_cf(self.tune_callback, self.options.osr) + return receiver + + def _process_options(self): + parser = OptionParser(option_class=eng_option) + parser.add_option("-d", "--decim", type="int", default=128, + help="Set USRP decimation rate to DECIM [default=%default]") + parser.add_option("-I", "--inputfile", type="string", default="cfile", + help="Input filename") + parser.add_option("-O", "--outputfile", type="string", default="cfile2.out", + help="Output filename") + parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, + help="Select USRP Rx side A or B (default=first one with a daughterboard)") + parser.add_option("-r", "--osr", type="int", default=4, + help="Oversampling ratio [default=%default]") + parser.add_option("-f", "--freq", type="eng_float", default="950.4M", + help="set frequency to FREQ", metavar="FREQ") + parser.add_option("-g", "--gain", type="eng_float", default=None, + help="Set gain in dB (default is midpoint)") + (options, args) = parser.parse_args () + return (options, args) + + def set_frequency(self, center_freq): + self.filtr.set_center_freq(center_freq) + +def main(): + try: + gsm_receiver_first_blood().run() + except KeyboardInterrupt: + pass + +if __name__ == '__main__': + main() + + -- cgit v1.2.3 From 46b8adbe2aaeccd7f4d0f700aaa3e1c097be202a Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Sat, 13 Jun 2009 19:31:43 +0200 Subject: added new file for usrp realtime receive - caution - this doesn't work well yet --- src/lib/gsm_constants.h | 2 + src/lib/gsm_receiver_cf.cc | 16 ++++-- src/lib/gsm_receiver_cf.h | 2 + src/python/gsm_findfcch_usrp.py | 122 ---------------------------------------- 4 files changed, 15 insertions(+), 127 deletions(-) delete mode 100755 src/python/gsm_findfcch_usrp.py diff --git a/src/lib/gsm_constants.h b/src/lib/gsm_constants.h index 3f7ef04..1ebce1c 100644 --- a/src/lib/gsm_constants.h +++ b/src/lib/gsm_constants.h @@ -33,6 +33,8 @@ #define CHAN_IMP_RESP_LENGTH 5 +#define MAX_SCH_ERRORS 2 //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} burst_type; typedef enum {unknown, multiframe_26, multiframe_51} multiframe_type; diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 7f91fa8..0fde642 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -55,10 +55,10 @@ void gsm_receiver_cf::process_normal_burst(burst_counter burst_nr, const unsigne 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(TIMESLOT6, multiframe_26); // d_channel_conf.set_burst_types(TIMESLOT6, TRAFFIC_CHANNEL_F, sizeof(TRAFFIC_CHANNEL_F) / sizeof(unsigned), normal_burst); } @@ -94,7 +94,8 @@ gsm_receiver_cf::gsm_receiver_cf(gr_feval_dd *tuner, int osr) d_fcch_start_pos(0), d_freq_offset(0), d_state(first_fcch_search), - d_burst_nr(osr) + d_burst_nr(osr), + d_failed_sch(0) { int i; gmsk_mapper(SYNC_BITS, N_SYNC_BITS, d_sch_training_seq, gr_complex(0.0, -1.0)); @@ -102,7 +103,7 @@ gsm_receiver_cf::gsm_receiver_cf(gr_feval_dd *tuner, int osr) for (i = 0; i < TRAIN_SEQ_NUM; i++) { gmsk_mapper(train_seq[i], N_TRAIN_BITS, d_norm_training_seq[i], gr_complex(1.0, 0.0)); } - + /* Initialize GSM Stack */ GS_new(&d_gs_ctx); //TODO: remove it! it'a not right place for a decoder } @@ -218,10 +219,16 @@ gsm_receiver_cf::general_work(int noutput_items, 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; + } } } break; @@ -680,6 +687,5 @@ int gsm_receiver_cf::get_norm_chan_imp_resp(const gr_complex *input, gr_complex //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 index af13618..c37813a 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -96,6 +96,8 @@ class gsm_receiver_cf : public gr_block 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 diff --git a/src/python/gsm_findfcch_usrp.py b/src/python/gsm_findfcch_usrp.py deleted file mode 100755 index 7bf81f3..0000000 --- a/src/python/gsm_findfcch_usrp.py +++ /dev/null @@ -1,122 +0,0 @@ -#!/usr/bin/env python -#!/usr/bin/env python - -from gnuradio import gr, gru, blks2 -from gnuradio import usrp -#from gnuradio import gsm -from gnuradio.eng_option import eng_option -from optparse import OptionParser -from os import sys -#""" -for extdir in ['../../debug/src/lib','../../debug/src/lib/.libs']: - if extdir not in sys.path: - sys.path.append(extdir) -import gsm -#""" -def pick_subdevice(u): - if u.db[0][0].dbid() >= 0: - return (0, 0) - if u.db[1][0].dbid() >= 0: - return (1, 0) - return (0, 0) - -class gsm_receiver_first_blood(gr.top_block): - def __init__(self): - gr.top_block.__init__(self) - ( self.options, self.args) = self._przetworz_opcje() - self._ustaw_taktowanie() - self.zrodlo = self._ustaw_zrodlo() - self.filtr = self._ustaw_filtr() - self.interpolator = self._ustaw_interpolator() - self.odbiornik = self._ustaw_odbiornik() - self.konwerter = self._ustaw_konwerter() - self.ujscie = self._ustaw_ujscie() - - self.connect(self.zrodlo, self.filtr, self.interpolator, self.odbiornik, self.konwerter, self.ujscie) -# self.connect(self.zrodlo, self.ujscie) - - def _ustaw_ujscie(self): - nazwa_pliku_wy = self.options.outputfile - ujscie = gr.file_sink(gr.sizeof_float, nazwa_pliku_wy) - return ujscie - - def _ustaw_zrodlo(self): - options = self.options - fusb_block_size = gr.prefs().get_long('fusb', 'block_size', 4096) - fusb_nblocks = gr.prefs().get_long('fusb', 'nblocks', 16) - self.usrp = usrp.source_c(decim_rate=options.decim, fusb_block_size=fusb_block_size, fusb_nblocks=fusb_nblocks) - - if options.rx_subdev_spec is None: - options.rx_subdev_spec = pick_subdevice(self.usrp) - - self.usrp.set_mux(usrp.determine_rx_mux_value(self.usrp, options.rx_subdev_spec)) - # determine the daughterboard subdevice - self.subdev = usrp.selected_subdev(self.usrp, options.rx_subdev_spec) - input_rate = self.usrp.adc_freq() / self.usrp.decim_rate() - - # set initial values - if options.gain is None: - # if no gain was specified, use the mid-point in dB - g = self.subdev.gain_range() - options.gain = float(g[0]+g[1])/2 - - r = self.usrp.tune(0, self.subdev, options.freq) - self.subdev.set_gain(options.gain) - return self.usrp - - def _ustaw_taktowanie(self): - options = self.options - clock_rate = 64e6 - self.clock_rate = clock_rate - self.input_rate = clock_rate / options.decim - self.gsm_symb_rate = 1625000.0 / 6.0 - self.sps = self.input_rate / self.gsm_symb_rate - - def _ustaw_filtr(self): - filter_cutoff = 145e3 - filter_t_width = 10e3 - offset = 0 - print "input_rate:", self.input_rate, "sample rate:", self.sps, " filter_cutoff:", filter_cutoff, " filter_t_width:", filter_t_width - filter_taps = gr.firdes.low_pass(1.0, self.input_rate, filter_cutoff, filter_t_width, gr.firdes.WIN_HAMMING) - filtr = gr.freq_xlating_fir_filter_ccf(1, filter_taps, offset, self.input_rate) - return filtr - - def _ustaw_konwerter(self): - v2s = gr.vector_to_stream(gr.sizeof_float, 142) - return v2s - - def _ustaw_interpolator(self): - interpolator = gr.fractional_interpolator_cc(0, self.sps) - return interpolator - - def _ustaw_odbiornik(self): - odbiornik = gsm.receiver_cf(1) - return odbiornik - - def _przetworz_opcje(self): - parser = OptionParser(option_class=eng_option) - parser.add_option("-d", "--decim", type="int", default=128, - help="Set USRP decimation rate to DECIM [default=%default]") - parser.add_option("-I", "--inputfile", type="string", default="cfile", - help="Input filename") - parser.add_option("-O", "--outputfile", type="string", default="cfile2.out", - help="Output filename") - parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, - help="Select USRP Rx side A or B (default=first one with a daughterboard)") - parser.add_option("-f", "--freq", type="eng_float", default="950.4M", - help="set frequency to FREQ", metavar="FREQ") - parser.add_option("-g", "--gain", type="eng_float", default=None, - help="Set gain in dB (default is midpoint)") - (options, args) = parser.parse_args () - return (options, args) - -def main(): - try: - gsm_receiver_first_blood().run() - except KeyboardInterrupt: - pass - -if __name__ == '__main__': - main() - - -- cgit v1.2.3 From ad4d4caba66a1f585165f8ead89992687c7b9120 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Sat, 13 Jun 2009 19:35:05 +0200 Subject: bootstrap makes 'debug' directory now --- bootstrap | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bootstrap b/bootstrap index 525a6b0..350e0ff 100755 --- a/bootstrap +++ b/bootstrap @@ -27,3 +27,6 @@ autoconf autoheader libtoolize --automake automake --add-missing +if test ! -d debug; then + mkdir debug +fi \ No newline at end of file -- cgit v1.2.3 From df53876e411e5e4eceb6d341643147b6bbc3df01 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Sat, 13 Jun 2009 19:42:22 +0200 Subject: added two little utils from gsm-tvoid --- README | 7 +++++++ src/python/capture.sh | 39 +++++++++++++++++++++++++++++++++++++++ src/python/go.sh | 12 ++++++++++++ 3 files changed, 58 insertions(+) create mode 100755 src/python/capture.sh create mode 100755 src/python/go.sh diff --git a/README b/README index e69de29..61141d5 100644 --- a/README +++ b/README @@ -0,0 +1,7 @@ +To build gsm receiver use: + $ ./bootstrap + $ cd debug + $ ./configure + $ make + +Usage \ No newline at end of file diff --git a/src/python/capture.sh b/src/python/capture.sh new file mode 100755 index 0000000..7256f2b --- /dev/null +++ b/src/python/capture.sh @@ -0,0 +1,39 @@ +#! /bin/sh + +if [ $1"x" = x ]; then + echo "./capture.sh [duration==10] [decim==112]" + echo "Example: ./capture.sh 940.4M" + exit 1 +fi +FREQ=$1 + +DURATION=$2 +if [ $2"x" = x ]; then + DURATION=10 +fi +DECIM=$3 +if [ $3"x" = x ]; then + DECIM=112 +fi + +USRP_PROG=usrp_rx_cfile.py +while :; do + which "$USRP_PROG" + if [ $? -eq 0 ]; then + break + fi + USRP_PROG=/usr/share/gnuradio/usrp/usrp_rx_cfile.py + which "$USRP_PROG" + if [ $? -eq 0 ]; then + break + fi + + echo "ERROR: usrp_rx_cfile.py not found. Make sure it's in your PATH!" + exit 1 +done + +FILE="capture_${FREQ}_${DECIM}.cfile" +samples=`expr 64000000 / $DECIM '*' $DURATION` +echo "Capturing for $DURATION seconds to $FILE ($samples samples)" +$USRP_PROG -d "$DECIM" -f "$FREQ" -N $samples $FILE + diff --git a/src/python/go.sh b/src/python/go.sh new file mode 100755 index 0000000..1e8150d --- /dev/null +++ b/src/python/go.sh @@ -0,0 +1,12 @@ +#! /bin/sh + +echo "go.sh [decim==112]" + +DECIM=$2 +FILE=$1 + +if [ $DECIM"x" = x ]; then + DECIM=112 +fi + +./gsm_receive.py -d "$DECIM" -I "$FILE" | ../../../gsmdecode/src/gsmdecode -i -- cgit v1.2.3 From f1e01e52ccd20813a5a04aca00efc6457de27259 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Sat, 13 Jun 2009 19:47:03 +0200 Subject: changed installation and receiver --- INSTALL | 240 ++-------------------------------------------------------------- README | 3 +- 2 files changed, 6 insertions(+), 237 deletions(-) diff --git a/INSTALL b/INSTALL index 23e5f25..7e127f9 100644 --- a/INSTALL +++ b/INSTALL @@ -1,236 +1,6 @@ -Installation Instructions -************************* - -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free -Software Foundation, Inc. - -This file is free documentation; the Free Software Foundation gives -unlimited permission to copy, distribute and modify it. - -Basic Installation -================== - -These are generic installation instructions. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). - - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. (Caching is -disabled by default to prevent problems with accidental use of stale -cache files.) - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you -may remove or edit it. - - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You only need -`configure.ac' if you want to change it or regenerate `configure' using -a newer version of `autoconf'. - -The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. If you're - using `csh' on an old version of System V, you might need to type - `sh ./configure' instead to prevent `csh' from trying to execute - `configure' itself. - - Running `configure' takes awhile. While running, it prints some - messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package. - - 4. Type `make install' to install the programs and any data files and - documentation. - - 5. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - -Compilers and Options -===================== - -Some systems require unusual options for compilation or linking that the -`configure' script does not know about. Run `./configure --help' for -details on some of the pertinent environment variables. - - You can give `configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here -is an example: - - ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix - - *Note Defining Variables::, for more details. - -Compiling For Multiple Architectures -==================================== - -You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you must use a version of `make' that -supports the `VPATH' variable, such as GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. - - If you have to use a `make' that does not support the `VPATH' -variable, you have to compile the package for one architecture at a -time in the source code directory. After you have installed the -package for one architecture, use `make distclean' before reconfiguring -for another architecture. - -Installation Names -================== - -By default, `make install' installs the package's commands under -`/usr/local/bin', include files under `/usr/local/include', etc. You -can specify an installation prefix other than `/usr/local' by giving -`configure' the option `--prefix=PREFIX'. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -pass the option `--exec-prefix=PREFIX' to `configure', the package uses -PREFIX as the prefix for installing programs and libraries. -Documentation and other data files still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=DIR' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - -Optional Features -================= - -Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - -Specifying the System Type -========================== - -There may be some features `configure' cannot figure out automatically, -but needs to determine by the type of machine the package will run on. -Usually, assuming the package is built to be run on the _same_ -architectures, `configure' can figure that out, but if it prints a -message saying it cannot guess the machine type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: - - CPU-COMPANY-SYSTEM - -where SYSTEM can have one of these forms: - - OS KERNEL-OS - - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the machine type. - - If you are _building_ compiler tools for cross-compiling, you should -use the option `--target=TYPE' to select the type of system they will -produce code for. - - If you want to _use_ a cross compiler, that generates code for a -platform different from the build platform, you should specify the -"host" platform (i.e., that on which the generated programs will -eventually be run) with `--host=TYPE'. - -Sharing Defaults -================ - -If you want to set default values for `configure' scripts to share, you -can create a site shell script called `config.site' that gives default -values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Defining Variables -================== - -Variables not defined in a site shell script can be set in the -environment passed to `configure'. However, some packages may run -configure again during the build, and the customized values of these -variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: - - ./configure CC=/usr/local2/bin/gcc - -causes the specified `gcc' to be used as the C compiler (unless it is -overridden in the site shell script). Here is a another example: - - /bin/bash ./configure CONFIG_SHELL=/bin/bash - -Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent -configuration-related scripts to be executed by `/bin/bash'. - -`configure' Invocation -====================== - -`configure' recognizes the following options to control how it operates. - -`--help' -`-h' - Print a summary of the options to `configure', and exit. - -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`--cache-file=FILE' - Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to - disable caching. - -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. +Usage: + -capture cfile with usrp: + $ capture.sh + -run go.sh on this file: + $ go.sh diff --git a/README b/README index 61141d5..0174797 100644 --- a/README +++ b/README @@ -1,7 +1,6 @@ -To build gsm receiver use: +To build the GSM Receiver use: $ ./bootstrap $ cd debug $ ./configure $ make -Usage \ No newline at end of file -- cgit v1.2.3 From 31cf43810c3876c6af5527c686e1ad1ea3319dd3 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Sat, 13 Jun 2009 19:49:11 +0200 Subject: dfad --- INSTALL | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/INSTALL b/INSTALL index 7e127f9..90aab7f 100644 --- a/INSTALL +++ b/INSTALL @@ -2,5 +2,5 @@ Usage: -capture cfile with usrp: $ capture.sh -run go.sh on this file: - $ go.sh + $ go.sh -- cgit v1.2.3 From 5a3a299da271e6e81c6bf90cec0c235e0b73ddb2 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Sat, 13 Jun 2009 20:05:31 +0200 Subject: nothing interesting --- INSTALL | 10 +++++----- README | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/INSTALL b/INSTALL index 90aab7f..0174797 100644 --- a/INSTALL +++ b/INSTALL @@ -1,6 +1,6 @@ -Usage: - -capture cfile with usrp: - $ capture.sh - -run go.sh on this file: - $ go.sh +To build the GSM Receiver use: + $ ./bootstrap + $ cd debug + $ ./configure + $ make diff --git a/README b/README index 0174797..90aab7f 100644 --- a/README +++ b/README @@ -1,6 +1,6 @@ -To build the GSM Receiver use: - $ ./bootstrap - $ cd debug - $ ./configure - $ make +Usage: + -capture cfile with usrp: + $ capture.sh + -run go.sh on this file: + $ go.sh -- cgit v1.2.3 From 48dc955afd9c020c9e5627111db222717ce0664f Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Sun, 14 Jun 2009 19:16:20 +0200 Subject: little changes to decrease number of errors in output bits --- src/lib/gsm_constants.h | 2 +- src/lib/gsm_receiver_cf.cc | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/lib/gsm_constants.h b/src/lib/gsm_constants.h index 1ebce1c..e4e2461 100644 --- a/src/lib/gsm_constants.h +++ b/src/lib/gsm_constants.h @@ -33,7 +33,7 @@ #define CHAN_IMP_RESP_LENGTH 5 -#define MAX_SCH_ERRORS 2 //maximum number of subsequent sch errors after which gsm receiver goes to find_next_fcch state +#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} burst_type; typedef enum {unknown, multiframe_26, multiframe_51} multiframe_type; diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 0fde642..ceea6a1 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -613,6 +613,9 @@ inline void gsm_receiver_cf::mafi(const gr_complex * input, int nitems, gr_compl } } +//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, unsigned search_range, int bcc) { vector_complex correlation_buffer; @@ -626,7 +629,8 @@ int gsm_receiver_cf::get_norm_chan_imp_resp(const gr_complex *input, gr_complex 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 + 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++) { @@ -643,7 +647,8 @@ int gsm_receiver_cf::get_norm_chan_imp_resp(const gr_complex *input, gr_complex vector_float::iterator iter_ii = iter; energy = 0; - for (int ii = 0; ii < (d_chan_imp_length)*d_OSR; ii++, iter_ii++) { + 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; @@ -657,9 +662,9 @@ int gsm_receiver_cf::get_norm_chan_imp_resp(const gr_complex *input, gr_complex 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(); + //!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++) { -- cgit v1.2.3 From 87aca185e3eecc4c8952e94bb46930d05f7e45fe Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Sun, 14 Jun 2009 19:43:53 +0200 Subject: added first simple test --- src/python/test.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100755 src/python/test.sh diff --git a/src/python/test.sh b/src/python/test.sh new file mode 100755 index 0000000..1631f70 --- /dev/null +++ b/src/python/test.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +./gsm_receive.py -I cfile > receiver-test.out +echo " 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b\n 15 06 21 00 01 00 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b" > receiver-comp.out +diff receiver-test.out receiver-comp.out > receiver-test-diff.out +test_result=`cat receiver-test-diff.out` + +rm receiver-test.out receiver-test-diff.out receiver-comp.out + +if [ "x$test_result" = "x" ]; then + echo "Test: passed" + exit 0 +else + echo "Test: failed" + exit 1 +fi -- cgit v1.2.3 From f75b5678e6f8ae31fe5a3be1ef7ffa45fc311bbd Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Sun, 14 Jun 2009 23:29:57 +0200 Subject: changed comment in gsm_receive_usrp.py --- src/python/gsm_receive_usrp.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/python/gsm_receive_usrp.py b/src/python/gsm_receive_usrp.py index 2633775..2c0c050 100755 --- a/src/python/gsm_receive_usrp.py +++ b/src/python/gsm_receive_usrp.py @@ -1,4 +1,7 @@ #!/usr/bin/env python +#this file isn't ready to use now - gsm-receiver lacks realtime processing capability +#there are many underruns of buffer fom usrp's samples, many blocks of samples get lost and +#receiver isn't prepared for this situation too well from gnuradio import gr, gru, blks2 #, gsm -- cgit v1.2.3 From 008152ac306e11da227b8f020eeb93c80f1e9463 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Sun, 14 Jun 2009 23:31:04 +0200 Subject: one letter change to gsm_receive_usrp.py --- src/python/gsm_receive_usrp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/gsm_receive_usrp.py b/src/python/gsm_receive_usrp.py index 2c0c050..7d28633 100755 --- a/src/python/gsm_receive_usrp.py +++ b/src/python/gsm_receive_usrp.py @@ -1,6 +1,6 @@ #!/usr/bin/env python #this file isn't ready to use now - gsm-receiver lacks realtime processing capability -#there are many underruns of buffer fom usrp's samples, many blocks of samples get lost and +#there are many underruns of buffer from usrp's samples, many blocks of samples get lost and #receiver isn't prepared for this situation too well from gnuradio import gr, gru, blks2 -- cgit v1.2.3 From 3f0169585338a5412f6aa46d2feada369436853f Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Mon, 15 Jun 2009 18:14:43 +0200 Subject: some changes to test.sh --- INSTALL | 4 +++- README | 1 - src/python/capture.sh | 10 ++++++++-- src/python/go.sh | 2 +- src/python/test.sh | 2 +- 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/INSTALL b/INSTALL index 0174797..2e57aa5 100644 --- a/INSTALL +++ b/INSTALL @@ -1,6 +1,8 @@ +Under Ubuntu 9.04 install: + $ apt-get install gnuradio libtool automake + To build the GSM Receiver use: $ ./bootstrap $ cd debug $ ./configure $ make - diff --git a/README b/README index 90aab7f..96b560b 100644 --- a/README +++ b/README @@ -3,4 +3,3 @@ Usage: $ capture.sh -run go.sh on this file: $ go.sh - diff --git a/src/python/capture.sh b/src/python/capture.sh index 7256f2b..ef205d8 100755 --- a/src/python/capture.sh +++ b/src/python/capture.sh @@ -1,7 +1,7 @@ #! /bin/sh if [ $1"x" = x ]; then - echo "./capture.sh [duration==10] [decim==112]" + echo "./capture.sh [duration==10] [decim==112] [gain==52]" echo "Example: ./capture.sh 940.4M" exit 1 fi @@ -16,6 +16,12 @@ if [ $3"x" = x ]; then DECIM=112 fi +GAIN=$4 +if [ $4"x" = x ]; then + GAIN=52 +fi + + USRP_PROG=usrp_rx_cfile.py while :; do which "$USRP_PROG" @@ -35,5 +41,5 @@ done FILE="capture_${FREQ}_${DECIM}.cfile" samples=`expr 64000000 / $DECIM '*' $DURATION` echo "Capturing for $DURATION seconds to $FILE ($samples samples)" -$USRP_PROG -d "$DECIM" -f "$FREQ" -N $samples $FILE +$USRP_PROG -g $GAIN -d "$DECIM" -f "$FREQ" -N $samples $FILE diff --git a/src/python/go.sh b/src/python/go.sh index 1e8150d..e0d1290 100755 --- a/src/python/go.sh +++ b/src/python/go.sh @@ -1,6 +1,6 @@ #! /bin/sh -echo "go.sh [decim==112]" +#echo "go.sh [decim==112]" DECIM=$2 FILE=$1 diff --git a/src/python/test.sh b/src/python/test.sh index 1631f70..0a828e9 100755 --- a/src/python/test.sh +++ b/src/python/test.sh @@ -1,6 +1,6 @@ #!/bin/sh -./gsm_receive.py -I cfile > receiver-test.out +./gsm_receive.py -I cfile > receiver-test.out 2> /dev/null echo " 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b\n 15 06 21 00 01 00 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b" > receiver-comp.out diff receiver-test.out receiver-comp.out > receiver-test-diff.out test_result=`cat receiver-test-diff.out` -- cgit v1.2.3 From aa5a774a430337a50409ec9709ff4bf9c98d0fcd Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Thu, 18 Jun 2009 14:00:39 +0200 Subject: little update to Install --- INSTALL | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/INSTALL b/INSTALL index 2e57aa5..b9fb61c 100644 --- a/INSTALL +++ b/INSTALL @@ -1,5 +1,10 @@ Under Ubuntu 9.04 install: - $ apt-get install gnuradio libtool automake + -add following lines to /etc/apt/sources.list + deb http://gnuradio.org/ubuntu stable main + deb-src http://gnuradio.org/ubuntu stable main + -type + $ sudo apt-get update + $ sudo apt-get install gnuradio libtool automake To build the GSM Receiver use: $ ./bootstrap -- cgit v1.2.3 From e71a1a8675f16b177920d1f6b2413288c914d8f9 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Thu, 18 Jun 2009 14:10:17 +0200 Subject: added new burst type - dummy_or_normal for situations in which you don't know what type is used when --- src/lib/gsm_constants.h | 2 +- src/lib/gsm_receiver_cf.cc | 21 +++++++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/lib/gsm_constants.h b/src/lib/gsm_constants.h index e4e2461..74d2e2e 100644 --- a/src/lib/gsm_constants.h +++ b/src/lib/gsm_constants.h @@ -35,7 +35,7 @@ #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} burst_type; +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[] = { diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index ceea6a1..39571dc 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -59,8 +59,8 @@ void gsm_receiver_cf::configure_receiver() 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(TIMESLOT6, multiframe_26); -// d_channel_conf.set_burst_types(TIMESLOT6, TRAFFIC_CHANNEL_F, sizeof(TRAFFIC_CHANNEL_F) / sizeof(unsigned), normal_burst); +// 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); } @@ -239,6 +239,23 @@ gsm_receiver_cf::general_work(int noutput_items, 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], TRAIN_SEARCH_RANGE, TS_DUMMY); + detect_burst(input, &channel_imp_resp[0], burst_start, output_binary); + + std::vector v(20); + std::vector::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], TRAIN_SEARCH_RANGE, 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 -- cgit v1.2.3 From b14ed29e21ed7fc8be9a5b7ba779877df7331bf1 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Thu, 18 Jun 2009 14:12:25 +0200 Subject: added some attemt to repair receiver's faulty behavior when some samples get losted between USRP and PC and resynchronisation is necessary - it doesn't work yet --- src/lib/gsm_receiver_cf.cc | 61 +++++++++++++++++++++++++++++++--------------- src/lib/gsm_receiver_cf.h | 2 ++ 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 39571dc..c9ef010 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -28,9 +28,9 @@ #include #include #include -#include #include #include +#include #include #include #include @@ -41,13 +41,15 @@ //TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready void gsm_receiver_cf::process_normal_burst(burst_counter burst_nr, const unsigned char * burst_binary) { - if (burst_nr.get_timeslot_nr() == 0) { -// printf("burst = [ "); + if (burst_nr.get_timeslot_nr() == 0) { +// std::cout << " t2:" << burst_nr.get_t2() << " fn:" << burst_nr.get_frame_nr(); +// printf(" burst = [ "); // for (int i = 0; i < BURST_SIZE ; i++) { // printf(" %d", burst_binary[i]); // } // printf("];\n"); // std::cout << " t2: " << burst_nr.get_t2() << "\n"; +// std::cout << " bcc: " << d_bcc << "\n"; GS_process(&d_gs_ctx, TIMESLOT0, 6, &burst_binary[3], burst_nr.get_frame_nr()); } } @@ -101,11 +103,19 @@ gsm_receiver_cf::gsm_receiver_cf(gr_feval_dd *tuner, int osr) 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++) { - gmsk_mapper(train_seq[i], N_TRAIN_BITS, d_norm_training_seq[i], gr_complex(1.0, 0.0)); + 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 negative 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); } /* Initialize GSM Stack */ - GS_new(&d_gs_ctx); //TODO: remove it! it'a not right place for a decoder + GS_new(&d_gs_ctx); //TODO: remove it! it's not a right place for a decoder } /* @@ -144,9 +154,8 @@ gsm_receiver_cf::general_work(int noutput_items, } break; - case next_fcch_search: { //this state is used because it takes a bunch of buffered samples - //before previous set_frequqency cause change - float prev_freq_offset = d_freq_offset; + 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 @@ -159,6 +168,7 @@ gsm_receiver_cf::general_work(int noutput_items, } break; } + case sch_search: { vector_complex channel_imp_resp(CHAN_IMP_RESP_LENGTH*d_OSR); int t1, t2, t3; @@ -204,12 +214,21 @@ gsm_receiver_cf::general_work(int noutput_items, 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; + 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 - if (abs(freq_offset) > FCCH_MAX_FREQ_OFFSET) { - d_freq_offset -= freq_offset; //and adjust frequency if it have changed beyond - set_frequency(d_freq_offset); //some limit - DCOUT("Adjusting frequency, new frequency offset: " << d_freq_offset << "\n"); + + 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; @@ -226,8 +245,10 @@ gsm_receiver_cf::general_work(int noutput_items, 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; + 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"); } } } @@ -646,8 +667,8 @@ int gsm_receiver_cf::get_norm_chan_imp_resp(const gr_complex *input, gr_complex 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_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++) { @@ -664,7 +685,7 @@ int gsm_receiver_cf::get_norm_chan_imp_resp(const gr_complex *input, gr_complex 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 - 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; @@ -680,8 +701,8 @@ int gsm_receiver_cf::get_norm_chan_imp_resp(const gr_complex *input, gr_complex 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 + 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++) { diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index c37813a..070f9cf 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -23,6 +23,7 @@ #define INCLUDED_GSM_RECEIVER_CF_H #include +#include #include #include #include @@ -75,6 +76,7 @@ class gsm_receiver_cf : public gr_block 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 d_freq_offset_vals; /**@name Identifiers of the BTS extracted from the SCH burst */ //@{ -- cgit v1.2.3 From 9b2c992cf1055afb35780e1eba799243d8be2dae Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Mon, 22 Jun 2009 17:22:07 +0200 Subject: added first step towards correction of USRP's clock offset --- src/lib/gsm.i | 4 ++-- src/lib/gsm_receiver_cf.cc | 6 +++--- src/lib/gsm_receiver_cf.h | 9 ++++----- src/python/gsm_receive.py | 29 +++++++++++++++++++---------- 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/src/lib/gsm.i b/src/lib/gsm.i index 8c4d79a..b5a33f2 100644 --- a/src/lib/gsm.i +++ b/src/lib/gsm.i @@ -38,12 +38,12 @@ GR_SWIG_BLOCK_MAGIC(gsm,receiver_cf); -gsm_receiver_cf_sptr gsm_make_receiver_cf ( gr_feval_dd *tuner, int osr); +gsm_receiver_cf_sptr gsm_make_receiver_cf ( gr_feval_dd *tuner, gr_feval_dd *synchronizer, int osr); class gsm_receiver_cf : public gr_block { private: - gsm_receiver_cf ( gr_feval_dd *tuner, int osr); + gsm_receiver_cf ( gr_feval_dd *tuner, gr_feval_dd *synchronizer, int osr); }; // ---------------------------------------------------------------- diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index c9ef010..e314381 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -72,9 +72,9 @@ typedef std::vector vector_float; typedef boost::circular_buffer circular_buffer_float; gsm_receiver_cf_sptr -gsm_make_receiver_cf(gr_feval_dd *tuner, int osr) +gsm_make_receiver_cf(gr_feval_dd *tuner, gr_feval_dd *synchronizer, int osr) { - return gsm_receiver_cf_sptr(new gsm_receiver_cf(tuner, osr)); + return gsm_receiver_cf_sptr(new gsm_receiver_cf(tuner, synchronizer, osr)); } static const int MIN_IN = 1; // mininum number of input streams @@ -85,7 +85,7 @@ static const int MAX_OUT = 1; // maximum number of output streams /* * The private constructor */ -gsm_receiver_cf::gsm_receiver_cf(gr_feval_dd *tuner, int osr) +gsm_receiver_cf::gsm_receiver_cf(gr_feval_dd *tuner, gr_feval_dd *synchronizer, int osr) : 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))), diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index 070f9cf..9454997 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -37,7 +37,7 @@ class gsm_receiver_cf; typedef boost::shared_ptr gsm_receiver_cf_sptr; typedef std::vector vector_complex; -gsm_receiver_cf_sptr gsm_make_receiver_cf(gr_feval_dd *tuner, int osr); +gsm_receiver_cf_sptr gsm_make_receiver_cf(gr_feval_dd *tuner, gr_feval_dd *synchronizer, int osr); /** GSM Receiver GNU Radio block * @@ -61,6 +61,7 @@ class gsm_receiver_cf : public gr_block gr_complex d_norm_training_seq[TRAIN_SEQ_NUM][N_TRAIN_BITS]; /// Date: Mon, 22 Jun 2009 17:25:24 +0200 Subject: added files for pcap from Harald's gsmstack --- src/lib/decoder/gsmstack.c | 29 +++++------ src/lib/decoder/gsmstack.h | 4 +- src/lib/decoder/gsmtap.h | 41 +++++++++++++++ src/lib/decoder/out_pcap.c | 111 ++++++++++++++++++++++++++++++++++++++++ src/lib/decoder/out_pcap.h | 9 ++++ src/lib/decoder/tun.c | 125 +++++++++++++++++++++++++++++++++++++++++++++ src/lib/decoder/tun.h | 4 ++ 7 files changed, 306 insertions(+), 17 deletions(-) create mode 100644 src/lib/decoder/gsmtap.h create mode 100644 src/lib/decoder/out_pcap.c create mode 100644 src/lib/decoder/out_pcap.h create mode 100644 src/lib/decoder/tun.c create mode 100644 src/lib/decoder/tun.h diff --git a/src/lib/decoder/gsmstack.c b/src/lib/decoder/gsmstack.c index ceda6c5..a1f32d8 100644 --- a/src/lib/decoder/gsmstack.c +++ b/src/lib/decoder/gsmstack.c @@ -84,17 +84,17 @@ GS_new(GS_CTX *ctx) 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->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("tvoid.pcap"); -// if (ctx->pcap_fd < 0) -// fprintf(stderr, "cannot open PCAP file: %s\n", strerror(errno)); + ctx->pcap_fd = open_pcap_file("tvoid.pcap"); + if (ctx->pcap_fd < 0) + fprintf(stderr, "cannot open PCAP file: %s\n", strerror(errno)); -// ctx->burst_pcap_fd = open_pcap_file("tvoid-burst.pcap"); -// if (ctx->burst_pcap_fd < 0) -// fprintf(stderr, "cannot open burst PCAP file: %s\n", strerror(errno)); + ctx->burst_pcap_fd = open_pcap_file("tvoid-burst.pcap"); + if (ctx->burst_pcap_fd < 0) + fprintf(stderr, "cannot open burst PCAP file: %s\n", strerror(errno)); return 0; } @@ -118,8 +118,8 @@ GS_process(GS_CTX *ctx, int ts, int type, const unsigned char *src, int fn) /* 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); + write_pcap_packet(ctx->burst_pcap_fd, 0 /* arfcn */, ts, ctx->fn, + 1, type, octified, BURST_BYTES); #if 0 if (ts != 0) { @@ -177,9 +177,9 @@ GS_process(GS_CTX *ctx, int ts, int type, const unsigned char *src, int fn) //DEBUGF("OK TS %d, len %d\n", ts, len); out_gsmdecode(0, 0, ts, ctx->fn - 4, data, len); -// write_interface(ctx->tun_fd, data+1, len-1, ctx->ether_addr); -// write_pcap_packet(ctx->pcap_fd, 0 /* arfcn */, ts, ctx->fn, -// 0, NORMAL, data, len); + 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; @@ -204,4 +204,3 @@ out_gsmdecode(char type, int arfcn, int ts, int fn, char *data, int len) printf("\n"); fflush(stdout); } - diff --git a/src/lib/decoder/gsmstack.h b/src/lib/decoder/gsmstack.h index 7295b08..9355785 100644 --- a/src/lib/decoder/gsmstack.h +++ b/src/lib/decoder/gsmstack.h @@ -29,8 +29,8 @@ typedef struct int tun_fd; unsigned char ether_addr[ETH_ALEN]; -// int pcap_fd; -// int burst_pcap_fd; + int pcap_fd; + int burst_pcap_fd; } GS_CTX; int GS_new(GS_CTX *ctx); diff --git a/src/lib/decoder/gsmtap.h b/src/lib/decoder/gsmtap.h new file mode 100644 index 0000000..1022194 --- /dev/null +++ b/src/lib/decoder/gsmtap.h @@ -0,0 +1,41 @@ +#ifndef _GSMTAP_H +#define _GSMTAP_H + +/* gsmtap header, pseudo-header in front of the actua GSM payload*/ + +#include + +#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/out_pcap.c b/src/lib/decoder/out_pcap.c new file mode 100644 index 0000000..4da5fd6 --- /dev/null +++ b/src/lib/decoder/out_pcap.c @@ -0,0 +1,111 @@ +/* PCAP support for gsm-tvoid + * (C) 2008 by Harald Welte + */ + +#include +#include +#include +#include +#include +#include + +#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 new file mode 100644 index 0000000..5ae5e3c --- /dev/null +++ b/src/lib/decoder/out_pcap.h @@ -0,0 +1,9 @@ +#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/tun.c b/src/lib/decoder/tun.c new file mode 100644 index 0000000..2abda90 --- /dev/null +++ b/src/lib/decoder/tun.c @@ -0,0 +1,125 @@ +// $Id: tun.cc,v 1.2 2007-07-07 16:31:42 jl Exp $ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 new file mode 100644 index 0000000..a7868c4 --- /dev/null +++ b/src/lib/decoder/tun.h @@ -0,0 +1,4 @@ +// $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 *); -- cgit v1.2.3 From 59d16fcfe6b32c36fdbe64c594234fa96473dc70 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Mon, 22 Jun 2009 17:56:04 +0200 Subject: added Harald's code for pcap output --- src/lib/decoder/Makefile.am | 7 ++++++- src/lib/decoder/gsmstack.c | 4 ++-- src/lib/gsm_receiver_cf.cc | 6 ++---- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/lib/decoder/Makefile.am b/src/lib/decoder/Makefile.am index 3a3e3f5..1ad7899 100644 --- a/src/lib/decoder/Makefile.am +++ b/src/lib/decoder/Makefile.am @@ -30,6 +30,8 @@ libdecoder_la_SOURCES = \ cch.c \ fire_crc.c \ gsmstack.c \ + out_pcap.c \ + tun.c \ interleave.c noinst_HEADERS = \ @@ -38,6 +40,9 @@ noinst_HEADERS = \ fire_crc.h \ gsmstack.h \ interleave.h \ - system.h + system.h \ + out_pcap.h \ + tun.h \ + gsmtap.h # burst_types.h diff --git a/src/lib/decoder/gsmstack.c b/src/lib/decoder/gsmstack.c index a1f32d8..c3f1921 100644 --- a/src/lib/decoder/gsmstack.c +++ b/src/lib/decoder/gsmstack.c @@ -88,11 +88,11 @@ GS_new(GS_CTX *ctx) if (ctx->tun_fd < 0) fprintf(stderr, "cannot open 'gsm' tun device, did you create it?\n"); - ctx->pcap_fd = open_pcap_file("tvoid.pcap"); + 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("tvoid-burst.pcap"); + 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)); diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index e314381..2081e07 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -42,13 +42,11 @@ void gsm_receiver_cf::process_normal_burst(burst_counter burst_nr, const unsigned char * burst_binary) { if (burst_nr.get_timeslot_nr() == 0) { -// std::cout << " t2:" << burst_nr.get_t2() << " fn:" << burst_nr.get_frame_nr(); -// printf(" burst = [ "); +// printf(" %2d %6x %6x", burst_nr.get_t2(), burst_nr.get_frame_nr(), burst_nr.get_frame_nr_mod()); // for (int i = 0; i < BURST_SIZE ; i++) { // printf(" %d", burst_binary[i]); // } -// printf("];\n"); -// std::cout << " t2: " << burst_nr.get_t2() << "\n"; +// std::cout << "\n"; // std::cout << " bcc: " << d_bcc << "\n"; GS_process(&d_gs_ctx, TIMESLOT0, 6, &burst_binary[3], burst_nr.get_frame_nr()); } -- cgit v1.2.3 From 182d18994b05d8ca886eed5bb876791a63c3833e Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Mon, 22 Jun 2009 20:45:58 +0200 Subject: little changes for TCH/F listening --- src/lib/decoder/AUTHORS | 1 + src/lib/gsm_receiver_cf.cc | 4 ++-- src/lib/gsm_receiver_config.h | 4 ++++ 3 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 src/lib/decoder/AUTHORS diff --git a/src/lib/decoder/AUTHORS b/src/lib/decoder/AUTHORS new file mode 100644 index 0000000..dcc5998 --- /dev/null +++ b/src/lib/decoder/AUTHORS @@ -0,0 +1 @@ +Harald Welte diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index 2081e07..f94e303 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -59,8 +59,8 @@ void gsm_receiver_cf::configure_receiver() 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(TIMESLOT7, multiframe_26); -// d_channel_conf.set_burst_types(TIMESLOT7, 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); } diff --git a/src/lib/gsm_receiver_config.h b/src/lib/gsm_receiver_config.h index 25a3efc..b7ba43a 100644 --- a/src/lib/gsm_receiver_config.h +++ b/src/lib/gsm_receiver_config.h @@ -122,6 +122,10 @@ class burst_counter 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; -- cgit v1.2.3 From 81c29dbb877de8a39019ad1947936245d4c34207 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Tue, 23 Jun 2009 16:19:52 +0200 Subject: added a5-1-2.c for decryption --- src/lib/decoder/a5-1-2.c | 429 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 429 insertions(+) create mode 100644 src/lib/decoder/a5-1-2.c diff --git a/src/lib/decoder/a5-1-2.c b/src/lib/decoder/a5-1-2.c new file mode 100644 index 0000000..64370d2 --- /dev/null +++ b/src/lib/decoder/a5-1-2.c @@ -0,0 +1,429 @@ +/* + * 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 + * Voice: +1 (925) 798-4042 + * + */ + + +#include + + +/* 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[8], word frame) { + int i; + bit keybit, framebit; + + + /* 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)); + } +} + + +/* 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"); + } +} + + +int main(void) { + test(); + return 0; +} \ No newline at end of file -- cgit v1.2.3 From f1df46a5c04d38f155cd8f8c8315eeb1f3fc7c2e Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Sat, 27 Jun 2009 13:14:30 +0200 Subject: added files from openbts for tch/f decoding and removed openbts --- src/lib/decoder/openbtsstuff/AUTHORS | 173 +++++++++ src/lib/decoder/openbtsstuff/Assert.h | 49 +++ src/lib/decoder/openbtsstuff/BitVector.cpp | 513 ++++++++++++++++++++++++ src/lib/decoder/openbtsstuff/BitVector.h | 427 ++++++++++++++++++++ src/lib/decoder/openbtsstuff/GSM610Tables.cpp | 492 +++++++++++++++++++++++ src/lib/decoder/openbtsstuff/GSM610Tables.h | 37 ++ src/lib/decoder/openbtsstuff/GSMCommon.cpp | 315 +++++++++++++++ src/lib/decoder/openbtsstuff/GSMCommon.h | 537 ++++++++++++++++++++++++++ src/lib/decoder/openbtsstuff/GSML1FEC.cpp | 256 ++++++++++++ src/lib/decoder/openbtsstuff/GSML1FEC.h | 146 +++++++ src/lib/decoder/openbtsstuff/GSMTDMA.cpp | 337 ++++++++++++++++ src/lib/decoder/openbtsstuff/GSMTDMA.h | 358 +++++++++++++++++ src/lib/decoder/openbtsstuff/Makefile.am | 49 +++ src/lib/decoder/openbtsstuff/RxBurst.h | 69 ++++ src/lib/decoder/openbtsstuff/Threads.cpp | 106 +++++ src/lib/decoder/openbtsstuff/Threads.h | 150 +++++++ src/lib/decoder/openbtsstuff/Timeval.cpp | 93 +++++ src/lib/decoder/openbtsstuff/Timeval.h | 96 +++++ src/lib/decoder/openbtsstuff/Vector.h | 257 ++++++++++++ src/lib/decoder/openbtsstuff/VocoderFrame.h | 25 ++ 20 files changed, 4485 insertions(+) create mode 100644 src/lib/decoder/openbtsstuff/AUTHORS create mode 100644 src/lib/decoder/openbtsstuff/Assert.h create mode 100644 src/lib/decoder/openbtsstuff/BitVector.cpp create mode 100644 src/lib/decoder/openbtsstuff/BitVector.h create mode 100644 src/lib/decoder/openbtsstuff/GSM610Tables.cpp create mode 100644 src/lib/decoder/openbtsstuff/GSM610Tables.h create mode 100644 src/lib/decoder/openbtsstuff/GSMCommon.cpp create mode 100644 src/lib/decoder/openbtsstuff/GSMCommon.h create mode 100644 src/lib/decoder/openbtsstuff/GSML1FEC.cpp create mode 100644 src/lib/decoder/openbtsstuff/GSML1FEC.h create mode 100644 src/lib/decoder/openbtsstuff/GSMTDMA.cpp create mode 100644 src/lib/decoder/openbtsstuff/GSMTDMA.h create mode 100644 src/lib/decoder/openbtsstuff/Makefile.am create mode 100644 src/lib/decoder/openbtsstuff/RxBurst.h create mode 100644 src/lib/decoder/openbtsstuff/Threads.cpp create mode 100644 src/lib/decoder/openbtsstuff/Threads.h create mode 100644 src/lib/decoder/openbtsstuff/Timeval.cpp create mode 100644 src/lib/decoder/openbtsstuff/Timeval.h create mode 100644 src/lib/decoder/openbtsstuff/Vector.h create mode 100644 src/lib/decoder/openbtsstuff/VocoderFrame.h diff --git a/src/lib/decoder/openbtsstuff/AUTHORS b/src/lib/decoder/openbtsstuff/AUTHORS new file mode 100644 index 0000000..8075492 --- /dev/null +++ b/src/lib/decoder/openbtsstuff/AUTHORS @@ -0,0 +1,173 @@ +# +# 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 new file mode 100644 index 0000000..00ad07d --- /dev/null +++ b/src/lib/decoder/openbtsstuff/Assert.h @@ -0,0 +1,49 @@ +/* +* 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 . + +*/ + + +#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 new file mode 100644 index 0000000..89d8d19 --- /dev/null +++ b/src/lib/decoder/openbtsstuff/BitVector.cpp @@ -0,0 +1,513 @@ +/* +* 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 . + +*/ + + + + +#include "BitVector.h" +#include + +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>i; + return sum & 0x01; +} + + + + + + +BitVector::BitVector(const char *valString) + :Vector(strlen(valString)) +{ + uint32_t accum = 0; + for (size_t i=0; i=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=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 (dpiState) << 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>1)&0x01][0]; + } +} + + +void ViterbiR2O4::pruneCandidates() +{ + const vCand* c1 = mCandidates; // 0-prefix + const vCand* c2 = mCandidates + mIStates; // 1-prefix + for (unsigned i=0; i=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; i0.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; i0.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=deferral) *op++ = (minCost.iState >> deferral); + oCount++; + } + } +} + + + + +ostream& operator<<(ostream& os, const SoftVector& sv) +{ + for (size_t i=0; i0.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. + +*/ + + +#ifndef FECVECTORS_H +#define FECVECTORS_H + +#include "Vector.h" +#include + + +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<>(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< { + + + public: + + /**@name Constructors. */ + //@{ + + /**@name Casts of Vector constructors. */ + //@{ + BitVector(char* wData, char* wStart, char* wEnd) + :Vector(wData,wStart,wEnd) + { } + BitVector(size_t len=0):Vector(len) {} + BitVector(const Vector& source):Vector(source) {} + BitVector(Vector& source):Vector(source) {} + BitVector(const Vector& source1, const Vector source2):Vector(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::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 { + + public: + + /** Build a SoftVector of a given length. */ + SoftVector(size_t wSize=0):Vector(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(wData,length) + {} + + SoftVector(float* wData, float* wStart, float* wEnd) + :Vector(wData,wStart,wEnd) + { } + + /** + Casting from a Vector. + Note that this is NOT pass-by-reference. + */ + SoftVector(Vector source) + :Vector(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::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(dp0.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 new file mode 100644 index 0000000..38f643f --- /dev/null +++ b/src/lib/decoder/openbtsstuff/GSM610Tables.cpp @@ -0,0 +1,492 @@ +/* +* 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 . + +*/ + + + +#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 new file mode 100644 index 0000000..53a8e1c --- /dev/null +++ b/src/lib/decoder/openbtsstuff/GSM610Tables.h @@ -0,0 +1,37 @@ +/* +* 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 . + +*/ + + + +#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 new file mode 100644 index 0000000..0bec812 --- /dev/null +++ b/src/lib/decoder/openbtsstuff/GSMCommon.cpp @@ -0,0 +1,315 @@ +/* +* 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 . + +*/ + + +#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='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 new file mode 100644 index 0000000..9dc1c95 --- /dev/null +++ b/src/lib/decoder/openbtsstuff/GSMCommon.h @@ -0,0 +1,537 @@ +/**@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 . + +*/ + + + +#ifndef GSMCOMMON_H +#define GSMCOMMON_H + +#include +#include +#include +#include + +#include +#include +#include + + + + +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(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 new file mode 100644 index 0000000..1c99a0f --- /dev/null +++ b/src/lib/decoder/openbtsstuff/GSML1FEC.cpp @@ -0,0 +1,256 @@ +/* +* 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 . + +*/ + + +#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="< + + + +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 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 new file mode 100644 index 0000000..27ebe0e --- /dev/null +++ b/src/lib/decoder/openbtsstuff/GSMTDMA.cpp @@ -0,0 +1,337 @@ +/* +* 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 . + +*/ + + +#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. + +*/ + + + +#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<. + +*/ + + + + +#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 new file mode 100644 index 0000000..14cff04 --- /dev/null +++ b/src/lib/decoder/openbtsstuff/Threads.h @@ -0,0 +1,150 @@ +/* +* 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 . + +*/ + + +#ifndef THREADS_H +#define THREADS_H + + +#include +#include +#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 new file mode 100644 index 0000000..e7590cb --- /dev/null +++ b/src/lib/decoder/openbtsstuff/Timeval.cpp @@ -0,0 +1,93 @@ +/* +* 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 . + +*/ + + + +#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 new file mode 100644 index 0000000..44618bc --- /dev/null +++ b/src/lib/decoder/openbtsstuff/Timeval.h @@ -0,0 +1,96 @@ +/* +* 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 . + +*/ + + +#ifndef TIMEVAL_H +#define TIMEVAL_H + +#include "sys/time.h" +#include + + + +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 new file mode 100644 index 0000000..cec278a --- /dev/null +++ b/src/lib/decoder/openbtsstuff/Vector.h @@ -0,0 +1,257 @@ +/**@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 . + +*/ + + + + +#ifndef VECTOR_H +#define VECTOR_H + +#include +#include +#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 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& 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& other) + :mData(other.mData),mStart(other.mStart),mEnd(other.mEnd) + { other.mData=NULL; } + + /** Build a Vector by copying another. */ + Vector(const Vector& 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& other1, const Vector& 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& other) + { + clear(); + mData=other.mData; + mStart=other.mStart; + mEnd=other.mEnd; + other.mData=NULL; + } + + /** Assign from another Vector, copying. */ + void operator=(const Vector& other) { clone(other); } + + //@} + + + //@{ + + /** Return an alias to a segment of this Vector. */ + Vector segment(size_t start, size_t span) + { + T* wStart = mStart + start; + T* wEnd = wStart + span; + assert(wEnd<=mEnd); + return Vector(NULL,wStart,wEnd); + } + + /** Return an alias to a segment of this Vector. */ + const Vector segment(size_t start, size_t span) const + { + T* wStart = mStart + start; + T* wEnd = wStart + span; + assert(wEnd<=mEnd); + return Vector(NULL,wStart,wEnd); + } + + Vector head(size_t span) { return segment(0,span); } + const Vector head(size_t span) const { return segment(0,span); } + Vector tail(size_t start) { return segment(start,size()-start); } + const Vector 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& 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& other, size_t start=0) const { copyToSegment(other,start,size()); } + + void copyTo(Vector& 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& 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 +std::ostream& operator<<(std::ostream& os, const Vector& v) +{ + for (unsigned i=0; i Date: Sat, 27 Jun 2009 13:18:13 +0200 Subject: added dirty tch/f decoding to gsm-receiver (which also should be removed in the future) --- INSTALL | 2 +- Makefile.am | 16 +- Makefile.common | 15 +- bootstrap | 2 +- configure.ac | 10 +- src/lib/Makefile.am | 10 +- src/lib/decoder/Makefile.am | 28 ++- src/lib/decoder/a5-1-2.c | 429 ----------------------------------------- src/lib/gsm.i | 2 +- src/lib/gsm_constants.h | 7 +- src/lib/gsm_receiver_cf.cc | 163 ++++++++++++++-- src/lib/gsm_receiver_cf.h | 31 ++- src/python/gsm_receive.py | 7 +- src/python/gsm_receive_usrp.py | 2 +- 14 files changed, 225 insertions(+), 499 deletions(-) delete mode 100644 src/lib/decoder/a5-1-2.c diff --git a/INSTALL b/INSTALL index b9fb61c..314b196 100644 --- a/INSTALL +++ b/INSTALL @@ -9,5 +9,5 @@ Under Ubuntu 9.04 install: To build the GSM Receiver use: $ ./bootstrap $ cd debug - $ ./configure + $ ../configure $ make diff --git a/Makefile.am b/Makefile.am index 863aebb..734941a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,17 +3,11 @@ include $(top_srcdir)/Makefile.common SUBDIRS = src config DIST_SUBDIRS = src config -#EXTRA_DIST = \ -# bootstrap \ -# configure \ -# config.h.in -# gsm-receiver.pc.in - -#pkgconfigdir = $(libdir)/pkgconfig -#pkgconfig_DATA = gsm-receiver.pc - EXTRA_DIST = \ - gsm-receiver.pc.in - + configure \ + gsm-receiver.pc.in \ + config.h.in +# bootstrap + pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = gsm-receiver.pc diff --git a/Makefile.common b/Makefile.common index e662909..0b88813 100644 --- a/Makefile.common +++ b/Makefile.common @@ -19,15 +19,20 @@ # the Free Software Foundation, Inc., 51 Franklin Street, # Boston, MA 02110-1301, USA. # -DECODER_INCLUDEDIR = $(top_srcdir)/src/lib/decoder -MAIN_INCLUDEDIR = $(top_srcdir)/src/lib -#STD_DEFINES_AND_INCLUDES = \ -# -I$(DECODER_INCLUDEDIR) \ -# -I$(MAIN_INCLUDEDIR) +#!! remove this +TCH_DECODER_INCLUDEDIR = $(top_srcdir)/src/lib/decoder/openbtsstuff +MAIN_INCLUDEDIR = $(top_srcdir)/src/lib +DECODER_INCLUDEDIR = $(top_srcdir)/src/lib/decoder DECODER_LA = $(top_builddir)/src/lib/decoder/libdecoder.la +STD_DEFINES_AND_INCLUDES = \ + -I$(DECODER_INCLUDEDIR) \ + -I$(MAIN_INCLUDEDIR) \ + -I$(GNURADIO_CORE_INCLUDEDIR) \ + -I$(TCH_DECODER_INCLUDEDIR) + # includes grincludedir = $(includedir)/gnuradio diff --git a/bootstrap b/bootstrap index 350e0ff..7e0a2eb 100755 --- a/bootstrap +++ b/bootstrap @@ -29,4 +29,4 @@ libtoolize --automake automake --add-missing if test ! -d debug; then mkdir debug -fi \ No newline at end of file +fi diff --git a/configure.ac b/configure.ac index 709ac12..30fe57a 100644 --- a/configure.ac +++ b/configure.ac @@ -99,7 +99,8 @@ GR_REQUIRE_BOOST_INCLUDES STD_DEFINES_AND_INCLUDES="$GNURADIO_CORE_CFLAGS $BOOST_CFLAGS" AC_SUBST(STD_DEFINES_AND_INCLUDES) - + + AC_CONFIG_FILES([\ Makefile \ config/Makefile \ @@ -107,10 +108,11 @@ AC_CONFIG_FILES([\ src/lib/Makefile \ src/lib/decoder/Makefile \ src/python/Makefile \ - gsm-receiver.pc + src/lib/decoder/openbtsstuff/Makefile \ + gsm-receiver.pc \ ]) -# doc/Makefile \ -# src/python/run_tests \ +dnl # doc/Makefile \ +dnl # src/python/run_tests \ dnl run_tests is created from run_tests.in. Make it executable. #AC_CONFIG_COMMANDS([run_tests], [chmod +x src/python/run_tests]) diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 91819fa..925eaca 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -29,7 +29,8 @@ SUBDIRS = decoder ourpythondir = $(grpythondir) ourlibdir = $(grpyexecdir) -AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(WITH_INCLUDES) -I$(DECODER_INCLUDEDIR) +AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(WITH_INCLUDES) +# -I$(OPEN_BTS_INCLUDES) SWIGPYTHONARGS = $(SWIGPYTHONFLAGS) $(SWIGGRFLAGS) $(WITH_SWIG_INCLUDES) \ $(WITH_INCLUDES) @@ -76,11 +77,10 @@ _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 \ + $(PYTHON_LDFLAGS) \ + libgsmdemod.la \ -lstdc++ \ - decoder/libdecoder.la -# $(DECODER_LA) + $(DECODER_LA) #libgsmdemod_la_LIBADD = diff --git a/src/lib/decoder/Makefile.am b/src/lib/decoder/Makefile.am index 1ad7899..1726d68 100644 --- a/src/lib/decoder/Makefile.am +++ b/src/lib/decoder/Makefile.am @@ -21,28 +21,36 @@ include $(top_srcdir)/Makefile.common -AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) -I$(MAIN_INCLUDEDIR) +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 \ - interleave.c - -noinst_HEADERS = \ - sch.h \ + tun.c +# tch.c \ +# conv.c + +noinst_HEADERS = \ + sch.h \ cch.h \ fire_crc.h \ gsmstack.h \ interleave.h \ - system.h \ out_pcap.h \ tun.h \ - gsmtap.h - -# burst_types.h + system.h \ + gsmtap.h \ + a5-1-2.h +# tch.h \ +# conv.h diff --git a/src/lib/decoder/a5-1-2.c b/src/lib/decoder/a5-1-2.c deleted file mode 100644 index 64370d2..0000000 --- a/src/lib/decoder/a5-1-2.c +++ /dev/null @@ -1,429 +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 - * Voice: +1 (925) 798-4042 - * - */ - - -#include - - -/* 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[8], word frame) { - int i; - bit keybit, framebit; - - - /* 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)); - } -} - - -/* 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"); - } -} - - -int main(void) { - test(); - return 0; -} \ No newline at end of file diff --git a/src/lib/gsm.i b/src/lib/gsm.i index b5a33f2..3a5c561 100644 --- a/src/lib/gsm.i +++ b/src/lib/gsm.i @@ -38,7 +38,7 @@ 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); +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 { diff --git a/src/lib/gsm_constants.h b/src/lib/gsm_constants.h index 74d2e2e..939099d 100644 --- a/src/lib/gsm_constants.h +++ b/src/lib/gsm_constants.h @@ -9,10 +9,11 @@ #define GUARD_BITS 8 #define GUARD_FRACTIONAL 0.25 //fractional part of guard period #define GUARD_PERIOD GUARD_BITS + GUARD_FRACTIONAL -#define DATA_BITS 58 //size of 1 data block in normal burst +#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 + N_TRAIN_BITS ) +#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) @@ -22,7 +23,7 @@ #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 + 5) //first 5 bits of a training sequence +#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 // diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index f94e303..4742b33 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -33,21 +33,102 @@ #include #include #include +#include #include + +#include "RxBurst.h" +#include "GSMCommon.h" + #define SYNC_SEARCH_RANGE 30 -#define TRAIN_SEARCH_RANGE 40 +// #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) { - if (burst_nr.get_timeslot_nr() == 0) { -// printf(" %2d %6x %6x", burst_nr.get_t2(), burst_nr.get_frame_nr(), burst_nr.get_frame_nr_mod()); -// for (int i = 0; i < BURST_SIZE ; i++) { -// printf(" %d", burst_binary[i]); -// } -// std::cout << "\n"; -// std::cout << " bcc: " << d_bcc << "\n"; +// 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()); } } @@ -59,8 +140,24 @@ void gsm_receiver_cf::configure_receiver() 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); + } @@ -70,9 +167,9 @@ typedef std::vector vector_float; typedef boost::circular_buffer circular_buffer_float; gsm_receiver_cf_sptr -gsm_make_receiver_cf(gr_feval_dd *tuner, gr_feval_dd *synchronizer, int osr) +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)); + return gsm_receiver_cf_sptr(new gsm_receiver_cf(tuner, synchronizer, osr, key)); } static const int MIN_IN = 1; // mininum number of input streams @@ -83,7 +180,7 @@ 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) +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))), @@ -95,15 +192,21 @@ gsm_receiver_cf::gsm_receiver_cf(gr_feval_dd *tuner, gr_feval_dd *synchronizer, d_freq_offset(0), d_state(first_fcch_search), d_burst_nr(osr), - d_failed_sch(0) + 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 negative values + 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 @@ -111,7 +214,25 @@ gsm_receiver_cf::gsm_receiver_cf(gr_feval_dd *tuner, gr_feval_dd *synchronizer, 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 } @@ -153,7 +274,7 @@ gsm_receiver_cf::general_work(int noutput_items, 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 + 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 @@ -253,13 +374,13 @@ gsm_receiver_cf::general_work(int noutput_items, break; case normal_burst: //if it's normal burst - burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], TRAIN_SEARCH_RANGE, d_bcc); //get channel impulse response for given training sequence number - d_bcc + 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], TRAIN_SEARCH_RANGE, TS_DUMMY); + 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 v(20); @@ -268,7 +389,7 @@ gsm_receiver_cf::general_work(int noutput_items, int different_bits = (it - v.begin()); if (different_bits > 2) { - burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], TRAIN_SEARCH_RANGE, d_bcc); + 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 @@ -283,7 +404,7 @@ gsm_receiver_cf::general_work(int noutput_items, break; case dummy: //if it's dummy - burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], TRAIN_SEARCH_RANGE, TS_DUMMY); //read 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 @@ -652,7 +773,7 @@ inline void gsm_receiver_cf::mafi(const gr_complex * input, int nitems, gr_compl //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, unsigned search_range, int bcc) +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; diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index 9454997..21cb1ff 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -31,13 +31,17 @@ #include #include //TODO: remember to remove this line in the future! +#include "GSML1FEC.h" //!! +#include //!! +#include //!! +#include //!! class gsm_receiver_cf; typedef boost::shared_ptr gsm_receiver_cf_sptr; typedef std::vector vector_complex; -gsm_receiver_cf_sptr gsm_make_receiver_cf(gr_feval_dd *tuner, gr_feval_dd *synchronizer, int osr); +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 * @@ -50,7 +54,16 @@ gsm_receiver_cf_sptr gsm_make_receiver_cf(gr_feval_dd *tuner, gr_feval_dd *synch class gsm_receiver_cf : public gr_block { private: - + std::map 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 @@ -104,8 +117,8 @@ class gsm_receiver_cf : public gr_block // 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); - gsm_receiver_cf(gr_feval_dd *tuner, gr_feval_dd *synchronizer, int osr); + 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 @@ -209,8 +222,14 @@ class gsm_receiver_cf : public gr_block * @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, unsigned search_range, int bcc); + int get_norm_chan_imp_resp(const gr_complex * input, gr_complex * chan_imp_resp, int bcc); + + /** + * + */ + void read_key(std::string key); + /** * */ @@ -220,6 +239,8 @@ class gsm_receiver_cf : public gr_block * */ void configure_receiver(); + + public: ~gsm_receiver_cf(); diff --git a/src/python/gsm_receive.py b/src/python/gsm_receive.py index 40c1520..4cfb876 100755 --- a/src/python/gsm_receive.py +++ b/src/python/gsm_receive.py @@ -6,7 +6,7 @@ from gnuradio.eng_option import eng_option from optparse import OptionParser from os import sys -for extdir in ['../../debug/src/lib','../../debug/src/lib/.libs']: +for extdir in ['../../debug/src/lib','../../debug/src/lib/.libs','../lib','../lib/.libs','../..debug/src/lib/decoder/openbts/SIP']: if extdir not in sys.path: sys.path.append(extdir) import gsm @@ -82,7 +82,7 @@ class gsm_receiver_first_blood(gr.top_block): return interpolator def _set_receiver(self): - receiver = gsm.receiver_cf(self.tuner_callback, self.synchronizer_callback, self.options.osr) + receiver = gsm.receiver_cf(self.tuner_callback, self.synchronizer_callback, self.options.osr, self.options.key.replace(' ', '').lower()) return receiver def _process_options(self): @@ -95,6 +95,9 @@ class gsm_receiver_first_blood(gr.top_block): help="Input filename") parser.add_option("-O", "--outputfile", type="string", default="cfile2.out", help="Output filename") + parser.add_option("-k", "--key", type="string", default="2B 08 74 9F DD 0D 9C 00", + help="KC session key") + (options, args) = parser.parse_args () return (options, args) diff --git a/src/python/gsm_receive_usrp.py b/src/python/gsm_receive_usrp.py index 7d28633..a4e9720 100755 --- a/src/python/gsm_receive_usrp.py +++ b/src/python/gsm_receive_usrp.py @@ -1,6 +1,6 @@ #!/usr/bin/env python #this file isn't ready to use now - gsm-receiver lacks realtime processing capability -#there are many underruns of buffer from usrp's samples, many blocks of samples get lost and +#there are many underruns of buffer for samples from usrp's, many blocks of samples get lost and #receiver isn't prepared for this situation too well from gnuradio import gr, gru, blks2 -- cgit v1.2.3 From 154e4669cf35b803d497c721bad899fbb5bfc33a Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Sun, 28 Jun 2009 15:50:28 +0200 Subject: added missing a5-1-2.h --- src/lib/decoder/a5-1-2.h | 453 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 453 insertions(+) create mode 100644 src/lib/decoder/a5-1-2.h diff --git a/src/lib/decoder/a5-1-2.h b/src/lib/decoder/a5-1-2.h new file mode 100644 index 0000000..de764ee --- /dev/null +++ b/src/lib/decoder/a5-1-2.h @@ -0,0 +1,453 @@ +/* + * 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 + * Voice: +1 (925) 798-4042 + * + */ + + +#include + + +/* 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"); + } +} + -- cgit v1.2.3 From 8f97a59b21fd8d3ecd111ee770932d852e625d52 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Sun, 28 Jun 2009 16:11:56 +0200 Subject: added .gitignore for config dir --- config/.gitignore | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 config/.gitignore diff --git a/config/.gitignore b/config/.gitignore new file mode 100644 index 0000000..38066dd --- /dev/null +++ b/config/.gitignore @@ -0,0 +1,5 @@ +libtool.m4 +ltoptions.m4 +ltsugar.m4 +ltversion.m4 +lt~obsolete.m4 -- cgit v1.2.3 From 8d2bc49fb9e0c9a5fbd75aa3cad207608e72bf99 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Tue, 30 Jun 2009 23:03:33 +0200 Subject: moved gsm-receiver into directory - preparation to move to airprobe --- .gitignore | 25 - AUTHORS | 1 - CHANGELOG | 0 COPYING | 674 ---------------- ChangeLog | 0 Doxyfile | 316 -------- INSTALL | 13 - Makefile.am | 13 - Makefile.common | 57 -- NEWS | 0 README | 5 - bootstrap | 32 - config/.gitignore | 5 - config/Makefile.am | 70 -- config/acx_pthread.m4 | 190 ----- config/bnv_have_qt.m4 | 404 ---------- config/cppunit.m4 | 80 -- config/gr_boost.m4 | 111 --- config/gr_check_createfilemapping.m4 | 52 -- config/gr_check_mc4020.m4 | 37 - config/gr_check_shm_open.m4 | 29 - config/gr_check_usrp.m4 | 32 - config/gr_doxygen.m4 | 59 -- config/gr_gprof.m4 | 72 -- config/gr_libgnuradio_core_extra_ldflags.m4 | 40 - config/gr_no_undefined.m4 | 44 -- config/gr_omnithread.m4 | 51 -- config/gr_pwin32.m4 | 146 ---- config/gr_python.m4 | 111 --- config/gr_require_mc4020.m4 | 33 - config/gr_scripting.m4 | 30 - config/gr_set_md_cpu.m4 | 44 -- config/gr_swig.m4 | 85 -- config/gr_sysv_shm.m4 | 36 - config/gr_x86_64.m4 | 39 - config/lf_cc.m4 | 42 - config/lf_cxx.m4 | 121 --- config/lf_warnings.m4 | 128 ---- config/lf_x11.m4 | 39 - config/mkstemp.m4 | 89 --- config/onceonly.m4 | 63 -- config/pkg.m4 | 68 -- config/usrp_fusb_tech.m4 | 56 -- config/usrp_libusb.m4 | 43 -- config/usrp_sdcc.m4 | 67 -- configure.ac | 120 --- gsm-receiver.pc.in | 11 - gsm-receiver/.gitignore | 25 + gsm-receiver/AUTHORS | 1 + gsm-receiver/CHANGELOG | 0 gsm-receiver/COPYING | 674 ++++++++++++++++ gsm-receiver/ChangeLog | 0 gsm-receiver/Doxyfile | 316 ++++++++ gsm-receiver/INSTALL | 13 + gsm-receiver/Makefile.am | 13 + gsm-receiver/Makefile.common | 57 ++ gsm-receiver/NEWS | 0 gsm-receiver/README | 5 + gsm-receiver/bootstrap | 32 + gsm-receiver/config/.gitignore | 5 + gsm-receiver/config/Makefile.am | 70 ++ gsm-receiver/config/acx_pthread.m4 | 190 +++++ gsm-receiver/config/bnv_have_qt.m4 | 404 ++++++++++ gsm-receiver/config/cppunit.m4 | 80 ++ gsm-receiver/config/gr_boost.m4 | 111 +++ gsm-receiver/config/gr_check_createfilemapping.m4 | 52 ++ gsm-receiver/config/gr_check_mc4020.m4 | 37 + gsm-receiver/config/gr_check_shm_open.m4 | 29 + gsm-receiver/config/gr_check_usrp.m4 | 32 + gsm-receiver/config/gr_doxygen.m4 | 59 ++ gsm-receiver/config/gr_gprof.m4 | 72 ++ .../config/gr_libgnuradio_core_extra_ldflags.m4 | 40 + gsm-receiver/config/gr_no_undefined.m4 | 44 ++ gsm-receiver/config/gr_omnithread.m4 | 51 ++ gsm-receiver/config/gr_pwin32.m4 | 146 ++++ gsm-receiver/config/gr_python.m4 | 111 +++ gsm-receiver/config/gr_require_mc4020.m4 | 33 + gsm-receiver/config/gr_scripting.m4 | 30 + gsm-receiver/config/gr_set_md_cpu.m4 | 44 ++ gsm-receiver/config/gr_swig.m4 | 85 ++ gsm-receiver/config/gr_sysv_shm.m4 | 36 + gsm-receiver/config/gr_x86_64.m4 | 39 + gsm-receiver/config/lf_cc.m4 | 42 + gsm-receiver/config/lf_cxx.m4 | 121 +++ gsm-receiver/config/lf_warnings.m4 | 128 ++++ gsm-receiver/config/lf_x11.m4 | 39 + gsm-receiver/config/mkstemp.m4 | 89 +++ gsm-receiver/config/onceonly.m4 | 63 ++ gsm-receiver/config/pkg.m4 | 68 ++ gsm-receiver/config/usrp_fusb_tech.m4 | 56 ++ gsm-receiver/config/usrp_libusb.m4 | 43 ++ gsm-receiver/config/usrp_sdcc.m4 | 67 ++ gsm-receiver/configure.ac | 120 +++ gsm-receiver/gsm-receiver.pc.in | 11 + gsm-receiver/py-compile | 146 ++++ gsm-receiver/src/Makefile.am | 23 + gsm-receiver/src/lib/Assert.h | 67 ++ gsm-receiver/src/lib/Makefile.am | 109 +++ gsm-receiver/src/lib/decoder/AUTHORS | 1 + gsm-receiver/src/lib/decoder/Makefile.am | 56 ++ gsm-receiver/src/lib/decoder/a5-1-2.h | 453 +++++++++++ gsm-receiver/src/lib/decoder/burst_types.h | 214 ++++++ gsm-receiver/src/lib/decoder/cch.c | 482 ++++++++++++ gsm-receiver/src/lib/decoder/cch.h | 56 ++ gsm-receiver/src/lib/decoder/fire_crc.c | 179 +++++ gsm-receiver/src/lib/decoder/fire_crc.h | 47 ++ gsm-receiver/src/lib/decoder/gsmstack.c | 206 +++++ gsm-receiver/src/lib/decoder/gsmstack.h | 43 ++ gsm-receiver/src/lib/decoder/gsmtap.h | 41 + gsm-receiver/src/lib/decoder/interleave.c | 47 ++ gsm-receiver/src/lib/decoder/interleave.h | 19 + gsm-receiver/src/lib/decoder/openbtsstuff/AUTHORS | 173 +++++ gsm-receiver/src/lib/decoder/openbtsstuff/Assert.h | 49 ++ .../src/lib/decoder/openbtsstuff/BitVector.cpp | 513 +++++++++++++ .../src/lib/decoder/openbtsstuff/BitVector.h | 427 +++++++++++ .../src/lib/decoder/openbtsstuff/GSM610Tables.cpp | 492 ++++++++++++ .../src/lib/decoder/openbtsstuff/GSM610Tables.h | 37 + .../src/lib/decoder/openbtsstuff/GSMCommon.cpp | 315 ++++++++ .../src/lib/decoder/openbtsstuff/GSMCommon.h | 537 +++++++++++++ .../src/lib/decoder/openbtsstuff/GSML1FEC.cpp | 256 +++++++ .../src/lib/decoder/openbtsstuff/GSML1FEC.h | 146 ++++ .../src/lib/decoder/openbtsstuff/GSMTDMA.cpp | 337 ++++++++ .../src/lib/decoder/openbtsstuff/GSMTDMA.h | 358 +++++++++ .../src/lib/decoder/openbtsstuff/Makefile.am | 49 ++ .../src/lib/decoder/openbtsstuff/RxBurst.h | 69 ++ .../src/lib/decoder/openbtsstuff/Threads.cpp | 106 +++ .../src/lib/decoder/openbtsstuff/Threads.h | 150 ++++ .../src/lib/decoder/openbtsstuff/Timeval.cpp | 93 +++ .../src/lib/decoder/openbtsstuff/Timeval.h | 96 +++ gsm-receiver/src/lib/decoder/openbtsstuff/Vector.h | 257 +++++++ .../src/lib/decoder/openbtsstuff/VocoderFrame.h | 25 + gsm-receiver/src/lib/decoder/out_pcap.c | 111 +++ gsm-receiver/src/lib/decoder/out_pcap.h | 9 + gsm-receiver/src/lib/decoder/sch.c | 333 ++++++++ gsm-receiver/src/lib/decoder/sch.h | 17 + gsm-receiver/src/lib/decoder/system.h | 11 + gsm-receiver/src/lib/decoder/tun.c | 125 +++ gsm-receiver/src/lib/decoder/tun.h | 4 + gsm-receiver/src/lib/gsm.i | 49 ++ gsm-receiver/src/lib/gsm_constants.h | 150 ++++ gsm-receiver/src/lib/gsm_receiver_cf.cc | 853 +++++++++++++++++++++ gsm-receiver/src/lib/gsm_receiver_cf.h | 254 ++++++ gsm-receiver/src/lib/gsm_receiver_config.cc | 84 ++ gsm-receiver/src/lib/gsm_receiver_config.h | 164 ++++ gsm-receiver/src/lib/viterbi_detector.cc | 554 +++++++++++++ gsm-receiver/src/lib/viterbi_detector.h | 63 ++ gsm-receiver/src/python/Makefile.am | 24 + gsm-receiver/src/python/capture.sh | 45 ++ gsm-receiver/src/python/cfile | Bin 0 -> 640000 bytes gsm-receiver/src/python/go.sh | 12 + gsm-receiver/src/python/gsm_receive.py | 117 +++ gsm-receiver/src/python/gsm_receive_usrp.py | 141 ++++ gsm-receiver/src/python/test.sh | 16 + py-compile | 146 ---- src/Makefile.am | 23 - src/lib/Assert.h | 67 -- src/lib/Makefile.am | 109 --- src/lib/decoder/AUTHORS | 1 - src/lib/decoder/Makefile.am | 56 -- src/lib/decoder/a5-1-2.h | 453 ----------- src/lib/decoder/burst_types.h | 214 ------ src/lib/decoder/cch.c | 482 ------------ src/lib/decoder/cch.h | 56 -- src/lib/decoder/fire_crc.c | 179 ----- src/lib/decoder/fire_crc.h | 47 -- src/lib/decoder/gsmstack.c | 206 ----- src/lib/decoder/gsmstack.h | 43 -- src/lib/decoder/gsmtap.h | 41 - src/lib/decoder/interleave.c | 47 -- src/lib/decoder/interleave.h | 19 - src/lib/decoder/openbtsstuff/AUTHORS | 173 ----- src/lib/decoder/openbtsstuff/Assert.h | 49 -- src/lib/decoder/openbtsstuff/BitVector.cpp | 513 ------------- src/lib/decoder/openbtsstuff/BitVector.h | 427 ----------- src/lib/decoder/openbtsstuff/GSM610Tables.cpp | 492 ------------ src/lib/decoder/openbtsstuff/GSM610Tables.h | 37 - src/lib/decoder/openbtsstuff/GSMCommon.cpp | 315 -------- src/lib/decoder/openbtsstuff/GSMCommon.h | 537 ------------- src/lib/decoder/openbtsstuff/GSML1FEC.cpp | 256 ------- src/lib/decoder/openbtsstuff/GSML1FEC.h | 146 ---- src/lib/decoder/openbtsstuff/GSMTDMA.cpp | 337 -------- src/lib/decoder/openbtsstuff/GSMTDMA.h | 358 --------- src/lib/decoder/openbtsstuff/Makefile.am | 49 -- src/lib/decoder/openbtsstuff/RxBurst.h | 69 -- src/lib/decoder/openbtsstuff/Threads.cpp | 106 --- src/lib/decoder/openbtsstuff/Threads.h | 150 ---- src/lib/decoder/openbtsstuff/Timeval.cpp | 93 --- src/lib/decoder/openbtsstuff/Timeval.h | 96 --- src/lib/decoder/openbtsstuff/Vector.h | 257 ------- src/lib/decoder/openbtsstuff/VocoderFrame.h | 25 - src/lib/decoder/out_pcap.c | 111 --- src/lib/decoder/out_pcap.h | 9 - src/lib/decoder/sch.c | 333 -------- src/lib/decoder/sch.h | 17 - src/lib/decoder/system.h | 11 - src/lib/decoder/tun.c | 125 --- src/lib/decoder/tun.h | 4 - src/lib/gsm.i | 49 -- src/lib/gsm_constants.h | 150 ---- src/lib/gsm_receiver_cf.cc | 853 --------------------- src/lib/gsm_receiver_cf.h | 254 ------ src/lib/gsm_receiver_config.cc | 84 -- src/lib/gsm_receiver_config.h | 164 ---- src/lib/viterbi_detector.cc | 554 ------------- src/lib/viterbi_detector.h | 63 -- src/python/Makefile.am | 24 - src/python/capture.sh | 45 -- src/python/cfile | Bin 640000 -> 0 bytes src/python/go.sh | 12 - src/python/gsm_receive.py | 117 --- src/python/gsm_receive_usrp.py | 141 ---- src/python/test.sh | 16 - 212 files changed, 13593 insertions(+), 13593 deletions(-) delete mode 100644 .gitignore delete mode 100644 AUTHORS delete mode 100644 CHANGELOG delete mode 100644 COPYING delete mode 100644 ChangeLog delete mode 100644 Doxyfile delete mode 100644 INSTALL delete mode 100644 Makefile.am delete mode 100644 Makefile.common delete mode 100644 NEWS delete mode 100644 README delete mode 100755 bootstrap delete mode 100644 config/.gitignore delete mode 100644 config/Makefile.am delete mode 100644 config/acx_pthread.m4 delete mode 100644 config/bnv_have_qt.m4 delete mode 100644 config/cppunit.m4 delete mode 100644 config/gr_boost.m4 delete mode 100644 config/gr_check_createfilemapping.m4 delete mode 100644 config/gr_check_mc4020.m4 delete mode 100644 config/gr_check_shm_open.m4 delete mode 100644 config/gr_check_usrp.m4 delete mode 100644 config/gr_doxygen.m4 delete mode 100644 config/gr_gprof.m4 delete mode 100644 config/gr_libgnuradio_core_extra_ldflags.m4 delete mode 100644 config/gr_no_undefined.m4 delete mode 100644 config/gr_omnithread.m4 delete mode 100644 config/gr_pwin32.m4 delete mode 100644 config/gr_python.m4 delete mode 100644 config/gr_require_mc4020.m4 delete mode 100644 config/gr_scripting.m4 delete mode 100644 config/gr_set_md_cpu.m4 delete mode 100644 config/gr_swig.m4 delete mode 100644 config/gr_sysv_shm.m4 delete mode 100644 config/gr_x86_64.m4 delete mode 100644 config/lf_cc.m4 delete mode 100644 config/lf_cxx.m4 delete mode 100644 config/lf_warnings.m4 delete mode 100644 config/lf_x11.m4 delete mode 100644 config/mkstemp.m4 delete mode 100644 config/onceonly.m4 delete mode 100644 config/pkg.m4 delete mode 100644 config/usrp_fusb_tech.m4 delete mode 100644 config/usrp_libusb.m4 delete mode 100644 config/usrp_sdcc.m4 delete mode 100644 configure.ac delete mode 100644 gsm-receiver.pc.in create mode 100644 gsm-receiver/.gitignore create mode 100644 gsm-receiver/AUTHORS create mode 100644 gsm-receiver/CHANGELOG create mode 100644 gsm-receiver/COPYING create mode 100644 gsm-receiver/ChangeLog create mode 100644 gsm-receiver/Doxyfile create mode 100644 gsm-receiver/INSTALL create mode 100644 gsm-receiver/Makefile.am create mode 100644 gsm-receiver/Makefile.common create mode 100644 gsm-receiver/NEWS create mode 100644 gsm-receiver/README create mode 100755 gsm-receiver/bootstrap create mode 100644 gsm-receiver/config/.gitignore create mode 100644 gsm-receiver/config/Makefile.am create mode 100644 gsm-receiver/config/acx_pthread.m4 create mode 100644 gsm-receiver/config/bnv_have_qt.m4 create mode 100644 gsm-receiver/config/cppunit.m4 create mode 100644 gsm-receiver/config/gr_boost.m4 create mode 100644 gsm-receiver/config/gr_check_createfilemapping.m4 create mode 100644 gsm-receiver/config/gr_check_mc4020.m4 create mode 100644 gsm-receiver/config/gr_check_shm_open.m4 create mode 100644 gsm-receiver/config/gr_check_usrp.m4 create mode 100644 gsm-receiver/config/gr_doxygen.m4 create mode 100644 gsm-receiver/config/gr_gprof.m4 create mode 100644 gsm-receiver/config/gr_libgnuradio_core_extra_ldflags.m4 create mode 100644 gsm-receiver/config/gr_no_undefined.m4 create mode 100644 gsm-receiver/config/gr_omnithread.m4 create mode 100644 gsm-receiver/config/gr_pwin32.m4 create mode 100644 gsm-receiver/config/gr_python.m4 create mode 100644 gsm-receiver/config/gr_require_mc4020.m4 create mode 100644 gsm-receiver/config/gr_scripting.m4 create mode 100644 gsm-receiver/config/gr_set_md_cpu.m4 create mode 100644 gsm-receiver/config/gr_swig.m4 create mode 100644 gsm-receiver/config/gr_sysv_shm.m4 create mode 100644 gsm-receiver/config/gr_x86_64.m4 create mode 100644 gsm-receiver/config/lf_cc.m4 create mode 100644 gsm-receiver/config/lf_cxx.m4 create mode 100644 gsm-receiver/config/lf_warnings.m4 create mode 100644 gsm-receiver/config/lf_x11.m4 create mode 100644 gsm-receiver/config/mkstemp.m4 create mode 100644 gsm-receiver/config/onceonly.m4 create mode 100644 gsm-receiver/config/pkg.m4 create mode 100644 gsm-receiver/config/usrp_fusb_tech.m4 create mode 100644 gsm-receiver/config/usrp_libusb.m4 create mode 100644 gsm-receiver/config/usrp_sdcc.m4 create mode 100644 gsm-receiver/configure.ac create mode 100644 gsm-receiver/gsm-receiver.pc.in create mode 100755 gsm-receiver/py-compile create mode 100644 gsm-receiver/src/Makefile.am create mode 100644 gsm-receiver/src/lib/Assert.h create mode 100644 gsm-receiver/src/lib/Makefile.am create mode 100644 gsm-receiver/src/lib/decoder/AUTHORS create mode 100644 gsm-receiver/src/lib/decoder/Makefile.am create mode 100644 gsm-receiver/src/lib/decoder/a5-1-2.h create mode 100644 gsm-receiver/src/lib/decoder/burst_types.h create mode 100644 gsm-receiver/src/lib/decoder/cch.c create mode 100644 gsm-receiver/src/lib/decoder/cch.h create mode 100644 gsm-receiver/src/lib/decoder/fire_crc.c create mode 100644 gsm-receiver/src/lib/decoder/fire_crc.h create mode 100644 gsm-receiver/src/lib/decoder/gsmstack.c create mode 100644 gsm-receiver/src/lib/decoder/gsmstack.h create mode 100644 gsm-receiver/src/lib/decoder/gsmtap.h create mode 100644 gsm-receiver/src/lib/decoder/interleave.c create mode 100644 gsm-receiver/src/lib/decoder/interleave.h create mode 100644 gsm-receiver/src/lib/decoder/openbtsstuff/AUTHORS create mode 100644 gsm-receiver/src/lib/decoder/openbtsstuff/Assert.h create mode 100644 gsm-receiver/src/lib/decoder/openbtsstuff/BitVector.cpp create mode 100644 gsm-receiver/src/lib/decoder/openbtsstuff/BitVector.h create mode 100644 gsm-receiver/src/lib/decoder/openbtsstuff/GSM610Tables.cpp create mode 100644 gsm-receiver/src/lib/decoder/openbtsstuff/GSM610Tables.h create mode 100644 gsm-receiver/src/lib/decoder/openbtsstuff/GSMCommon.cpp create mode 100644 gsm-receiver/src/lib/decoder/openbtsstuff/GSMCommon.h create mode 100644 gsm-receiver/src/lib/decoder/openbtsstuff/GSML1FEC.cpp create mode 100644 gsm-receiver/src/lib/decoder/openbtsstuff/GSML1FEC.h create mode 100644 gsm-receiver/src/lib/decoder/openbtsstuff/GSMTDMA.cpp create mode 100644 gsm-receiver/src/lib/decoder/openbtsstuff/GSMTDMA.h create mode 100644 gsm-receiver/src/lib/decoder/openbtsstuff/Makefile.am create mode 100644 gsm-receiver/src/lib/decoder/openbtsstuff/RxBurst.h create mode 100644 gsm-receiver/src/lib/decoder/openbtsstuff/Threads.cpp create mode 100644 gsm-receiver/src/lib/decoder/openbtsstuff/Threads.h create mode 100644 gsm-receiver/src/lib/decoder/openbtsstuff/Timeval.cpp create mode 100644 gsm-receiver/src/lib/decoder/openbtsstuff/Timeval.h create mode 100644 gsm-receiver/src/lib/decoder/openbtsstuff/Vector.h create mode 100644 gsm-receiver/src/lib/decoder/openbtsstuff/VocoderFrame.h create mode 100644 gsm-receiver/src/lib/decoder/out_pcap.c create mode 100644 gsm-receiver/src/lib/decoder/out_pcap.h create mode 100644 gsm-receiver/src/lib/decoder/sch.c create mode 100644 gsm-receiver/src/lib/decoder/sch.h create mode 100644 gsm-receiver/src/lib/decoder/system.h create mode 100644 gsm-receiver/src/lib/decoder/tun.c create mode 100644 gsm-receiver/src/lib/decoder/tun.h create mode 100644 gsm-receiver/src/lib/gsm.i create mode 100644 gsm-receiver/src/lib/gsm_constants.h create mode 100644 gsm-receiver/src/lib/gsm_receiver_cf.cc create mode 100644 gsm-receiver/src/lib/gsm_receiver_cf.h create mode 100644 gsm-receiver/src/lib/gsm_receiver_config.cc create mode 100644 gsm-receiver/src/lib/gsm_receiver_config.h create mode 100644 gsm-receiver/src/lib/viterbi_detector.cc create mode 100644 gsm-receiver/src/lib/viterbi_detector.h create mode 100644 gsm-receiver/src/python/Makefile.am create mode 100755 gsm-receiver/src/python/capture.sh create mode 100644 gsm-receiver/src/python/cfile create mode 100755 gsm-receiver/src/python/go.sh create mode 100755 gsm-receiver/src/python/gsm_receive.py create mode 100755 gsm-receiver/src/python/gsm_receive_usrp.py create mode 100755 gsm-receiver/src/python/test.sh delete mode 100755 py-compile delete mode 100644 src/Makefile.am delete mode 100644 src/lib/Assert.h delete mode 100644 src/lib/Makefile.am delete mode 100644 src/lib/decoder/AUTHORS delete mode 100644 src/lib/decoder/Makefile.am delete mode 100644 src/lib/decoder/a5-1-2.h delete mode 100644 src/lib/decoder/burst_types.h delete mode 100644 src/lib/decoder/cch.c delete mode 100644 src/lib/decoder/cch.h delete mode 100644 src/lib/decoder/fire_crc.c delete mode 100644 src/lib/decoder/fire_crc.h delete mode 100644 src/lib/decoder/gsmstack.c delete mode 100644 src/lib/decoder/gsmstack.h delete mode 100644 src/lib/decoder/gsmtap.h delete mode 100644 src/lib/decoder/interleave.c delete mode 100644 src/lib/decoder/interleave.h delete mode 100644 src/lib/decoder/openbtsstuff/AUTHORS delete mode 100644 src/lib/decoder/openbtsstuff/Assert.h delete mode 100644 src/lib/decoder/openbtsstuff/BitVector.cpp delete mode 100644 src/lib/decoder/openbtsstuff/BitVector.h delete mode 100644 src/lib/decoder/openbtsstuff/GSM610Tables.cpp delete mode 100644 src/lib/decoder/openbtsstuff/GSM610Tables.h delete mode 100644 src/lib/decoder/openbtsstuff/GSMCommon.cpp delete mode 100644 src/lib/decoder/openbtsstuff/GSMCommon.h delete mode 100644 src/lib/decoder/openbtsstuff/GSML1FEC.cpp delete mode 100644 src/lib/decoder/openbtsstuff/GSML1FEC.h delete mode 100644 src/lib/decoder/openbtsstuff/GSMTDMA.cpp delete mode 100644 src/lib/decoder/openbtsstuff/GSMTDMA.h delete mode 100644 src/lib/decoder/openbtsstuff/Makefile.am delete mode 100644 src/lib/decoder/openbtsstuff/RxBurst.h delete mode 100644 src/lib/decoder/openbtsstuff/Threads.cpp delete mode 100644 src/lib/decoder/openbtsstuff/Threads.h delete mode 100644 src/lib/decoder/openbtsstuff/Timeval.cpp delete mode 100644 src/lib/decoder/openbtsstuff/Timeval.h delete mode 100644 src/lib/decoder/openbtsstuff/Vector.h delete mode 100644 src/lib/decoder/openbtsstuff/VocoderFrame.h delete mode 100644 src/lib/decoder/out_pcap.c delete mode 100644 src/lib/decoder/out_pcap.h delete mode 100644 src/lib/decoder/sch.c delete mode 100644 src/lib/decoder/sch.h delete mode 100644 src/lib/decoder/system.h delete mode 100644 src/lib/decoder/tun.c delete mode 100644 src/lib/decoder/tun.h delete mode 100644 src/lib/gsm.i delete mode 100644 src/lib/gsm_constants.h delete mode 100644 src/lib/gsm_receiver_cf.cc delete mode 100644 src/lib/gsm_receiver_cf.h delete mode 100644 src/lib/gsm_receiver_config.cc delete mode 100644 src/lib/gsm_receiver_config.h delete mode 100644 src/lib/viterbi_detector.cc delete mode 100644 src/lib/viterbi_detector.h delete mode 100644 src/python/Makefile.am delete mode 100755 src/python/capture.sh delete mode 100644 src/python/cfile delete mode 100755 src/python/go.sh delete mode 100755 src/python/gsm_receive.py delete mode 100755 src/python/gsm_receive_usrp.py delete mode 100755 src/python/test.sh diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 91f0ff0..0000000 --- a/.gitignore +++ /dev/null @@ -1,25 +0,0 @@ -configure -Makefile.in -config.log -config.h -config.sub -config.guess -ltmain.sh -Makefile -config.status -stamp-h1 -config.h.in -autom4te.cache -libtool -missing -aclocal.m4 -install-sh -depcomp -compile -build -*~ -autom4te.cache -debug -html -latex -xml diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index 944ad20..0000000 --- a/AUTHORS +++ /dev/null @@ -1 +0,0 @@ -Piotr Krysik \ No newline at end of file diff --git a/CHANGELOG b/CHANGELOG deleted file mode 100644 index e69de29..0000000 diff --git a/COPYING b/COPYING deleted file mode 100644 index 94a9ed0..0000000 --- a/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - 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 . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/ChangeLog b/ChangeLog deleted file mode 100644 index e69de29..0000000 diff --git a/Doxyfile b/Doxyfile deleted file mode 100644 index 2c5110c..0000000 --- a/Doxyfile +++ /dev/null @@ -1,316 +0,0 @@ -# Doxyfile 1.5.6-KDevelop - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- -DOXYFILE_ENCODING = UTF-8 -PROJECT_NAME = gsm_receiver -PROJECT_NUMBER = 0.0.1 -OUTPUT_DIRECTORY = -CREATE_SUBDIRS = NO -OUTPUT_LANGUAGE = English -BRIEF_MEMBER_DESC = YES -REPEAT_BRIEF = YES -ABBREVIATE_BRIEF = "The $name class" \ - "The $name widget" \ - "The $name file" \ - is \ - provides \ - specifies \ - contains \ - represents \ - a \ - an \ - the -ALWAYS_DETAILED_SEC = NO -INLINE_INHERITED_MEMB = NO -FULL_PATH_NAMES = YES -STRIP_FROM_PATH = /home/piotr/ -STRIP_FROM_INC_PATH = -SHORT_NAMES = NO -JAVADOC_AUTOBRIEF = YES -QT_AUTOBRIEF = NO -MULTILINE_CPP_IS_BRIEF = NO -DETAILS_AT_TOP = NO -INHERIT_DOCS = YES -SEPARATE_MEMBER_PAGES = NO -TAB_SIZE = 8 -ALIASES = -OPTIMIZE_OUTPUT_FOR_C = NO -OPTIMIZE_OUTPUT_JAVA = NO -OPTIMIZE_FOR_FORTRAN = NO -OPTIMIZE_OUTPUT_VHDL = NO -BUILTIN_STL_SUPPORT = NO -CPP_CLI_SUPPORT = NO -SIP_SUPPORT = NO -IDL_PROPERTY_SUPPORT = YES -DISTRIBUTE_GROUP_DOC = NO -SUBGROUPING = YES -TYPEDEF_HIDES_STRUCT = NO -SYMBOL_CACHE_SIZE = 0 -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- -EXTRACT_ALL = NO -EXTRACT_PRIVATE = YES -EXTRACT_STATIC = YES -EXTRACT_LOCAL_CLASSES = YES -EXTRACT_LOCAL_METHODS = NO -EXTRACT_ANON_NSPACES = NO -HIDE_UNDOC_MEMBERS = NO -HIDE_UNDOC_CLASSES = NO -HIDE_FRIEND_COMPOUNDS = NO -HIDE_IN_BODY_DOCS = NO -INTERNAL_DOCS = NO -CASE_SENSE_NAMES = YES -HIDE_SCOPE_NAMES = NO -SHOW_INCLUDE_FILES = YES -INLINE_INFO = YES -SORT_MEMBER_DOCS = YES -SORT_BRIEF_DOCS = NO -SORT_GROUP_NAMES = NO -SORT_BY_SCOPE_NAME = NO -GENERATE_TODOLIST = YES -GENERATE_TESTLIST = YES -GENERATE_BUGLIST = YES -GENERATE_DEPRECATEDLIST= YES -ENABLED_SECTIONS = -MAX_INITIALIZER_LINES = 30 -SHOW_USED_FILES = YES -SHOW_DIRECTORIES = NO -SHOW_FILES = YES -SHOW_NAMESPACES = YES -FILE_VERSION_FILTER = -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- -QUIET = NO -WARNINGS = YES -WARN_IF_UNDOCUMENTED = YES -WARN_IF_DOC_ERROR = YES -WARN_NO_PARAMDOC = NO -WARN_FORMAT = "$file:$line: $text" -WARN_LOGFILE = -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- -INPUT = /home/piotr/MiejscePracy/gsm-receiver -INPUT_ENCODING = UTF-8 -FILE_PATTERNS = *.c \ - *.cc \ - *.cxx \ - *.cpp \ - *.c++ \ - *.d \ - *.java \ - *.ii \ - *.ixx \ - *.ipp \ - *.i++ \ - *.inl \ - *.h \ - *.hh \ - *.hxx \ - *.hpp \ - *.h++ \ - *.idl \ - *.odl \ - *.cs \ - *.php \ - *.php3 \ - *.inc \ - *.m \ - *.mm \ - *.dox \ - *.py \ - *.f90 \ - *.f \ - *.vhd \ - *.vhdl \ - *.C \ - *.CC \ - *.C++ \ - *.II \ - *.I++ \ - *.H \ - *.HH \ - *.H++ \ - *.CS \ - *.PHP \ - *.PHP3 \ - *.M \ - *.MM \ - *.PY \ - *.F90 \ - *.F \ - *.VHD \ - *.VHDL \ - *.C \ - *.H \ - *.tlh \ - *.diff \ - *.patch \ - *.moc \ - *.xpm \ - *.dox -RECURSIVE = yes -EXCLUDE = -EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = -EXCLUDE_SYMBOLS = -EXAMPLE_PATH = -EXAMPLE_PATTERNS = * -EXAMPLE_RECURSIVE = NO -IMAGE_PATH = -INPUT_FILTER = -FILTER_PATTERNS = -FILTER_SOURCE_FILES = NO -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- -SOURCE_BROWSER = NO -INLINE_SOURCES = NO -STRIP_CODE_COMMENTS = YES -REFERENCED_BY_RELATION = NO -REFERENCES_RELATION = NO -REFERENCES_LINK_SOURCE = YES -USE_HTAGS = NO -VERBATIM_HEADERS = YES -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- -ALPHABETICAL_INDEX = NO -COLS_IN_ALPHA_INDEX = 5 -IGNORE_PREFIX = -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- -GENERATE_HTML = YES -HTML_OUTPUT = html -HTML_FILE_EXTENSION = .html -HTML_HEADER = -HTML_FOOTER = -HTML_STYLESHEET = -HTML_ALIGN_MEMBERS = YES -GENERATE_HTMLHELP = NO -GENERATE_DOCSET = NO -DOCSET_FEEDNAME = "Doxygen generated docs" -DOCSET_BUNDLE_ID = org.doxygen.Project -HTML_DYNAMIC_SECTIONS = NO -CHM_FILE = -HHC_LOCATION = -QTHELP_FILE = -QTHELP_CONFIG = -DOXYGEN2QTHELP_LOC = -GENERATE_CHI = NO -CHM_INDEX_ENCODING = -BINARY_TOC = NO -TOC_EXPAND = NO -DISABLE_INDEX = NO -ENUM_VALUES_PER_LINE = 4 -GENERATE_TREEVIEW = NONE -TREEVIEW_WIDTH = 250 -FORMULA_FONTSIZE = 10 -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- -GENERATE_LATEX = YES -LATEX_OUTPUT = latex -LATEX_CMD_NAME = latex -MAKEINDEX_CMD_NAME = makeindex -COMPACT_LATEX = NO -PAPER_TYPE = a4wide -EXTRA_PACKAGES = -LATEX_HEADER = -PDF_HYPERLINKS = YES -USE_PDFLATEX = YES -LATEX_BATCHMODE = NO -LATEX_HIDE_INDICES = NO -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- -GENERATE_RTF = NO -RTF_OUTPUT = rtf -COMPACT_RTF = NO -RTF_HYPERLINKS = NO -RTF_STYLESHEET_FILE = -RTF_EXTENSIONS_FILE = -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- -GENERATE_MAN = NO -MAN_OUTPUT = man -MAN_EXTENSION = .3 -MAN_LINKS = NO -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- -GENERATE_XML = yes -XML_OUTPUT = xml -XML_SCHEMA = -XML_DTD = -XML_PROGRAMLISTING = YES -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- -GENERATE_AUTOGEN_DEF = NO -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- -GENERATE_PERLMOD = NO -PERLMOD_LATEX = NO -PERLMOD_PRETTY = YES -PERLMOD_MAKEVAR_PREFIX = -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- -ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = NO -EXPAND_ONLY_PREDEF = NO -SEARCH_INCLUDES = YES -INCLUDE_PATH = -INCLUDE_FILE_PATTERNS = -PREDEFINED = -EXPAND_AS_DEFINED = -SKIP_FUNCTION_MACROS = YES -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- -TAGFILES = -GENERATE_TAGFILE = gsm_receiver.tag -ALLEXTERNALS = NO -EXTERNAL_GROUPS = YES -PERL_PATH = /usr/bin/perl -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- -CLASS_DIAGRAMS = YES -MSCGEN_PATH = -HIDE_UNDOC_RELATIONS = YES -HAVE_DOT = NO -DOT_FONTNAME = FreeSans -DOT_FONTPATH = -CLASS_GRAPH = YES -COLLABORATION_GRAPH = YES -GROUP_GRAPHS = YES -UML_LOOK = NO -TEMPLATE_RELATIONS = NO -INCLUDE_GRAPH = YES -INCLUDED_BY_GRAPH = YES -CALL_GRAPH = NO -CALLER_GRAPH = NO -GRAPHICAL_HIERARCHY = YES -DIRECTORY_GRAPH = YES -DOT_IMAGE_FORMAT = png -DOT_PATH = -DOTFILE_DIRS = -DOT_GRAPH_MAX_NODES = 50 -MAX_DOT_GRAPH_DEPTH = 1000 -DOT_TRANSPARENT = YES -DOT_MULTI_TARGETS = NO -GENERATE_LEGEND = YES -DOT_CLEANUP = YES -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- -SEARCHENGINE = NO diff --git a/INSTALL b/INSTALL deleted file mode 100644 index 314b196..0000000 --- a/INSTALL +++ /dev/null @@ -1,13 +0,0 @@ -Under Ubuntu 9.04 install: - -add following lines to /etc/apt/sources.list - deb http://gnuradio.org/ubuntu stable main - deb-src http://gnuradio.org/ubuntu stable main - -type - $ sudo apt-get update - $ sudo apt-get install gnuradio libtool automake - -To build the GSM Receiver use: - $ ./bootstrap - $ cd debug - $ ../configure - $ make diff --git a/Makefile.am b/Makefile.am deleted file mode 100644 index 734941a..0000000 --- a/Makefile.am +++ /dev/null @@ -1,13 +0,0 @@ -include $(top_srcdir)/Makefile.common - -SUBDIRS = src config -DIST_SUBDIRS = src config - -EXTRA_DIST = \ - configure \ - gsm-receiver.pc.in \ - config.h.in -# bootstrap - -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = gsm-receiver.pc diff --git a/Makefile.common b/Makefile.common deleted file mode 100644 index 0b88813..0000000 --- a/Makefile.common +++ /dev/null @@ -1,57 +0,0 @@ -# -*- Makefile -*- -# -# Copyright 2004,2006 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. -# - -#!! remove this -TCH_DECODER_INCLUDEDIR = $(top_srcdir)/src/lib/decoder/openbtsstuff - -MAIN_INCLUDEDIR = $(top_srcdir)/src/lib -DECODER_INCLUDEDIR = $(top_srcdir)/src/lib/decoder -DECODER_LA = $(top_builddir)/src/lib/decoder/libdecoder.la - -STD_DEFINES_AND_INCLUDES = \ - -I$(DECODER_INCLUDEDIR) \ - -I$(MAIN_INCLUDEDIR) \ - -I$(GNURADIO_CORE_INCLUDEDIR) \ - -I$(TCH_DECODER_INCLUDEDIR) - -# includes -grincludedir = $(includedir)/gnuradio - -# swig includes -swigincludedir = $(grincludedir)/swig - -# Install this stuff in the appropriate subdirectory -# This usually ends up at: -# ${prefix}/lib/python${python_version}/site-packages/gnuradio - -grpythondir = $(pythondir)/gnuradio -grpyexecdir = $(pyexecdir)/gnuradio - -# swig flags -SWIGPYTHONFLAGS = -fvirtual -python -modern -SWIGGRFLAGS = -I$(GNURADIO_CORE_INCLUDEDIR)/swig -I$(GNURADIO_CORE_INCLUDEDIR) - -# Don't assume that make predefines $(RM), because BSD make does -# not. We define it now in configure.ac using AM_PATH_PROG, but now -# here have to add a -f to be like GNU make. -RM=$(RM_PROG) -f - diff --git a/NEWS b/NEWS deleted file mode 100644 index e69de29..0000000 diff --git a/README b/README deleted file mode 100644 index 96b560b..0000000 --- a/README +++ /dev/null @@ -1,5 +0,0 @@ -Usage: - -capture cfile with usrp: - $ capture.sh - -run go.sh on this file: - $ go.sh diff --git a/bootstrap b/bootstrap deleted file mode 100755 index 7e0a2eb..0000000 --- a/bootstrap +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh - -# Copyright 2001,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 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. - - -rm -fr config.cache autom4te*.cache - -aclocal -I config -autoconf -autoheader -libtoolize --automake -automake --add-missing -if test ! -d debug; then - mkdir debug -fi diff --git a/config/.gitignore b/config/.gitignore deleted file mode 100644 index 38066dd..0000000 --- a/config/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -libtool.m4 -ltoptions.m4 -ltsugar.m4 -ltversion.m4 -lt~obsolete.m4 diff --git a/config/Makefile.am b/config/Makefile.am deleted file mode 100644 index 1c99d68..0000000 --- a/config/Makefile.am +++ /dev/null @@ -1,70 +0,0 @@ -# -# Copyright 2001 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 - -# Install m4 macros in this directory -m4datadir = $(datadir)/aclocal - -# List your m4 macros here -m4macros = \ - acx_pthread.m4 \ - bnv_have_qt.m4 \ - cppunit.m4 \ - gr_boost.m4 \ - gr_check_createfilemapping.m4 \ - gr_check_usrp.m4 \ - gr_check_mc4020.m4 \ - gr_check_shm_open.m4 \ - gr_doxygen.m4 \ - gr_gprof.m4 \ - gr_libgnuradio_core_extra_ldflags.m4 \ - gr_no_undefined.m4 \ - gr_omnithread.m4 \ - gr_pwin32.m4 \ - gr_python.m4 \ - gr_require_mc4020.m4 \ - gr_scripting.m4 \ - gr_set_md_cpu.m4 \ - gr_swig.m4 \ - gr_sysv_shm.m4 \ - gr_x86_64.m4 \ - lf_cc.m4 \ - lf_cxx.m4 \ - lf_warnings.m4 \ - lf_x11.m4 \ - mkstemp.m4 \ - onceonly.m4 \ - pkg.m4 \ - usrp_fusb_tech.m4 \ - usrp_libusb.m4 \ - usrp_sdcc.m4 - - -# Don't install m4 macros anymore -# m4data_DATA = $(m4macros) - -EXTRA_DIST = $(m4macros) \ - libtool.m4 \ - lt~obsolete.m4 \ - ltsugar.m4 \ - ltversion.m4 \ - ltoptions.m4 diff --git a/config/acx_pthread.m4 b/config/acx_pthread.m4 deleted file mode 100644 index d318ab0..0000000 --- a/config/acx_pthread.m4 +++ /dev/null @@ -1,190 +0,0 @@ -dnl Available from the GNU Autoconf Macro Archive at: -dnl http://www.gnu.org/software/ac-archive/htmldoc/acx_pthread.html -dnl -AC_DEFUN([ACX_PTHREAD], [ -AC_REQUIRE([AC_CANONICAL_HOST]) -AC_LANG_SAVE -AC_LANG_C -acx_pthread_ok=no - -# We used to check for pthread.h first, but this fails if pthread.h -# requires special compiler flags (e.g. on True64 or Sequent). -# It gets checked for in the link test anyway. - -# First of all, check if the user has set any of the PTHREAD_LIBS, -# etcetera environment variables, and if threads linking works using -# them: -if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - save_LIBS="$LIBS" - LIBS="$PTHREAD_LIBS $LIBS" - AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) - AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) - AC_MSG_RESULT($acx_pthread_ok) - if test x"$acx_pthread_ok" = xno; then - PTHREAD_LIBS="" - PTHREAD_CFLAGS="" - fi - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" -fi - -# We must check for the threads library under a number of different -# names; the ordering is very important because some systems -# (e.g. DEC) have both -lpthread and -lpthreads, where one of the -# libraries is broken (non-POSIX). - -# Create a list of thread flags to try. Items starting with a "-" are -# C compiler flags, and other items are library names, except for "none" -# which indicates that we try without any flags at all. - -acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt" - -# The ordering *is* (sometimes) important. Some notes on the -# individual items follow: - -# pthreads: AIX (must check this before -lpthread) -# none: in case threads are in libc; should be tried before -Kthread and -# other compiler flags to prevent continual compiler warnings -# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) -# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) -# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) -# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) -# -pthreads: Solaris/gcc -# -mthreads: Mingw32/gcc, Lynx/gcc -# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it -# doesn't hurt to check since this sometimes defines pthreads too; -# also defines -D_REENTRANT) -# pthread: Linux, etcetera -# --thread-safe: KAI C++ - -case "${host_cpu}-${host_os}" in - *solaris*) - - # On Solaris (at least, for some versions), libc contains stubbed - # (non-functional) versions of the pthreads routines, so link-based - # tests will erroneously succeed. (We need to link with -pthread or - # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather - # a function called by this macro, so we could check for that, but - # who knows whether they'll stub that too in a future libc.) So, - # we'll just look for -pthreads and -lpthread first: - - acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags" - ;; -esac - -if test x"$acx_pthread_ok" = xno; then -for flag in $acx_pthread_flags; do - - case $flag in - none) - AC_MSG_CHECKING([whether pthreads work without any flags]) - ;; - - -*) - AC_MSG_CHECKING([whether pthreads work with $flag]) - PTHREAD_CFLAGS="$flag" - ;; - - *) - AC_MSG_CHECKING([for the pthreads library -l$flag]) - PTHREAD_LIBS="-l$flag" - ;; - esac - - save_LIBS="$LIBS" - save_CFLAGS="$CFLAGS" - LIBS="$PTHREAD_LIBS $LIBS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - - # Check for various functions. We must include pthread.h, - # since some functions may be macros. (On the Sequent, we - # need a special flag -Kthread to make this header compile.) - # We check for pthread_join because it is in -lpthread on IRIX - # while pthread_create is in libc. We check for pthread_attr_init - # due to DEC craziness with -lpthreads. We check for - # pthread_cleanup_push because it is one of the few pthread - # functions on Solaris that doesn't have a non-functional libc stub. - # We try pthread_create on general principles. - AC_TRY_LINK([#include ], - [pthread_t th; pthread_join(th, 0); - pthread_attr_init(0); pthread_cleanup_push(0, 0); - pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], - [acx_pthread_ok=yes]) - - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" - - AC_MSG_RESULT($acx_pthread_ok) - if test "x$acx_pthread_ok" = xyes; then - break; - fi - - PTHREAD_LIBS="" - PTHREAD_CFLAGS="" -done -fi - -# Various other checks: -if test "x$acx_pthread_ok" = xyes; then - save_LIBS="$LIBS" - LIBS="$PTHREAD_LIBS $LIBS" - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - - # Detect AIX lossage: threads are created detached by default - # and the JOINABLE attribute has a nonstandard name (UNDETACHED). - AC_MSG_CHECKING([for joinable pthread attribute]) - AC_TRY_LINK([#include ], - [int attr=PTHREAD_CREATE_JOINABLE;], - ok=PTHREAD_CREATE_JOINABLE, ok=unknown) - if test x"$ok" = xunknown; then - AC_TRY_LINK([#include ], - [int attr=PTHREAD_CREATE_UNDETACHED;], - ok=PTHREAD_CREATE_UNDETACHED, ok=unknown) - fi - if test x"$ok" != xPTHREAD_CREATE_JOINABLE; then - AC_DEFINE(PTHREAD_CREATE_JOINABLE, $ok, - [Define to the necessary symbol if this constant - uses a non-standard name on your system.]) - fi - AC_MSG_RESULT(${ok}) - if test x"$ok" = xunknown; then - AC_MSG_WARN([we do not know how to create joinable pthreads]) - fi - - AC_MSG_CHECKING([if more special flags are required for pthreads]) - flag=no - case "${host_cpu}-${host_os}" in - *-aix* | *-freebsd*) flag="-D_THREAD_SAFE";; - *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; - esac - AC_MSG_RESULT(${flag}) - if test "x$flag" != xno; then - PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" - fi - - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" - - # More AIX lossage: must compile with cc_r - AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC}) -else - PTHREAD_CC="$CC" -fi - -AC_SUBST(PTHREAD_LIBS) -AC_SUBST(PTHREAD_CFLAGS) -AC_SUBST(PTHREAD_CC) - -# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: -if test x"$acx_pthread_ok" = xyes; then - ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) - : -else - acx_pthread_ok=no - $2 -fi -AC_LANG_RESTORE -])dnl ACX_PTHREAD diff --git a/config/bnv_have_qt.m4 b/config/bnv_have_qt.m4 deleted file mode 100644 index 1469bfb..0000000 --- a/config/bnv_have_qt.m4 +++ /dev/null @@ -1,404 +0,0 @@ -dnl Available from the GNU Autoconf Macro Archive at: -dnl http://www.gnu.org/software/ac-archive/htmldoc/bnv_have_qt.html -dnl -AC_DEFUN([BNV_HAVE_QT], -[ - dnl THANKS! This code includes bug fixes by: - dnl Tim McClarren. - - AC_REQUIRE([AC_PROG_CXX]) - AC_REQUIRE([AC_PATH_X]) - AC_REQUIRE([AC_PATH_XTRA]) - - AC_MSG_CHECKING(for Qt) - - AC_ARG_WITH([Qt-dir], - [ --with-Qt-dir=DIR DIR is equal to \$QTDIR if you have followed the - installation instructions of Trolltech. Header - files are in DIR/include, binary utilities are - in DIR/bin and the library is in DIR/lib]) - AC_ARG_WITH([Qt-include-dir], - [ --with-Qt-include-dir=DIR - Qt header files are in DIR]) - AC_ARG_WITH([Qt-bin-dir], - [ --with-Qt-bin-dir=DIR Qt utilities such as moc and uic are in DIR]) - AC_ARG_WITH([Qt-lib-dir], - [ --with-Qt-lib-dir=DIR The Qt library is in DIR]) - AC_ARG_WITH([Qt-lib], - [ --with-Qt-lib=LIB Use -lLIB to link with the Qt library]) - if test x"$with_Qt_dir" = x"no" || - test x"$with_Qt_include-dir" = x"no" || - test x"$with_Qt_bin_dir" = x"no" || - test x"$with_Qt_lib_dir" = x"no" || - test x"$with_Qt_lib" = x"no"; then - # user disabled Qt. Leave cache alone. - have_qt="User disabled Qt." - else - # "yes" is a bogus option - if test x"$with_Qt_dir" = xyes; then - with_Qt_dir= - fi - if test x"$with_Qt_include_dir" = xyes; then - with_Qt_include_dir= - fi - if test x"$with_Qt_bin_dir" = xyes; then - with_Qt_bin_dir= - fi - if test x"$with_Qt_lib_dir" = xyes; then - with_Qt_lib_dir= - fi - if test x"$with_Qt_lib" = xyes; then - with_Qt_lib= - fi - # No Qt unless we discover otherwise - have_qt=no - # Check whether we are requested to link with a specific version - if test x"$with_Qt_lib" != x; then - bnv_qt_lib="$with_Qt_lib" - fi - # Check whether we were supplied with an answer already - if test x"$with_Qt_dir" != x; then - have_qt=yes - bnv_qt_dir="$with_Qt_dir" - bnv_qt_include_dir="$with_Qt_dir/include" - bnv_qt_bin_dir="$with_Qt_dir/bin" - bnv_qt_lib_dir="$with_Qt_dir/lib" - # Only search for the lib if the user did not define one already - if test x"$bnv_qt_lib" = x; then - bnv_qt_lib="`ls $bnv_qt_lib_dir/libqt* | sed -n 1p | - sed s@$bnv_qt_lib_dir/lib@@ | [sed s@[.].*@@]`" - fi - bnv_qt_LIBS="-L$bnv_qt_lib_dir -l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" - else - # Use cached value or do search, starting with suggestions from - # the command line - AC_CACHE_VAL(bnv_cv_have_qt, - [ - # We are not given a solution and there is no cached value. - bnv_qt_dir=NO - bnv_qt_include_dir=NO - bnv_qt_lib_dir=NO - if test x"$bnv_qt_lib" = x; then - bnv_qt_lib=NO - fi - BNV_PATH_QT_DIRECT - if test "$bnv_qt_dir" = NO || - test "$bnv_qt_include_dir" = NO || - test "$bnv_qt_lib_dir" = NO || - test "$bnv_qt_lib" = NO; then - # Problem with finding complete Qt. Cache the known absence of Qt. - bnv_cv_have_qt="have_qt=no" - else - # Record where we found Qt for the cache. - bnv_cv_have_qt="have_qt=yes \ - bnv_qt_dir=$bnv_qt_dir \ - bnv_qt_include_dir=$bnv_qt_include_dir \ - bnv_qt_bin_dir=$bnv_qt_bin_dir \ - bnv_qt_LIBS=\"$bnv_qt_LIBS\"" - fi - ])dnl - eval "$bnv_cv_have_qt" - fi # all $bnv_qt_* are set - fi # $have_qt reflects the system status - if test x"$have_qt" = xyes; then - QT_CXXFLAGS="-I$bnv_qt_include_dir" - QT_DIR="$bnv_qt_dir" - QT_LIBS="$bnv_qt_LIBS" - # If bnv_qt_dir is defined, utilities are expected to be in the - # bin subdirectory - if test x"$bnv_qt_dir" != x; then - if test -x "$bnv_qt_dir/bin/uic"; then - QT_UIC="$bnv_qt_dir/bin/uic" - else - # Old versions of Qt don't have uic - QT_UIC= - fi - QT_MOC="$bnv_qt_dir/bin/moc" - else - # Or maybe we are told where to look for the utilities - if test x"$bnv_qt_bin_dir" != x; then - if test -x "$bnv_qt_bin_dir/uic"; then - QT_UIC="$bnv_qt_bin_dir/uic" - else - # Old versions of Qt don't have uic - QT_UIC= - fi - QT_MOC="$bnv_qt_bin_dir/moc" - else - # Last possibility is that they are in $PATH - QT_UIC="`which uic`" - QT_MOC="`which moc`" - fi - fi - # All variables are defined, report the result - AC_MSG_RESULT([$have_qt: - QT_CXXFLAGS=$QT_CXXFLAGS - QT_DIR=$QT_DIR - QT_LIBS=$QT_LIBS - QT_UIC=$QT_UIC - QT_MOC=$QT_MOC]) - else - # Qt was not found - QT_CXXFLAGS= - QT_DIR= - QT_LIBS= - QT_UIC= - QT_MOC= - AC_MSG_RESULT($have_qt) - fi - AC_SUBST(QT_CXXFLAGS) - AC_SUBST(QT_DIR) - AC_SUBST(QT_LIBS) - AC_SUBST(QT_UIC) - AC_SUBST(QT_MOC) - - #### Being paranoid: - if test x"$have_qt" = xyes; then - AC_MSG_CHECKING(correct functioning of Qt installation) - AC_CACHE_VAL(bnv_cv_qt_test_result, - [ - cat > bnv_qt_test.h << EOF -#include -class Test : public QObject -{ -Q_OBJECT -public: - Test() {} - ~Test() {} -public slots: - void receive() {} -signals: - void send(); -}; -EOF - - cat > bnv_qt_main.$ac_ext << EOF -#include "bnv_qt_test.h" -#include -int main( int argc, char **argv ) -{ - QApplication app( argc, argv ); - Test t; - QObject::connect( &t, SIGNAL(send()), &t, SLOT(receive()) ); -} -EOF - - bnv_cv_qt_test_result="failure" - bnv_try_1="$QT_MOC bnv_qt_test.h -o moc_bnv_qt_test.$ac_ext >/dev/null 2>bnv_qt_test_1.out" - AC_TRY_EVAL(bnv_try_1) - bnv_err_1=`grep -v '^ *+' bnv_qt_test_1.out | grep -v "^bnv_qt_test.h\$"` - if test x"$bnv_err_1" != x; then - echo "$bnv_err_1" >&AC_FD_CC - echo "configure: could not run $QT_MOC on:" >&AC_FD_CC - cat bnv_qt_test.h >&AC_FD_CC - else - bnv_try_2="$CXX $QT_CXXFLAGS -c $CXXFLAGS -o moc_bnv_qt_test.o moc_bnv_qt_test.$ac_ext >/dev/null 2>bnv_qt_test_2.out" - AC_TRY_EVAL(bnv_try_2) - bnv_err_2=`grep -v '^ *+' bnv_qt_test_2.out | grep -v "^bnv_qt_test.{$ac_ext}\$"` - if test x"$bnv_err_2" != x; then - echo "$bnv_err_2" >&AC_FD_CC - echo "configure: could not compile:" >&AC_FD_CC - cat bnv_qt_test.$ac_ext >&AC_FD_CC - else - bnv_try_3="$CXX $QT_CXXFLAGS -c $CXXFLAGS -o bnv_qt_main.o bnv_qt_main.$ac_ext >/dev/null 2>bnv_qt_test_3.out" - AC_TRY_EVAL(bnv_try_3) - bnv_err_3=`grep -v '^ *+' bnv_qt_test_3.out | grep -v "^bnv_qt_main.{$ac_ext}\$"` - if test x"$bnv_err_3" != x; then - echo "$bnv_err_3" >&AC_FD_CC - echo "configure: could not compile:" >&AC_FD_CC - cat bnv_qt_main.$ac_ext >&AC_FD_CC - else - bnv_try_4="$CXX $QT_LIBS $LIBS -o bnv_qt_main bnv_qt_main.o moc_bnv_qt_test.o >/dev/null 2>bnv_qt_test_4.out" - AC_TRY_EVAL(bnv_try_4) - bnv_err_4=`grep -v '^ *+' bnv_qt_test_4.out` - if test x"$bnv_err_4" != x; then - echo "$bnv_err_4" >&AC_FD_CC - else - bnv_cv_qt_test_result="success" - fi - fi - fi - fi - ])dnl AC_CACHE_VAL bnv_cv_qt_test_result - AC_MSG_RESULT([$bnv_cv_qt_test_result]); - if test x"$bnv_cv_qt_test_result" = "xfailure"; then - # working Qt was not found - QT_CXXFLAGS= - QT_DIR= - QT_LIBS= - QT_UIC= - QT_MOC= - have_qt=no - AC_MSG_WARN([Failed to find matching components of a complete - Qt installation. Try using more options, - see ./configure --help.]) - fi - - rm -f bnv_qt_test.h moc_bnv_qt_test.$ac_ext moc_bnv_qt_test.o \ - bnv_qt_main.$ac_ext bnv_qt_main.o bnv_qt_main \ - bnv_qt_test_1.out bnv_qt_test_2.out bnv_qt_test_3.out bnv_qt_test_4.out - fi -]) - -dnl Internal subroutine of BNV_HAVE_QT -dnl Set bnv_qt_dir bnv_qt_include_dir bnv_qt_bin_dir bnv_qt_lib_dir bnv_qt_lib -dnl Copyright 2001 Bastiaan N. Veelo -AC_DEFUN([BNV_PATH_QT_DIRECT], -[ - ## Binary utilities ## - if test x"$with_Qt_bin_dir" != x; then - bnv_qt_bin_dir=$with_Qt_bin_dir - fi - ## Look for header files ## - if test x"$with_Qt_include_dir" != x; then - bnv_qt_include_dir="$with_Qt_include_dir" - else - # The following header file is expected to define QT_VERSION. - qt_direct_test_header=qglobal.h - # Look for the header file in a standard set of common directories. - bnv_include_path_list=" - /usr/include - `ls -dr /usr/include/qt* 2>/dev/null` - `ls -dr /usr/lib/qt*/include 2>/dev/null` - `ls -dr /usr/local/qt*/include 2>/dev/null` - `ls -dr /opt/qt*/include 2>/dev/null` - " - for bnv_dir in $bnv_include_path_list; do - if test -r "$bnv_dir/$qt_direct_test_header"; then - bnv_dirs="$bnv_dirs $bnv_dir" - fi - done - # Now look for the newest in this list - bnv_prev_ver=0 - for bnv_dir in $bnv_dirs; do - bnv_this_ver=`egrep -w '#define QT_VERSION' $bnv_dir/$qt_direct_test_header | sed s/'#define QT_VERSION'//` - if expr $bnv_this_ver '>' $bnv_prev_ver > /dev/null; then - bnv_qt_include_dir=$bnv_dir - bnv_prev_ver=$bnv_this_ver - fi - done - fi dnl Found header files. - - # Are these headers located in a traditional Trolltech installation? - # That would be $bnv_qt_include_dir stripped from its last element: - bnv_possible_qt_dir=`dirname $bnv_qt_include_dir` - if test -x $bnv_possible_qt_dir/bin/moc && - ls $bnv_possible_qt_dir/lib/libqt* > /dev/null; then - # Then the rest is a piece of cake - bnv_qt_dir=$bnv_possible_qt_dir - bnv_qt_bin_dir="$bnv_qt_dir/bin" - bnv_qt_lib_dir="$bnv_qt_dir/lib" - # Only look for lib if the user did not supply it already - if test x"$bnv_qt_lib" = xNO; then - bnv_qt_lib="`ls $bnv_qt_lib_dir/libqt* | sed -n 1p | - sed s@$bnv_qt_lib_dir/lib@@ | [sed s@[.].*@@]`" - fi - bnv_qt_LIBS="-L$bnv_qt_lib_dir -l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" - else - # There is no valid definition for $QTDIR as Trolltech likes to see it - bnv_qt_dir= - ## Look for Qt library ## - if test x"$with_Qt_lib_dir" != x; then - bnv_qt_lib_dir="$with_Qt_lib_dir" - # Only look for lib if the user did not supply it already - if test x"$bnv_qt_lib" = xNO; then - bnv_qt_lib="`ls $bnv_qt_lib_dir/libqt* | sed -n 1p | - sed s@$bnv_qt_lib_dir/lib@@ | [sed s@[.].*@@]`" - fi - bnv_qt_LIBS="-L$bnv_qt_lib_dir -l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" - else - # Normally, when there is no traditional Trolltech installation, - # the library is installed in a place where the linker finds it - # automatically. - # If the user did not define the library name, try with qt - if test x"$bnv_qt_lib" = xNO; then - bnv_qt_lib=qt - fi - qt_direct_test_header=qapplication.h - qt_direct_test_main=" - int argc; - char ** argv; - QApplication app(argc,argv); - " - # See if we find the library without any special options. - # Don't add top $LIBS permanently yet - bnv_save_LIBS="$LIBS" - LIBS="-l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" - bnv_qt_LIBS="$LIBS" - bnv_save_CXXFLAGS="$CXXFLAGS" - CXXFLAGS="-I$bnv_qt_include_dir" - AC_TRY_LINK([#include <$qt_direct_test_header>], - $qt_direct_test_main, - [ - # Success. - # We can link with no special library directory. - bnv_qt_lib_dir= - ], [ - # That did not work. Try the multi-threaded version - echo "Non-critical error, please neglect the above." >&AC_FD_CC - bnv_qt_lib=qt-mt - LIBS="-l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" - AC_TRY_LINK([#include <$qt_direct_test_header>], - $qt_direct_test_main, - [ - # Success. - # We can link with no special library directory. - bnv_qt_lib_dir= - ], [ - # That did not work. Try the OpenGL version - echo "Non-critical error, please neglect the above." >&AC_FD_CC - bnv_qt_lib=qt-gl - LIBS="-l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" - AC_TRY_LINK([#include <$qt_direct_test_header>], - $qt_direct_test_main, - [ - # Succes. - # We can link with no special library directory. - bnv_qt_lib_dir= - ], [ - # That did not work. Maybe a library version I don't know about? - echo "Non-critical error, please neglect the above." >&AC_FD_CC - # Look for some Qt lib in a standard set of common directories. - bnv_dir_list=" - `echo $bnv_qt_includes | sed ss/includess` - /lib - /usr/lib - /usr/local/lib - /opt/lib - `ls -dr /usr/lib/qt* 2>/dev/null` - `ls -dr /usr/local/qt* 2>/dev/null` - `ls -dr /opt/qt* 2>/dev/null` - " - for bnv_dir in $bnv_dir_list; do - if ls $bnv_dir/libqt*; then - # Gamble that it's the first one... - bnv_qt_lib="`ls $bnv_dir/libqt* | sed -n 1p | - sed s@$bnv_dir/lib@@ | sed s/[.].*//`" - bnv_qt_lib_dir="$bnv_dir" - break - fi - done - # Try with that one - LIBS="-l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" - AC_TRY_LINK([#include <$qt_direct_test_header>], - $qt_direct_test_main, - [ - # Succes. - # We can link with no special library directory. - bnv_qt_lib_dir= - ], [ - # Leave bnv_qt_lib_dir defined - ]) - ]) - ]) - ]) - if test x"$bnv_qt_lib_dir" != x; then - bnv_qt_LIBS="-l$bnv_qt_lib_dir $LIBS" - else - bnv_qt_LIBS="$LIBS" - fi - LIBS="$bnv_save_LIBS" - CXXFLAGS="$bnv_save_CXXFLAGS" - fi dnl $with_Qt_lib_dir was not given - fi dnl Done setting up for non-traditional Trolltech installation -]) diff --git a/config/cppunit.m4 b/config/cppunit.m4 deleted file mode 100644 index 0991d51..0000000 --- a/config/cppunit.m4 +++ /dev/null @@ -1,80 +0,0 @@ -dnl -dnl AM_PATH_CPPUNIT(MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) -dnl -AC_DEFUN([AM_PATH_CPPUNIT], -[ - -AC_ARG_WITH(cppunit-prefix,[ --with-cppunit-prefix=PFX Prefix where CppUnit is installed (optional)], - cppunit_config_prefix="$withval", cppunit_config_prefix="") -AC_ARG_WITH(cppunit-exec-prefix,[ --with-cppunit-exec-prefix=PFX Exec prefix where CppUnit is installed (optional)], - cppunit_config_exec_prefix="$withval", cppunit_config_exec_prefix="") - - if test x$cppunit_config_exec_prefix != x ; then - cppunit_config_args="$cppunit_config_args --exec-prefix=$cppunit_config_exec_prefix" - if test x${CPPUNIT_CONFIG+set} != xset ; then - CPPUNIT_CONFIG=$cppunit_config_exec_prefix/bin/cppunit-config - fi - fi - if test x$cppunit_config_prefix != x ; then - cppunit_config_args="$cppunit_config_args --prefix=$cppunit_config_prefix" - if test x${CPPUNIT_CONFIG+set} != xset ; then - CPPUNIT_CONFIG=$cppunit_config_prefix/bin/cppunit-config - fi - fi - - AC_PATH_PROG(CPPUNIT_CONFIG, cppunit-config, no) - cppunit_version_min=$1 - - AC_MSG_CHECKING(for Cppunit - version >= $cppunit_version_min) - no_cppunit="" - if test "$CPPUNIT_CONFIG" = "no" ; then - no_cppunit=yes - else - CPPUNIT_CFLAGS=`$CPPUNIT_CONFIG --cflags` - CPPUNIT_LIBS=`$CPPUNIT_CONFIG --libs` - cppunit_version=`$CPPUNIT_CONFIG --version` - - cppunit_major_version=`echo $cppunit_version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` - cppunit_minor_version=`echo $cppunit_version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` - cppunit_micro_version=`echo $cppunit_version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` - - cppunit_major_min=`echo $cppunit_version_min | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` - cppunit_minor_min=`echo $cppunit_version_min | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` - cppunit_micro_min=`echo $cppunit_version_min | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` - - cppunit_version_proper=`expr \ - $cppunit_major_version \> $cppunit_major_min \| \ - $cppunit_major_version \= $cppunit_major_min \& \ - $cppunit_minor_version \> $cppunit_minor_min \| \ - $cppunit_major_version \= $cppunit_major_min \& \ - $cppunit_minor_version \= $cppunit_minor_min \& \ - $cppunit_micro_version \>= $cppunit_micro_min ` - - if test "$cppunit_version_proper" = "1" ; then - AC_MSG_RESULT([$cppunit_major_version.$cppunit_minor_version.$cppunit_micro_version]) - else - AC_MSG_RESULT(no) - no_cppunit=yes - fi - fi - - if test "x$no_cppunit" = x ; then - ifelse([$2], , :, [$2]) - else - CPPUNIT_CFLAGS="" - CPPUNIT_LIBS="" - ifelse([$3], , :, [$3]) - fi - - AC_SUBST(CPPUNIT_CFLAGS) - AC_SUBST(CPPUNIT_LIBS) -]) - - - diff --git a/config/gr_boost.m4 b/config/gr_boost.m4 deleted file mode 100644 index 0664d36..0000000 --- a/config/gr_boost.m4 +++ /dev/null @@ -1,111 +0,0 @@ -dnl -dnl Copyright 2004,2005 Free Software Foundation, Inc. -dnl -dnl This file is part of GNU Radio -dnl -dnl GNU Radio is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3, or (at your option) -dnl any later version. -dnl -dnl GNU Radio is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with GNU Radio; see the file COPYING. If not, write to -dnl the Free Software Foundation, Inc., 51 Franklin Street, -dnl Boston, MA 02110-1301, USA. -dnl - -dnl This tries to do the "right thing" to locate the boost include files. -dnl If the user explicitly specified --with-boost-include-dir= -dnl we believe them and use it. Otherwise, -dnl -dnl We look for boost/shared_ptr.hpp in the "normal places". That is, -dnl wherever AC_CHECK_HEADER looks. If the boost includes are in /usr/local/include -dnl this step will find them. -dnl -dnl Otherwise, we check to see if the boost stuff was installed in a version-specific -dnl directory under /usr/local/include. These look like: /usr/local/include/boost-1_33_1 -dnl If there's more than one version installed, we select the -dnl lexicographically greatest one. -dnl -dnl If none of these work, we bail. - -AC_DEFUN([GR_REQUIRE_BOOST_INCLUDES], -[ - AC_LANG_PUSH(C++) - gr_boost_include_dir= - AC_ARG_WITH([boost-include-dir], - AC_HELP_STRING([--with-boost-include-dir=], - [path to boost c++ include files]), - [ - # "yes" and "no" are bogus answers - if test x"$with_boost_include_dir" = xyes || - test x"$with_boost_include_dir" = xno; then - gr_boost_include_dir= - else - gr_boost_include_dir=$with_boost_include_dir - fi - ]) - echo "gr_boost_include_dir = $gr_boost_include_dir" - if test x$gr_boost_include_dir != x; then - # - # If the user specified a directory, then we use it - # - OLD_CPPFLAGS=$CPPFLAGS - CPPFLAGS="$CPPFLAGS -I$gr_boost_include_dir" - AC_CHECK_HEADER([boost/shared_ptr.hpp], - [BOOST_CFLAGS="-I$gr_boost_include_dir"], - [AC_MSG_ERROR( - [Failed to locate boost/shared_ptr.hpp. -Try using --with-boost-include-dir=, -E.g., --with-boost-include-dir=/usr/local/include/boost-1_33_1])]) - CPPFLAGS=$OLD_CPPFLAGS - else - # - # Otherwise we check in the default places - # - AC_CHECK_HEADER([boost/shared_ptr.hpp], - [BOOST_CFLAGS=""], - [ # Nope, look for latest version if any in $prefix/include/boost-* - - # Wipe out cached value. KLUDGE: AC should have API for this - unset AS_TR_SH([ac_cv_header_boost/shared_ptr.hpp]) - - boost_last_match(){ - #echo "boost_last_match: [$]*" - pattern="[$]1" - shift - if test "[$]pattern" = "[$]1" - then - LM='' - else - shift `expr [$]# - 1` - LM=[$]1 - fi - #echo "LM(1)='[$]LM'" - } - - pattern="/usr/local/include/boost-*" - boost_last_match "$pattern" $pattern - #echo "LM(2)='$LM'" - - OLD_CPPFLAGS=$CPP_FLAGS - CPPFLAGS="$CPPFLAGS -I$LM" - AC_CHECK_HEADER([boost/shared_ptr.hpp], - [BOOST_CFLAGS="-I$LM"], - [AC_MSG_ERROR( - [Failed to locate boost/shared_ptr.hpp. -Try using --with-boost-include-dir=, -E.g., --with-boost-include-dir=/usr/local/include/boost-1_33_1])]) - CPPFLAGS=$OLD_CPPFLAGS - ]) - - fi - unset boost_last_match LM - AC_LANG_POP - AC_SUBST(BOOST_CFLAGS) -]) diff --git a/config/gr_check_createfilemapping.m4 b/config/gr_check_createfilemapping.m4 deleted file mode 100644 index 5f9b4a4..0000000 --- a/config/gr_check_createfilemapping.m4 +++ /dev/null @@ -1,52 +0,0 @@ -dnl -dnl Copyright 2005 Free Software Foundation, Inc. -dnl -dnl This file is part of GNU Radio -dnl -dnl GNU Radio is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3, or (at your option) -dnl any later version. -dnl -dnl GNU Radio is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with GNU Radio; see the file COPYING. If not, write to -dnl the Free Software Foundation, Inc., 51 Franklin Street, -dnl Boston, MA 02110-1301, USA. - -dnl AC_DEFUN([GR_CHECK_CREATEFILEMAPPING], -dnl [ -dnl AC_CHECK_FUNCS([CreateFileMapping]) -dnl ]) - -AC_DEFUN([GR_CHECK_CREATEFILEMAPPING],[ - AC_MSG_CHECKING([for CreateFileMapping function]) - AC_COMPILE_IFELSE([ -#include -int main (int argc, char **argv) -{ - HANDLE handle; - int size; - char seg_name[[1024]]; - handle = CreateFileMapping( - INVALID_HANDLE_VALUE, // use paging file - NULL, // default security - PAGE_READWRITE, // read/write access - 0, // max. object size - size, // buffer size - seg_name); // name of mapping object - return 0; -} -],[HAVE_CREATEFILEMAPPING=yes - AC_DEFINE(HAVE_CREATEFILEMAPPING,[1],[Define if you have the CreateFilemapping function(win32).])], - [HAVE_CREATEFILEMAPPING=no]) - - AC_MSG_RESULT($HAVE_CREATEFILEMAPPING) - AM_CONDITIONAL(HAVE_CREATEFILEMAPPING, test x$HAVE_CREATEFILEMAPPING = xyes) -]) - - diff --git a/config/gr_check_mc4020.m4 b/config/gr_check_mc4020.m4 deleted file mode 100644 index 28987c2..0000000 --- a/config/gr_check_mc4020.m4 +++ /dev/null @@ -1,37 +0,0 @@ -dnl -dnl Copyright 2003 Free Software Foundation, Inc. -dnl -dnl This file is part of GNU Radio -dnl -dnl GNU Radio is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3, or (at your option) -dnl any later version. -dnl -dnl GNU Radio is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with GNU Radio; see the file COPYING. If not, write to -dnl the Free Software Foundation, Inc., 51 Franklin Street, -dnl Boston, MA 02110-1301, USA. -dnl - -AC_DEFUN([GR_CHECK_MC4020],[ - AC_MSG_CHECKING([for mc4020 A/D driver include file]) - AC_COMPILE_IFELSE([ -#include -int main (int argc, char **argv) -{ - return 0; -} -],[HAVE_MC4020=yes - AC_DEFINE(HAVE_MC4020,[1],[Define if you have a Measurement Computing PCI-DAS4020/12 A/D])], - [HAVE_MC4020=no]) - - AC_MSG_RESULT($HAVE_MC4020) - AM_CONDITIONAL(HAVE_MC4020, test x$HAVE_MC4020 = xyes) -]) - diff --git a/config/gr_check_shm_open.m4 b/config/gr_check_shm_open.m4 deleted file mode 100644 index 83d260b..0000000 --- a/config/gr_check_shm_open.m4 +++ /dev/null @@ -1,29 +0,0 @@ -dnl -dnl Copyright 2003 Free Software Foundation, Inc. -dnl -dnl This file is part of GNU Radio -dnl -dnl GNU Radio is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3, or (at your option) -dnl any later version. -dnl -dnl GNU Radio is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with GNU Radio; see the file COPYING. If not, write to -dnl the Free Software Foundation, Inc., 51 Franklin Street, -dnl Boston, MA 02110-1301, USA. - -AC_DEFUN([GR_CHECK_SHM_OPEN], -[ - SHM_OPEN_LIBS="" - save_LIBS="$LIBS" - AC_SEARCH_LIBS([shm_open], [rt], [SHM_OPEN_LIBS="$LIBS"]) - AC_CHECK_FUNCS([shm_open]) - LIBS="$save_LIBS" - AC_SUBST(SHM_OPEN_LIBS) -]) diff --git a/config/gr_check_usrp.m4 b/config/gr_check_usrp.m4 deleted file mode 100644 index 12a5d1c..0000000 --- a/config/gr_check_usrp.m4 +++ /dev/null @@ -1,32 +0,0 @@ -dnl -dnl Copyright 2003 Free Software Foundation, Inc. -dnl -dnl This file is part of GNU Radio -dnl -dnl GNU Radio is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3, or (at your option) -dnl any later version. -dnl -dnl GNU Radio is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with GNU Radio; see the file COPYING. If not, write to -dnl the Free Software Foundation, Inc., 51 Franklin Street, -dnl Boston, MA 02110-1301, USA. -dnl - -dnl Check for Universal Software Radio Peripheral - -AC_DEFUN([GR_CHECK_USRP],[ - PKG_CHECK_MODULES(USRP, usrp >= 0.2, - [HAVE_USRP=yes - AC_DEFINE(HAVE_USRP,[1],[Define if you have a USRP])], - [HAVE_USRP=no]) - - AM_CONDITIONAL(HAVE_USRP, test x$HAVE_USRP = xyes) -]) - diff --git a/config/gr_doxygen.m4 b/config/gr_doxygen.m4 deleted file mode 100644 index 4670c29..0000000 --- a/config/gr_doxygen.m4 +++ /dev/null @@ -1,59 +0,0 @@ -dnl -dnl Copyright 2003,2005 Free Software Foundation, Inc. -dnl -dnl This file is part of GNU Radio -dnl -dnl GNU Radio is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3, or (at your option) -dnl any later version. -dnl -dnl GNU Radio is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with GNU Radio; see the file COPYING. If not, write to -dnl the Free Software Foundation, Inc., 51 Franklin Street, -dnl Boston, MA 02110-1301, USA. -dnl - -AC_DEFUN([GR_CHECK_DOXYGEN],[ - AC_ARG_ENABLE(doxygen, [ --enable-doxygen enable documentation generation with doxygen (no)]) - AC_ARG_ENABLE(dot, [ --enable-dot use 'dot' to generate graphs in doxygen (auto)]) - AC_ARG_ENABLE(html-docs, [ --enable-html-docs enable HTML generation with doxygen (yes)], [], [ enable_html_docs=yes]) - AC_ARG_ENABLE(latex-docs, [ --enable-latex-docs enable LaTeX doc generation with doxygen (no)], [], [ enable_latex_docs=no]) - - if test "x$enable_doxygen" = xyes; then - AC_PATH_PROG(DOXYGEN, doxygen, , $PATH) - if test x$DOXYGEN = x; then - if test "x$enable_doxygen" = xyes; then - AC_MSG_ERROR([could not find doxygen]) - fi - enable_doc=no - generate_docs= - else - enable_doc=yes - generate_docs=docs - AC_PATH_PROG(DOT, dot, , $PATH) - fi - else - enable_doc=no - fi - - AM_CONDITIONAL(DOC, test x$enable_doc = xyes) - - if test x$DOT = x; then - if test "x$enable_dot" = xyes; then - AC_MSG_ERROR([could not find dot]) - fi - enable_dot=no - else - enable_dot=yes - fi - AC_SUBST(enable_dot) - AC_SUBST(enable_html_docs) - AC_SUBST(enable_latex_docs) - AC_SUBST(generate_docs) -]) diff --git a/config/gr_gprof.m4 b/config/gr_gprof.m4 deleted file mode 100644 index 20bacf3..0000000 --- a/config/gr_gprof.m4 +++ /dev/null @@ -1,72 +0,0 @@ -dnl -dnl Copyright 2002 Free Software Foundation, Inc. -dnl -dnl This file is part of GNU Radio -dnl -dnl GNU Radio is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3, or (at your option) -dnl any later version. -dnl -dnl GNU Radio is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with GNU Radio; see the file COPYING. If not, write to -dnl the Free Software Foundation, Inc., 51 Franklin Street, -dnl Boston, MA 02110-1301, USA. -dnl - -dnl FIXME probably need to add linker flag too... - -AC_DEFUN([GR_SET_GPROF],[ - dnl Check for --with-gprof - AC_MSG_CHECKING([whether user wants gprof]) - AC_ARG_WITH(gprof, - [ --with-gprof Turn on gprof profiling], - [], [ with_gprof=no ]) - AC_MSG_RESULT($with_gprof) - - dnl gprof profiling flags for the two main compilers - cc_profiling_flags="-pg" - cxx_profiling_flags="-pg" - ld_profiling_flags="-pg" - if test $with_gprof = yes - then - if test -n "${CC}" - then - LF_CHECK_CC_FLAG($cc_profiling_flags) - fi - if test -n "${CXX}" - then - LF_CHECK_CXX_FLAG($cxx_profiling_flags) - fi - fi -]) - -AC_DEFUN([GR_SET_PROF],[ - dnl Check for --with-prof - AC_MSG_CHECKING([whether user wants prof]) - AC_ARG_WITH(prof, - [ --with-prof Turn on prof profiling], - [], [ with_prof=no ]) - AC_MSG_RESULT($with_prof) - - dnl prof profiling flags for the two main compilers - cc_profiling_flags="-p" - cxx_profiling_flags="-p" - ld_profiling_flags="-p" - if test $with_prof = yes - then - if test -n "${CC}" - then - LF_CHECK_CC_FLAG($cc_profiling_flags) - fi - if test -n "${CXX}" - then - LF_CHECK_CXX_FLAG($cxx_profiling_flags) - fi - fi -]) diff --git a/config/gr_libgnuradio_core_extra_ldflags.m4 b/config/gr_libgnuradio_core_extra_ldflags.m4 deleted file mode 100644 index 43f872c..0000000 --- a/config/gr_libgnuradio_core_extra_ldflags.m4 +++ /dev/null @@ -1,40 +0,0 @@ -# Check for (MinGW)win32 extra ld options. -*- Autoconf -*- - -# Copyright 2003,2004,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 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. - -dnl -AC_DEFUN([GR_LIBGNURADIO_CORE_EXTRA_LDFLAGS], [ -AC_REQUIRE([AC_PROG_LD]) -# on Mingw32 extra LDFLAGS are required to ease global variable linking -LIBGNURADIO_CORE_EXTRA_LDFLAGS="" - -AC_MSG_CHECKING([whether $LD accepts --enable-runtime-pseudo-reloc]) -if ${LD} --enable-runtime-pseudo-reloc --version >/dev/null 2>&1 -then - # libtool requires the quotes - LIBGNURADIO_CORE_EXTRA_LDFLAGS="\"-Wl,--enable-runtime-pseudo-reloc\"" - AC_MSG_RESULT(yes) -else - AC_MSG_RESULT(no) -fi - -AC_SUBST(LIBGNURADIO_CORE_EXTRA_LDFLAGS) - -]) diff --git a/config/gr_no_undefined.m4 b/config/gr_no_undefined.m4 deleted file mode 100644 index c8d745d..0000000 --- a/config/gr_no_undefined.m4 +++ /dev/null @@ -1,44 +0,0 @@ -dnl -dnl Copyright 2005 Free Software Foundation, Inc. -dnl -dnl This file is part of GNU Radio -dnl -dnl GNU Radio is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3, or (at your option) -dnl any later version. -dnl -dnl GNU Radio is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with GNU Radio; see the file COPYING. If not, write to -dnl the Free Software Foundation, Inc., 51 Franklin Street, -dnl Boston, MA 02110-1301, USA. -dnl - -# GR_NO_UNDEFINED() -# -# Detemine whether we need to use the -no-undefined linker flag -# when building shared libraries. -# Sets NO_UNDEFINED to "" or "-no-undefined" -# -# As far as I can tell, we need -no-undefined only when building -# windows DLLs. This occurs when using MinGW and Cygwin. -# -# For now, we stub this out. - -AC_DEFUN([GR_NO_UNDEFINED],[ - AC_REQUIRE([AC_CANONICAL_HOST]) - no_undefined="" - case "${host_os}" in - *mingw* | *cygwin*) - - # on MinGW/Cygwin extra LDFLAGS are required - no_undefined="-no-undefined" - ;; - esac - AC_SUBST(NO_UNDEFINED,[$no_undefined]) -]) diff --git a/config/gr_omnithread.m4 b/config/gr_omnithread.m4 deleted file mode 100644 index b5e4090..0000000 --- a/config/gr_omnithread.m4 +++ /dev/null @@ -1,51 +0,0 @@ -# Check for Omnithread (pthread/NT) thread support. -*- Autoconf -*- - -# Copyright 2003 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, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Boston, MA -# 02110-1301, USA. - -AC_DEFUN([GR_OMNITHREAD], -[ - # Check first for POSIX - ACX_PTHREAD( - [ ot_posix="yes" - AC_DEFINE(OMNITHREAD_POSIX,[1],[Define to 1 to enable pthread]) - ],[ - # If no POSIX support found, then check for NT threads - AC_MSG_CHECKING([for NT threads]) - - AC_LINK_IFELSE([ - #include - #include - int main() { InitializeCriticalSection(NULL); return 0; } - ], - [ - ot_nt="yes" - AC_DEFINE(OMNITHREAD_NT,[1],[Define to 1 to enable NT thread]) - ], - [AC_MSG_FAILURE([GNU Radio requires POSIX threads. pthreads not found.])] - ) - AC_MSG_RESULT(yes) - ]) - AM_CONDITIONAL(OMNITHREAD_POSIX, test "x$ot_posix" = xyes) - AM_CONDITIONAL(OMNITHREAD_NT, test "x$ot_nt" = xyes) - - save_LIBS="$LIBS" - AC_SEARCH_LIBS([clock_gettime], [rt], [PTHREAD_LIBS="$PTHREAD_LIBS $LIBS"]) - AC_CHECK_FUNCS([clock_gettime gettimeofday nanosleep]) - LIBS="$save_LIBS" -]) - diff --git a/config/gr_pwin32.m4 b/config/gr_pwin32.m4 deleted file mode 100644 index 7b99cba..0000000 --- a/config/gr_pwin32.m4 +++ /dev/null @@ -1,146 +0,0 @@ -# Check for (mingw)win32 POSIX replacements. -*- Autoconf -*- - -# Copyright 2003,2004,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 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. - - -AC_DEFUN([GR_PWIN32], -[ -AC_REQUIRE([AC_HEADER_TIME]) -AC_CHECK_HEADERS([sys/types.h fcntl.h io.h]) -AC_CHECK_HEADERS([windows.h]) -AC_CHECK_HEADERS([winioctl.h winbase.h], [], [], [ - #if HAVE_WINDOWS_H - #include - #endif -]) - -AC_CHECK_FUNCS([getopt usleep gettimeofday nanosleep rand srand random srandom sleep sigaction]) -AC_CHECK_TYPES([struct timezone, struct timespec, ssize_t],[],[],[ - #if HAVE_SYS_TYPES_H - # include - #endif - #if TIME_WITH_SYS_TIME - # include - # include - #else - # if HAVE_SYS_TIME_H - # include - # else - # include - # endif - #endif -]) - -dnl Checks for replacements -AC_REPLACE_FUNCS([getopt usleep gettimeofday]) - - -AC_MSG_CHECKING(for Sleep) -AC_TRY_LINK([ #include - #include - ], [ Sleep(0); ], - [AC_DEFINE(HAVE_SSLEEP,1,[Define to 1 if you have win32 Sleep]) - AC_MSG_RESULT(yes)], - AC_MSG_RESULT(no) - ) - -dnl Under Win32, mkdir prototype in io.h has only one arg -AC_MSG_CHECKING(whether mkdir accepts only one arg) -AC_TRY_COMPILE([#include - #include - #include ], [ - mkdir("") - ], [ AC_MSG_RESULT(yes) - AC_DEFINE(MKDIR_TAKES_ONE_ARG,[],[Define if mkdir accepts only one arg]) ], - [ AC_MSG_RESULT(no) - ]) - -AH_BOTTOM( -[ -/* Define missing prototypes, implemented in replacement lib */ -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef HAVE_GETOPT -int getopt (int argc, char * const argv[], const char * optstring); -extern char * optarg; -extern int optind, opterr, optopt; -#endif - -#ifndef HAVE_USLEEP -int usleep(unsigned long usec); /* SUSv2 */ -#endif - -#ifndef HAVE_NANOSLEEP -#ifndef HAVE_STRUCT_TIMESPEC -#if HAVE_SYS_TYPES_H -# include /* need time_t */ -#endif -struct timespec { - time_t tv_sec; - long tv_nsec; -}; -#endif -static inline int nanosleep(const struct timespec *req, struct timespec *rem) { return usleep(req->tv_sec*1000000+req->tv_nsec/1000); } -#endif - -#if defined(HAVE_SSLEEP) && !defined(HAVE_SLEEP) -#ifdef HAVE_WINBASE_H -#include -#include -#endif -/* TODO: what about SleepEx? */ -static inline unsigned int sleep (unsigned int nb_sec) { Sleep(nb_sec*1000); return 0; } -#endif - -#ifndef HAVE_GETTIMEOFDAY -#ifdef HAVE_SYS_TIME_H -#include -#endif -#ifndef HAVE_STRUCT_TIMEZONE -struct timezone { - int tz_minuteswest; - int tz_dsttime; -}; -#endif -int gettimeofday(struct timeval *tv, struct timezone *tz); -#endif - -#if !defined(HAVE_RANDOM) && defined(HAVE_RAND) -#include -static inline long int random (void) { return rand(); } -#endif - -#if !defined(HAVE_SRANDOM) && defined(HAVE_SRAND) -static inline void srandom (unsigned int seed) { srand(seed); } -#endif - -#ifndef HAVE_SSIZE_T -typedef size_t ssize_t; -#endif - -#ifdef __cplusplus -} -#endif -]) - - -]) diff --git a/config/gr_python.m4 b/config/gr_python.m4 deleted file mode 100644 index 5816b27..0000000 --- a/config/gr_python.m4 +++ /dev/null @@ -1,111 +0,0 @@ -dnl -dnl Copyright 2003,2004,2005 Free Software Foundation, Inc. -dnl -dnl This file is part of GNU Radio -dnl -dnl GNU Radio is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3, or (at your option) -dnl any later version. -dnl -dnl GNU Radio is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with GNU Radio; see the file COPYING. If not, write to -dnl the Free Software Foundation, Inc., 51 Franklin Street, -dnl Boston, MA 02110-1301, USA. -dnl - -# PYTHON_DEVEL() -# -# Checks for Python and tries to get the include path to 'Python.h'. -# It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LDFLAGS) output variables. -# -AC_DEFUN([PYTHON_DEVEL],[ - AC_REQUIRE([AM_PATH_PYTHON]) - AC_REQUIRE([AC_CANONICAL_HOST]) - - # For Fedora Core 5 and 6, see ticket:39 in Trac - if test -f '/etc/redhat-release'; then - if (echo $pyexecdir | grep -q lib64); then - pythondir="$pyexecdir" - fi - fi - - # Check for Python include path - AC_MSG_CHECKING([for Python include path]) - if test -z "$PYTHON" ; then - AC_MSG_ERROR([cannot find Python path]) - fi - - # ask distutils which include path we should use - python_cmd=' -import distutils.sysconfig -import os -path = distutils.sysconfig.get_python_inc(plat_specific=False) -if os.sep == "\\": - path = path.replace("\\", "/") -print path -' - python_path=`$PYTHON -c "$python_cmd"` - AC_MSG_RESULT([$python_path]) - if test -z "$python_path" ; then - AC_MSG_ERROR([cannot find Python include path]) - fi - - AC_SUBST(PYTHON_CPPFLAGS,[-I$python_path]) - - # Check for Python headers usability - python_save_CPPFLAGS=$CPPFLAGS - CPPFLAGS="$CPPFLAGS $PYTHON_CPPFLAGS" - AC_CHECK_HEADERS([Python.h], [], - [AC_MSG_ERROR([cannot find usable Python headers])]) - CPPFLAGS="$python_save_CPPFLAGS" - - # Only set this on mingw and cygwin hosts, (only implemented - # for mingw host, for crosscompiling you need to trick this) - - PYTHON_LDFLAGS="" - case $host_os in - *mingw* | *cygwin* ) - AC_MSG_CHECKING([for Python LDFLAGS]) - - python_cmd=' -import distutils.sysconfig -import os -path = distutils.sysconfig.get_config_var("LIBPL") -if path == None: - path = distutils.sysconfig.PREFIX + "/libs" -if os.sep == "\\": - path = path.replace("\\", "/") -print path -' - python_stdlib_path=`$PYTHON -c "$python_cmd"` - - python_version_nodot=`echo $PYTHON_VERSION | sed "s,\.,,"` - libpython_name="python$PYTHON_VERSION" - - # Standard install of python for win32 has libpython24.a - # instead of libpython2.4.a so we check for the library - # without the dot in the version number. - - python_stdlib_filename=`find $python_stdlib_path -type f -name libpython$python_version_nodot.* -print | sed "1q"` - if test -n "$python_stdlib_filename" ; then - libpython_name="python$python_version_nodot" - fi - - PYTHON_LDFLAGS="-L$python_stdlib_path -l$libpython_name" - AC_MSG_RESULT($PYTHON_LDFLAGS) - # Replace all backslashes in PYTHON Paths with forward slashes - pythondir=`echo $pythondir |sed 's,\\\\,/,g'` - pkgpythondir=`echo $pkgpythondir |sed 's,\\\\,/,g'` - pyexecdir=`echo $pyexecdir |sed 's,\\\\,/,g'` - pkgpyexecdir=`echo $pkgpyexecdir |sed 's,\\\\,/,g'` - ;; - esac - - AC_SUBST([PYTHON_LDFLAGS]) -]) diff --git a/config/gr_require_mc4020.m4 b/config/gr_require_mc4020.m4 deleted file mode 100644 index 90774fd..0000000 --- a/config/gr_require_mc4020.m4 +++ /dev/null @@ -1,33 +0,0 @@ -dnl -dnl Copyright 2003,2004 Free Software Foundation, Inc. -dnl -dnl This file is part of GNU Radio -dnl -dnl GNU Radio is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3, or (at your option) -dnl any later version. -dnl -dnl GNU Radio is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with GNU Radio; see the file COPYING. If not, write to -dnl the Free Software Foundation, Inc., 51 Franklin Street, -dnl Boston, MA 02110-1301, USA. -dnl - -AC_DEFUN([GR_REQUIRE_MC4020],[ - AC_MSG_CHECKING([for mc4020 A/D driver include file]) - AC_COMPILE_IFELSE([ -#include -int main (int argc, char **argv) -{ - return 0; -} -],[AC_MSG_RESULT([yes])], - [AC_MSG_RESULT([no]) - AC_MSG_ERROR([mc4020.h not found.])]) -]) diff --git a/config/gr_scripting.m4 b/config/gr_scripting.m4 deleted file mode 100644 index 86870e7..0000000 --- a/config/gr_scripting.m4 +++ /dev/null @@ -1,30 +0,0 @@ -dnl -dnl Copyright 2003 Free Software Foundation, Inc. -dnl -dnl This file is part of GNU Radio -dnl -dnl GNU Radio is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3, or (at your option) -dnl any later version. -dnl -dnl GNU Radio is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with GNU Radio; see the file COPYING. If not, write to -dnl the Free Software Foundation, Inc., 51 Franklin Street, -dnl Boston, MA 02110-1301, USA. -dnl - -AC_DEFUN([GR_SCRIPTING],[ - AC_REQUIRE([AC_PROG_LN_S]) - AC_REQUIRE([AC_PROG_CXX]) - AC_REQUIRE([AC_PROG_LIBTOOL]) - - SWIG_PROG(1.3.23) - SWIG_ENABLE_CXX - SWIG_PYTHON -]) diff --git a/config/gr_set_md_cpu.m4 b/config/gr_set_md_cpu.m4 deleted file mode 100644 index ebc1fad..0000000 --- a/config/gr_set_md_cpu.m4 +++ /dev/null @@ -1,44 +0,0 @@ -dnl -dnl Copyright 2003 Free Software Foundation, Inc. -dnl -dnl This file is part of GNU Radio -dnl -dnl GNU Radio is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3, or (at your option) -dnl any later version. -dnl -dnl GNU Radio is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with GNU Radio; see the file COPYING. If not, write to -dnl the Free Software Foundation, Inc., 51 Franklin Street, -dnl Boston, MA 02110-1301, USA. -dnl - -AC_DEFUN([GR_SET_MD_CPU],[ - AC_REQUIRE([AC_CANONICAL_HOST]) - AC_ARG_WITH(md-cpu, - [ --with-md-cpu=ARCH set machine dependent speedups (auto)], - [cf_with_md_cpu="$withval"], - [cf_with_md_cpu="$host_cpu"]) - - AC_MSG_CHECKING([for machine dependent speedups]) - case "$cf_with_md_cpu" in - x86 | i[[3-7]]86) MD_CPU=x86 MD_SUBCPU=x86 ;; - x86_64) MD_CPU=x86 MD_SUBCPU=x86_64 ;; -# sparc) MD_CPU=sparc ;; - *) MD_CPU=generic ;; - esac - AC_MSG_RESULT($MD_CPU) - AC_SUBST(MD_CPU) - AC_SUBST(MD_SUBCPU) - - AM_CONDITIONAL(MD_CPU_x86, test $MD_CPU = x86) - AM_CONDITIONAL(MD_SUBCPU_x86_64, test $MD_SUBCPU = x86_64) - AM_CONDITIONAL(MD_CPU_generic, test $MD_CPU = generic) -]) - diff --git a/config/gr_swig.m4 b/config/gr_swig.m4 deleted file mode 100644 index cdb2805..0000000 --- a/config/gr_swig.m4 +++ /dev/null @@ -1,85 +0,0 @@ -dnl -dnl Copyright 2003 Free Software Foundation, Inc. -dnl -dnl This file is part of GNU Radio -dnl -dnl GNU Radio is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3, or (at your option) -dnl any later version. -dnl -dnl GNU Radio is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with GNU Radio; see the file COPYING. If not, write to -dnl the Free Software Foundation, Inc., 51 Franklin Street, -dnl Boston, MA 02110-1301, USA. -dnl - -# SWIG_PROG([required-version]) -# -# Checks for the SWIG program. If found you can (and should) call SWIG via $(SWIG). -# You can use the optional first argument to check if the version of the available SWIG -# is greater or equal to the value of the argument. It should have the format: -# N[.N[.N]] (N is a number between 0 and 999. Only the first N is mandatory.) -AC_DEFUN([SWIG_PROG],[ - AC_REQUIRE([AC_PROG_MAKE_SET]) - AC_CHECK_PROG(SWIG,swig,[`which swig`]) - if test -z "$SWIG" ; then - AC_MSG_ERROR([Cannot find 'swig' program. SWIG version >= $1 required]) - SWIG=false - elif test -n "$1" ; then - AC_MSG_CHECKING([for SWIG version]) - swig_version=`$SWIG -version 2>&1 | \ - awk '/^SWIG Version [[0-9]+\.[0-9]+\.[0-9]]+.*$/ { split($[3],a,"[[^.0-9]]"); print a[[1]] }'` - AC_MSG_RESULT([$swig_version]) - if test -n "$swig_version" ; then - swig_version=`echo $swig_version | \ - awk '{ split($[1],a,"\."); print [a[1]*1000000+a[2]*1000+a[3]] }' 2>/dev/null` - swig_required_version=`echo $1 | \ - awk '{ split($[1],a,"\."); print [a[1]*1000000+a[2]*1000+a[3]] }' 2>/dev/null` - if test $swig_required_version -gt $swig_version ; then - AC_MSG_ERROR([SWIG version >= $1 required]) - fi - else - AC_MSG_ERROR([cannot determine SWIG version]) - fi - fi -]) - -# SWIG_ENABLE_CXX() -# -# Enable swig C++ support. This effects all invocations of $(SWIG). -AC_DEFUN([SWIG_ENABLE_CXX],[ - AC_REQUIRE([SWIG_PROG]) - AC_REQUIRE([AC_PROG_CXX]) - if test "$SWIG" != "false" ; then - SWIG="$SWIG -c++" - fi -]) - -# SWIG_PYTHON([use-shadow-classes]) -# -# Checks for Python and provides the $(SWIG_PYTHON_CPPFLAGS), -# $(SWIG_PYTHON_LIB) and $(SWIG_PYTHON_OPT) output variables. -# $(SWIG_PYTHON_OPT) contains all necessary swig options to generate -# code for Python. If you need multi module support use -# $(SWIG_PYTHON_LIB) (provided by the SWIG_MULTI_MODULE_SUPPORT() -# macro) to link against the appropriate library. It contains the -# SWIG Python runtime library that is needed by the type check system -# for example. - -AC_DEFUN([SWIG_PYTHON],[ - AC_REQUIRE([SWIG_PROG]) - AC_REQUIRE([PYTHON_DEVEL]) - if test "$SWIG" != "false" ; then - AC_SUBST(SWIG_PYTHON_LIB,[-lswigpy]) -dnl test ! "x$1" = "xno" && swig_shadow=" -shadow" || swig_shadow="" -dnl AC_SUBST(SWIG_PYTHON_OPT,[-python$swig_shadow]) - AC_SUBST(SWIG_PYTHON_OPT,[-python]) - fi - AC_SUBST(SWIG_PYTHON_CPPFLAGS,[$PYTHON_CPPFLAGS]) -]) diff --git a/config/gr_sysv_shm.m4 b/config/gr_sysv_shm.m4 deleted file mode 100644 index db5c835..0000000 --- a/config/gr_sysv_shm.m4 +++ /dev/null @@ -1,36 +0,0 @@ -# Check for IPC System V shm support. -*- Autoconf -*- - -# Copyright 2003 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, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Boston, MA -# 02110-1301, USA. - -AC_DEFUN([GR_SYSV_SHM], -[ - AC_LANG_SAVE - AC_LANG_C - - AC_CHECK_HEADERS([sys/ipc.h sys/shm.h]) - - save_LIBS="$LIBS" - AC_SEARCH_LIBS(shmat, [cygipc ipc], - [ IPC_LIBS="$LIBS" ], - [ AC_MSG_WARN([SystemV IPC support not found. ]) ] - ) - LIBS="$save_LIBS" - - AC_LANG_RESTORE - AC_SUBST(IPC_LIBS) -]) diff --git a/config/gr_x86_64.m4 b/config/gr_x86_64.m4 deleted file mode 100644 index 3f56c06..0000000 --- a/config/gr_x86_64.m4 +++ /dev/null @@ -1,39 +0,0 @@ -dnl -dnl Copyright 2005 Free Software Foundation, Inc. -dnl -dnl This file is part of GNU Radio -dnl -dnl GNU Radio is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3, or (at your option) -dnl any later version. -dnl -dnl GNU Radio is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with GNU Radio; see the file COPYING. If not, write to -dnl the Free Software Foundation, Inc., 51 Franklin Street, -dnl Boston, MA 02110-1301, USA. -dnl - -# GR_X86_64() -# -# Checks to see if we're on a x86_64 machine, and if so, ensure -# that libdir ends in "64" -# -AC_DEFUN([GR_X86_64],[ - AC_REQUIRE([AC_CANONICAL_HOST]) - if test "$host_cpu" = "x86_64"; then - AC_MSG_CHECKING([libdir for lib64 suffix]) - t=${libdir##*/lib} - if test "$t" != 64 && test -d /lib64 && ! test -L /lib64; then - libdir=${libdir}64 - AC_MSG_RESULT([no. Setting libdir to $libdir]) - else - AC_MSG_RESULT([yes]) - fi - fi -]) diff --git a/config/lf_cc.m4 b/config/lf_cc.m4 deleted file mode 100644 index b9d1c9c..0000000 --- a/config/lf_cc.m4 +++ /dev/null @@ -1,42 +0,0 @@ -dnl Autoconf support for C++ -dnl Copyright (C) 1988 Eleftherios Gkioulekas -dnl -dnl This program is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3 of the License, or -dnl (at your option) any later version. -dnl -dnl This program is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with this program; if not, write to the Free Software -dnl Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301, USA. -dnl -dnl As a special exception to the GNU General Public License, if you -dnl distribute this file as part of a program that contains a configuration -dnl script generated by Autoconf, you may include it under the same -dnl distribution terms that you use for the rest of that program. - -# ------------------------------------------------------------------------- -# Use this macro to configure your C compiler -# When called the macro does the following things: -# 1. It finds an appropriate C compiler. -# If you passed the flag --with-cc=foo then it uses that -# particular compiler -# 2. Check whether the compiler works. -# 3. Checks whether the compiler accepts the -g -# ------------------------------------------------------------------------- - -AC_DEFUN([LF_CONFIGURE_CC],[ - dnl Sing the song - AC_REQUIRE([AC_PROG_CC])dnl - AC_REQUIRE([AC_PROG_CPP])dnl - AC_REQUIRE([AC_AIX])dnl - AC_REQUIRE([AC_ISC_POSIX])dnl - AC_REQUIRE([AC_MINIX])dnl - AC_REQUIRE([AC_HEADER_STDC])dnl -]) - diff --git a/config/lf_cxx.m4 b/config/lf_cxx.m4 deleted file mode 100644 index c581c9b..0000000 --- a/config/lf_cxx.m4 +++ /dev/null @@ -1,121 +0,0 @@ -dnl Autoconf support for C++ -dnl Copyright (C) 1988 Eleftherios Gkioulekas -dnl -dnl This program is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3 of the License, or -dnl (at your option) any later version. -dnl -dnl This program is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with this program; if not, write to the Free Software -dnl Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301, USA. -dnl -dnl As a special exception to the GNU General Public License, if you -dnl distribute this file as part of a program that contains a configuration -dnl script generated by Autoconf, you may include it under the same -dnl distribution terms that you use for the rest of that program. - -# ----------------------------------------------------------------- -# This macro should be called to configure your C++ compiler. -# When called, the macro does the following things: -# 1. It finds an appropriate C++ compiler -# If you passed the flag --with-cxx=foo, then it uses that -# particular compiler -# 2. Checks whether the compiler accepts the -g -# ------------------------------------------------------------------ - -AC_DEFUN([LF_CONFIGURE_CXX],[ - AC_REQUIRE([AC_PROG_CXX])dnl - AC_REQUIRE([AC_PROG_CXXCPP])dnl - LF_CXX_PORTABILITY -]) - -# ----------------------------------------------------------------------- -# This macro tests the C++ compiler for various portability problem. -# 1. Defines CXX_HAS_NO_BOOL if the compiler does not support the bool -# data type -# 2. Defines CXX_HAS_BUGGY_FOR_LOOPS if the compiler has buggy -# scoping for the for-loop -# 3. Defines USE_ASSERT if the user wants to use assertions -# ----------------------------------------------------------------------- - - -AC_DEFUN([LF_CXX_PORTABILITY],[ - - dnl - dnl Check for common C++ portability problems - dnl - - dnl AC_LANG_PUSH - dnl AC_LANG_CPLUSPLUS - AC_LANG_SAVE - AC_LANG_CPLUSPLUS - - dnl Check whether we have bool - AC_MSG_CHECKING(whether C++ has bool) - AC_TRY_RUN([main() { bool b1=true; bool b2=false; }], - [ AC_MSG_RESULT(yes) ], - [ AC_MSG_RESULT(no) - AC_DEFINE(CXX_HAS_NO_BOOL,[],[Define if C++ is missing bool type]) ], - [ AC_MSG_WARN(Don't cross-compile)] - ) - - dnl Test whether C++ has buggy for-loops - AC_MSG_CHECKING(whether C++ has buggy scoping in for-loops) - AC_TRY_COMPILE([#include ], [ - for (int i=0;i<10;i++) { } - for (int i=0;i<10;i++) { } -], [ AC_MSG_RESULT(no) ], - [ AC_MSG_RESULT(yes) - AC_DEFINE(CXX_HAS_BUGGY_FOR_LOOPS,[],[Define if for loop scoping is broken]) ]) - - dnl Test whether the user wants to enable assertions - AC_MSG_CHECKING(whether user wants assertions) - AC_ARG_ENABLE(assert, - [ --disable-assert don't use cpp.h assert], - [ AC_DEFINE(NDEBUG,[],[Define to disable asserts (don't doit!)]) - AC_MSG_RESULT(no) ], - [ AC_MSG_RESULT(yes) ], - ) - - dnl Test whether C++ has std::isnan - AC_MSG_CHECKING(whether C++ has std::isnan) - AC_TRY_COMPILE([#include ], [ - std::isnan(0); -], [ AC_MSG_RESULT(yes) - AC_DEFINE(CXX_HAS_STD_ISNAN,[],[Define if has std::isnan]) ], - [ AC_MSG_RESULT(no) ]) - - dnl Done with the portability checks - dnl AC_LANG_POP([C++]) - AC_LANG_RESTORE -]) - -AH_BOTTOM([// Workaround for compilers with buggy for-loop scoping -// That's quite a few compilers actually including recent versions of -// Dec Alpha cxx, HP-UX CC and SGI CC. -// The trivial "if" statement provides the correct scoping to the -// for loop - -#ifdef CXX_HAS_BUGGY_FOR_LOOPS -#undef for -#define for if(1) for -#endif -]) - -AH_BOTTOM([// If the C++ compiler we use doesn't have bool, then -// the following is a near-perfect work-around. -// You must make sure your code does not depend on "int" and "bool" -// being two different types, in overloading for instance. - -#ifdef CXX_HAS_NO_BOOL -#define bool int -#define true 1 -#define false 0 -#endif -]) diff --git a/config/lf_warnings.m4 b/config/lf_warnings.m4 deleted file mode 100644 index 4e2ca91..0000000 --- a/config/lf_warnings.m4 +++ /dev/null @@ -1,128 +0,0 @@ -dnl Copyright (C) 1988 Eleftherios Gkioulekas -dnl -dnl This program is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3 of the License, or -dnl (at your option) any later version. -dnl -dnl This program is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with this program; if not, write to the Free Software -dnl Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301, USA. -dnl -dnl As a special exception to the GNU General Public License, if you -dnl distribute this file as part of a program that contains a configuration -dnl script generated by Autoconf, you may include it under the same -dnl distribution terms that you use for the rest of that program. - -# -------------------------------------------------------------------------- -# Check whether the C++ compiler accepts a certain flag -# If it does it adds the flag to CXXFLAGS -# If it does not then it returns an error to lf_ok -# Usage: -# LF_CHECK_CXX_FLAG(-flag1 -flag2 -flag3 ...) -# ------------------------------------------------------------------------- - -AC_DEFUN([LF_CHECK_CXX_FLAG],[ - echo 'void f(){}' > conftest.cc - for i in $1 - do - AC_MSG_CHECKING([whether $CXX accepts $i]) - if test -z "`${CXX} $i -c conftest.cc 2>&1`" - then - CXXFLAGS="${CXXFLAGS} $i" - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - fi - done - rm -f conftest.cc conftest.o -]) - -# -------------------------------------------------------------------------- -# Check whether the C compiler accepts a certain flag -# If it does it adds the flag to CFLAGS -# If it does not then it returns an error to lf_ok -# Usage: -# LF_CHECK_CC_FLAG(-flag1 -flag2 -flag3 ...) -# ------------------------------------------------------------------------- - -AC_DEFUN([LF_CHECK_CC_FLAG],[ - echo 'void f(){}' > conftest.c - for i in $1 - do - AC_MSG_CHECKING([whether $CC accepts $i]) - if test -z "`${CC} $i -c conftest.c 2>&1`" - then - CFLAGS="${CFLAGS} $i" - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - fi - done - rm -f conftest.c conftest.o -]) - -# -------------------------------------------------------------------------- -# Check whether the Fortran compiler accepts a certain flag -# If it does it adds the flag to FFLAGS -# If it does not then it returns an error to lf_ok -# Usage: -# LF_CHECK_F77_FLAG(-flag1 -flag2 -flag3 ...) -# ------------------------------------------------------------------------- - -AC_DEFUN([LF_CHECK_F77_FLAG],[ - cat << EOF > conftest.f -c....:++++++++++++++++++++++++ - PROGRAM MAIN - PRINT*,'Hello World!' - END -EOF - for i in $1 - do - AC_MSG_CHECKING([whether $F77 accepts $i]) - if test -z "`${F77} $i -c conftest.f 2>&1`" - then - FFLAGS="${FFLAGS} $i" - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - fi - done - rm -f conftest.f conftest.o -]) - -# ---------------------------------------------------------------------- -# Provide the configure script with an --with-warnings option that -# turns on warnings. Call this command AFTER you have configured ALL your -# compilers. -# ---------------------------------------------------------------------- - -AC_DEFUN([LF_SET_WARNINGS],[ - dnl Check for --with-warnings - AC_MSG_CHECKING([whether user wants warnings]) - AC_ARG_WITH(warnings, - [ --with-warnings Turn on warnings], - [ lf_warnings=yes ], [ lf_warnings=no ]) - lf_warnings=yes # hard code for now -eb - AC_MSG_RESULT($lf_warnings) - - dnl Warnings for the two main compilers - cc_warning_flags="-Wall" - cxx_warning_flags="-Wall -Woverloaded-virtual" - if test $lf_warnings = yes - then - if test -n "${CC}" - then - LF_CHECK_CC_FLAG($cc_warning_flags) - fi - if test -n "${CXX}" - then - LF_CHECK_CXX_FLAG($cxx_warning_flags) - fi - fi -]) diff --git a/config/lf_x11.m4 b/config/lf_x11.m4 deleted file mode 100644 index 460cd60..0000000 --- a/config/lf_x11.m4 +++ /dev/null @@ -1,39 +0,0 @@ -dnl Copyright (C) 1988 Eleftherios Gkioulekas -dnl -dnl This program is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3 of the License, or -dnl (at your option) any later version. -dnl -dnl This program is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with this program; if not, write to the Free Software -dnl Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301, USA. -dnl -dnl As a special exception to the GNU General Public License, if you -dnl distribute this file as part of a program that contains a configuration -dnl script generated by Autoconf, you may include it under the same -dnl distribution terms that you use for the rest of that program. - - -#----------------------------------------------------------------------- -# This macro searches for Xlib and when it finds it it adds the -# appropriate flags to CXXFLAGS and export the link sequence to -# the variable XLIB. -# In your configure.in file add: -# LF_PATH_XLIB -# In your Makefile.am add -# program_LDADD = .... $(XLIB) -#------------------------------------------------------------------------ - -AC_DEFUN([LF_PATH_XLIB],[ - AC_PATH_XTRA - CXXFLAGS="$CXXFLAGS $X_CFLAGS" - XLIB="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS" - AC_SUBST(XLIB) -]) - diff --git a/config/mkstemp.m4 b/config/mkstemp.m4 deleted file mode 100644 index 4af0f0a..0000000 --- a/config/mkstemp.m4 +++ /dev/null @@ -1,89 +0,0 @@ -#serial 4 - -# On some hosts (e.g., HP-UX 10.20, SunOS 4.1.4, Solaris 2.5.1), mkstemp has a -# silly limit that it can create no more than 26 files from a given template. -# Other systems lack mkstemp altogether. -# On OSF1/Tru64 V4.0F, the system-provided mkstemp function can create -# only 32 files per process. -# On systems like the above, arrange to use the replacement function. -AC_DEFUN([UTILS_FUNC_MKSTEMP], -[dnl - AC_REPLACE_FUNCS(mkstemp) - if test $ac_cv_func_mkstemp = no; then - utils_cv_func_mkstemp_limitations=yes - else - AC_CACHE_CHECK([for mkstemp limitations], - utils_cv_func_mkstemp_limitations, - [ - AC_TRY_RUN([ -# include - int main () - { - int i; - for (i = 0; i < 70; i++) - { - char template[] = "conftestXXXXXX"; - int fd = mkstemp (template); - if (fd == -1) - exit (1); - close (fd); - } - exit (0); - } - ], - utils_cv_func_mkstemp_limitations=no, - utils_cv_func_mkstemp_limitations=yes, - utils_cv_func_mkstemp_limitations=yes - ) - ] - ) - fi - - if test $utils_cv_func_mkstemp_limitations = yes; then - AC_LIBOBJ(mkstemp) - AC_LIBOBJ(tempname) - AC_DEFINE(mkstemp, rpl_mkstemp, - [Define to rpl_mkstemp if the replacement function should be used.]) - gl_PREREQ_MKSTEMP - jm_PREREQ_TEMPNAME - fi -]) - -# Prerequisites of lib/mkstemp.c. -AC_DEFUN([gl_PREREQ_MKSTEMP], -[ - AH_BOTTOM( - [ - #ifndef HAVE_MKSTEMP - #ifdef __cplusplus - extern "C" { - #endif - int rpl_mkstemp (char *templ); - #ifdef __cplusplus - } - #endif - #endif - ]) -]) - -# Prerequisites of lib/tempname.c. -AC_DEFUN([jm_PREREQ_TEMPNAME], -[ - AC_REQUIRE([AC_HEADER_STAT]) - AC_CHECK_HEADERS_ONCE(fcntl.h sys/time.h unistd.h) - AC_CHECK_HEADERS(stdint.h) - AC_CHECK_FUNCS(__secure_getenv gettimeofday lstat) - AC_CHECK_DECLS_ONCE(getenv) - # AC_REQUIRE([jm_AC_TYPE_UINTMAX_T]) - - dnl Under Win32, mkdir prototype in io.h has only one arg - AC_MSG_CHECKING(whether mkdir accepts only one arg) - AC_TRY_COMPILE([#include - #include - #include ], [ - mkdir("") - ], [ AC_MSG_RESULT(yes) - AC_DEFINE(MKDIR_TAKES_ONE_ARG,[],[Define if mkdir accepts only one arg]) ], - [ AC_MSG_RESULT(no) - ]) -]) diff --git a/config/onceonly.m4 b/config/onceonly.m4 deleted file mode 100644 index f6fec37..0000000 --- a/config/onceonly.m4 +++ /dev/null @@ -1,63 +0,0 @@ -# onceonly.m4 serial 3 -dnl Copyright (C) 2002, 2003 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl This file defines some "once only" variants of standard autoconf macros. -dnl AC_CHECK_HEADERS_ONCE like AC_CHECK_HEADERS -dnl AC_CHECK_FUNCS_ONCE like AC_CHECK_FUNCS -dnl AC_CHECK_DECLS_ONCE like AC_CHECK_DECLS -dnl AC_REQUIRE([AC_HEADER_STDC]) like AC_HEADER_STDC -dnl The advantage is that the check for each of the headers/functions/decls -dnl will be put only once into the 'configure' file. It keeps the size of -dnl the 'configure' file down, and avoids redundant output when 'configure' -dnl is run. -dnl The drawback is that the checks cannot be conditionalized. If you write -dnl if some_condition; then gl_CHECK_HEADERS(stdlib.h); fi -dnl inside an AC_DEFUNed function, the gl_CHECK_HEADERS macro call expands to -dnl empty, and the check will be inserted before the body of the AC_DEFUNed -dnl function. - -dnl Autoconf version 2.57 or newer is recommended. -AC_PREREQ(2.54) - -# AC_CHECK_HEADERS_ONCE(HEADER1 HEADER2 ...) is a once-only variant of -# AC_CHECK_HEADERS(HEADER1 HEADER2 ...). -AC_DEFUN([AC_CHECK_HEADERS_ONCE], [ - : - AC_FOREACH([gl_HEADER_NAME], [$1], [ - AC_DEFUN([gl_CHECK_HEADER_]m4_quote(translit(defn([gl_HEADER_NAME]), - [-./], [___])), [ - AC_CHECK_HEADERS(gl_HEADER_NAME) - ]) - AC_REQUIRE([gl_CHECK_HEADER_]m4_quote(translit(gl_HEADER_NAME, - [-./], [___]))) - ]) -]) - -# AC_CHECK_FUNCS_ONCE(FUNC1 FUNC2 ...) is a once-only variant of -# AC_CHECK_FUNCS(FUNC1 FUNC2 ...). -AC_DEFUN([AC_CHECK_FUNCS_ONCE], [ - : - AC_FOREACH([gl_FUNC_NAME], [$1], [ - AC_DEFUN([gl_CHECK_FUNC_]defn([gl_FUNC_NAME]), [ - AC_CHECK_FUNCS(defn([gl_FUNC_NAME])) - ]) - AC_REQUIRE([gl_CHECK_FUNC_]defn([gl_FUNC_NAME])) - ]) -]) - -# AC_CHECK_DECLS_ONCE(DECL1 DECL2 ...) is a once-only variant of -# AC_CHECK_DECLS(DECL1, DECL2, ...). -AC_DEFUN([AC_CHECK_DECLS_ONCE], [ - : - AC_FOREACH([gl_DECL_NAME], [$1], [ - AC_DEFUN([gl_CHECK_DECL_]defn([gl_DECL_NAME]), [ - AC_CHECK_DECLS(defn([gl_DECL_NAME])) - ]) - AC_REQUIRE([gl_CHECK_DECL_]defn([gl_DECL_NAME])) - ]) -]) diff --git a/config/pkg.m4 b/config/pkg.m4 deleted file mode 100644 index 770f062..0000000 --- a/config/pkg.m4 +++ /dev/null @@ -1,68 +0,0 @@ -dnl PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not) -dnl defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page -dnl also defines GSTUFF_PKG_ERRORS on error -AC_DEFUN([PKG_CHECK_MODULES], [ - succeeded=no - - if test -z "$PKG_CONFIG"; then - AC_PATH_PROG(PKG_CONFIG, pkg-config, no) - fi - - if test "$PKG_CONFIG" = "no" ; then - echo "*** The pkg-config script could not be found. Make sure it is" - echo "*** in your path, or set the PKG_CONFIG environment variable" - echo "*** to the full path to pkg-config." - echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." - else - dnl If PKG_CONFIG_PATH is not already set, add /usr/local/lib/pkgconfig. - dnl If it's set, assume the user knows what they're doing. - dnl This should help avoid failures while looking for fftw3f - if test -z "$PKG_CONFIG_PATH"; then - export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig" - fi - - PKG_CONFIG_MIN_VERSION=0.9.0 - if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then - AC_MSG_CHECKING(for $2) - - if $PKG_CONFIG --exists "$2" ; then - AC_MSG_RESULT(yes) - succeeded=yes - - AC_MSG_CHECKING($1_CFLAGS) - $1_CFLAGS=`$PKG_CONFIG --cflags "$2"` - AC_MSG_RESULT($$1_CFLAGS) - - AC_MSG_CHECKING($1_LIBS) - $1_LIBS=`$PKG_CONFIG --libs "$2"` - AC_MSG_RESULT($$1_LIBS) - - AC_MSG_CHECKING($1_INCLUDEDIR) - $1_INCLUDEDIR=`$PKG_CONFIG --variable=includedir "$2"` - AC_MSG_RESULT($$1_INCLUDEDIR) - else - $1_CFLAGS="" - $1_LIBS="" - ## If we have a custom action on failure, don't print errors, but - ## do set a variable so people can do so. - $1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` - ifelse([$4], ,echo $$1_PKG_ERRORS,) - fi - - AC_SUBST($1_CFLAGS) - AC_SUBST($1_LIBS) - AC_SUBST($1_INCLUDEDIR) - else - echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." - echo "*** See http://www.freedesktop.org/software/pkgconfig" - fi - fi - - if test $succeeded = yes; then - ifelse([$3], , :, [$3]) - else - ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4]) - fi -]) - - diff --git a/config/usrp_fusb_tech.m4 b/config/usrp_fusb_tech.m4 deleted file mode 100644 index b5a930b..0000000 --- a/config/usrp_fusb_tech.m4 +++ /dev/null @@ -1,56 +0,0 @@ -dnl -dnl Copyright 2003 Free Software Foundation, Inc. -dnl -dnl This file is part of GNU Radio -dnl -dnl GNU Radio is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3, or (at your option) -dnl any later version. -dnl -dnl GNU Radio is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with GNU Radio; see the file COPYING. If not, write to -dnl the Free Software Foundation, Inc., 51 Franklin Street, -dnl Boston, MA 02110-1301, USA. -dnl - -AC_DEFUN([USRP_SET_FUSB_TECHNIQUE],[ - AC_REQUIRE([AC_CANONICAL_HOST]) - AC_ARG_WITH(fusb-tech, - [ --with-fusb-tech=OS set fast usb technique (auto)], - [cf_with_fusb_tech="$withval"], - [cf_with_fusb_tech="$host_os"]) - - - AC_CHECK_HEADER([linux/usbdevice_fs.h], - [x_have_usbdevice_fs_h=yes], - [x_have_usbdevice_fs_h=no]) - - AC_MSG_CHECKING([for fast usb technique to use]) - case "$cf_with_fusb_tech" in - linux*) if test x${x_have_usbdevice_fs_h} = xyes; - then - FUSB_TECH=linux - else - FUSB_TECH=generic - fi ;; - - darwin*) FUSB_TECH=darwin ;; - cygwin*|win*|mingw*) FUSB_TECH=win32 ;; - *) FUSB_TECH=generic ;; - esac - - AC_MSG_RESULT($FUSB_TECH) - AC_SUBST(FUSB_TECH) - - AM_CONDITIONAL(FUSB_TECH_darwin, test $FUSB_TECH = darwin) - AM_CONDITIONAL(FUSB_TECH_win32, test $FUSB_TECH = win32) - AM_CONDITIONAL(FUSB_TECH_generic, test $FUSB_TECH = generic) - AM_CONDITIONAL(FUSB_TECH_linux, test $FUSB_TECH = linux) -]) - diff --git a/config/usrp_libusb.m4 b/config/usrp_libusb.m4 deleted file mode 100644 index 9fe4753..0000000 --- a/config/usrp_libusb.m4 +++ /dev/null @@ -1,43 +0,0 @@ -# Check for libusb support. -*- Autoconf -*- - -# Copyright 2003 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, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Boston, MA -# 02110-1301, USA. - -AC_DEFUN([USRP_LIBUSB], -[ - AC_REQUIRE([AC_CANONICAL_HOST]) - AC_LANG_PUSH(C) - - AC_CHECK_HEADERS([usb.h], - [], - [ AC_MSG_ERROR([USRP requires libusb. usb.h not found, stop. See http://libusb.sf.net]) ] - ) - - save_LIBS="$LIBS" - case "$host_os" in - darwin*) LIBS="$LIBS -lIOKit" ;; - *) ;; - esac - AC_SEARCH_LIBS(usb_bulk_write, [usb], - [ USB_LIBS="$LIBS" ], - [ AC_MSG_ERROR([USRP requires libusb. usb_bulk_write not found, stop. See http://libusb.sf.net]) ] - ) - LIBS="$save_LIBS" - - AC_LANG_POP - AC_SUBST(USB_LIBS) -]) diff --git a/config/usrp_sdcc.m4 b/config/usrp_sdcc.m4 deleted file mode 100644 index 37ce7c3..0000000 --- a/config/usrp_sdcc.m4 +++ /dev/null @@ -1,67 +0,0 @@ -# Check for sdcc support. -*- Autoconf -*- - -# Copyright 2004 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, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Boston, MA -# 02110-1301, USA. - -AC_DEFUN([USRP_SDCC], -[ - AC_CHECK_PROG(XCC, sdcc, sdcc -mmcs51 --no-xinit-opt,no) - AC_CHECK_PROG(XAS, asx8051, asx8051 -plosgff,no) - - if test "$XCC" = "no" -o "$XAS" = "no" ; then - AC_MSG_ERROR([USRP requires sdcc. sdcc not found, stop. See http://sdcc.sf.net]) - fi - - sdcc_version_min=$1 - - sdcc_version=`sdcc --version 2>&1 | \ - sed 's/\(SDCC.* \)\([[0-9]]*\.[[0-9]]*\.[[0-9]]*\)\( .*$\)/\2/'` - - AC_MSG_CHECKING([sdcc_version "$sdcc_version"]) - - sdcc_major_version=`echo $sdcc_version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` - sdcc_minor_version=`echo $sdcc_version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` - sdcc_micro_version=`echo $sdcc_version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` - - sdcc_major_min=`echo $sdcc_version_min | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` - sdcc_minor_min=`echo $sdcc_version_min | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` - sdcc_micro_min=`echo $sdcc_version_min | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` - - sdcc_version_proper=`expr \ - "$sdcc_major_version" \> "$sdcc_major_min" \| \ - "$sdcc_major_version" \= "$sdcc_major_min" \& \ - "$sdcc_minor_version" \> "$sdcc_minor_min" \| \ - "$sdcc_major_version" \= "$sdcc_major_min" \& \ - "$sdcc_minor_version" \= "$sdcc_minor_min" \& \ - "$sdcc_micro_version" \>= "$sdcc_micro_min" ` - - if test "$sdcc_version_proper" = "1" ; then - AC_MSG_RESULT([$sdcc_major_version.$sdcc_minor_version.$sdcc_micro_version]) - else - AC_MSG_ERROR([USRP requires sdcc >= $sdcc_version_min. sdcc not found, stop. See http://sdcc.sf.net]) - fi - - AC_SUBST(XCC) - AC_SUBST(XAS) - -]) diff --git a/configure.ac b/configure.ac deleted file mode 100644 index 30fe57a..0000000 --- a/configure.ac +++ /dev/null @@ -1,120 +0,0 @@ -dnl -dnl Copyright 2004,2005,2006,2007,2008 Free Software Foundation, Inc. -dnl -dnl This file is part of GNU Radio -dnl -dnl GNU Radio is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3, or (at your option) -dnl any later version. -dnl -dnl GNU Radio is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with GNU Radio; see the file COPYING. If not, write to -dnl the Free Software Foundation, Inc., 51 Franklin Street, -dnl Boston, MA 02110-1301, USA. -dnl - -AC_INIT -AC_PREREQ(2.61) -AC_CONFIG_SRCDIR([src/lib/gsm.i]) -AM_CONFIG_HEADER(config.h) -AC_CANONICAL_TARGET([]) -AC_CONFIG_AUX_DIR([.]) -AM_INIT_AUTOMAKE(gsm-receiver,0.0.1) -AC_CONFIG_MACRO_DIR([config]) - -GR_X86_64 -dnl LF_CONFIGURE_CC -LF_CONFIGURE_CXX -LF_SET_WARNINGS - -dnl add ${prefix}/lib${gr_libdir_suffix}/pkgconfig to the head of the PKG_CONFIG_PATH -if test x${PKG_CONFIG_PATH} = x; then - PKG_CONFIG_PATH=${prefix}/lib${gr_libdir_suffix}/pkgconfig -else - PKG_CONFIG_PATH=${prefix}/lib${gr_libdir_suffix}/pkgconfig:${PKG_CONFIG_PATH} -fi -export PKG_CONFIG_PATH - - -GR_SET_GPROF -GR_SET_PROF -AM_PROG_AS -AC_PROG_LN_S -AC_PROG_MAKE_SET -AC_PROG_INSTALL -AC_PATH_PROG([RM_PROG], [rm]) - -AC_LIBTOOL_WIN32_DLL -AC_ENABLE_SHARED dnl do build shared libraries -AC_DISABLE_STATIC dnl don't build static libraries -m4_ifdef([LT_INIT],[LT_INIT],[AC_PROG_LIBTOOL]) -dnl Locate python, SWIG, etc -GR_NO_UNDEFINED -GR_SCRIPTING - -dnl Checks for libraries. - -dnl check for threads (mandatory) -GR_OMNITHREAD - -CFLAGS="${CFLAGS} $PTHREAD_CFLAGS" -CXXFLAGS="${CXXFLAGS} $PTHREAD_CFLAGS" - -if test "x$CXX_FOR_BUILD" = x -then - CXX_FOR_BUILD=${CXX} -fi -AC_SUBST(CXX_FOR_BUILD) - -dnl Checks for header files. -AC_HEADER_STDC -AC_HEADER_SYS_WAIT -AC_CHECK_HEADERS(fcntl.h limits.h strings.h sys/ioctl.h sys/time.h unistd.h) -AC_CHECK_HEADERS(sys/mman.h) - -dnl Checks for typedefs, structures, and compiler characteristics. -AC_C_CONST -AC_C_INLINE -AC_TYPE_SIZE_T -AC_HEADER_TIME - -dnl Checks for library functions. -AC_CHECK_FUNCS([]) - -dnl Check for Mingw support -GR_PWIN32 - -PKG_CHECK_MODULES(GNURADIO_CORE, gnuradio-core >= 3) -dnl LIBS="$LIBS $GNURADIO_CORE_LIBS" - -dnl Define where to find boost includes -dnl defines BOOST_CFLAGS -GR_REQUIRE_BOOST_INCLUDES - -STD_DEFINES_AND_INCLUDES="$GNURADIO_CORE_CFLAGS $BOOST_CFLAGS" -AC_SUBST(STD_DEFINES_AND_INCLUDES) - - -AC_CONFIG_FILES([\ - Makefile \ - config/Makefile \ - src/Makefile \ - src/lib/Makefile \ - src/lib/decoder/Makefile \ - src/python/Makefile \ - src/lib/decoder/openbtsstuff/Makefile \ - gsm-receiver.pc \ - ]) -dnl # doc/Makefile \ -dnl # src/python/run_tests \ - -dnl run_tests is created from run_tests.in. Make it executable. -#AC_CONFIG_COMMANDS([run_tests], [chmod +x src/python/run_tests]) - -AC_OUTPUT diff --git a/gsm-receiver.pc.in b/gsm-receiver.pc.in deleted file mode 100644 index 0a18d4b..0000000 --- a/gsm-receiver.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: gsm-receiver -Description: The GSM receiver block which does FCCH burst search, sch decoding and normal burst demodulation -Requires: gnuradio-core -Version: @VERSION@ -Libs: -L${libdir} -lgsm-receiver -Cflags: -I${includedir} diff --git a/gsm-receiver/.gitignore b/gsm-receiver/.gitignore new file mode 100644 index 0000000..91f0ff0 --- /dev/null +++ b/gsm-receiver/.gitignore @@ -0,0 +1,25 @@ +configure +Makefile.in +config.log +config.h +config.sub +config.guess +ltmain.sh +Makefile +config.status +stamp-h1 +config.h.in +autom4te.cache +libtool +missing +aclocal.m4 +install-sh +depcomp +compile +build +*~ +autom4te.cache +debug +html +latex +xml diff --git a/gsm-receiver/AUTHORS b/gsm-receiver/AUTHORS new file mode 100644 index 0000000..944ad20 --- /dev/null +++ b/gsm-receiver/AUTHORS @@ -0,0 +1 @@ +Piotr Krysik \ No newline at end of file diff --git a/gsm-receiver/CHANGELOG b/gsm-receiver/CHANGELOG new file mode 100644 index 0000000..e69de29 diff --git a/gsm-receiver/COPYING b/gsm-receiver/COPYING new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/gsm-receiver/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/gsm-receiver/ChangeLog b/gsm-receiver/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/gsm-receiver/Doxyfile b/gsm-receiver/Doxyfile new file mode 100644 index 0000000..2c5110c --- /dev/null +++ b/gsm-receiver/Doxyfile @@ -0,0 +1,316 @@ +# Doxyfile 1.5.6-KDevelop + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = gsm_receiver +PROJECT_NUMBER = 0.0.1 +OUTPUT_DIRECTORY = +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = /home/piotr/ +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = YES +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_OUTPUT_VHDL = NO +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +IDL_PROPERTY_SUPPORT = YES +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +TYPEDEF_HIDES_STRUCT = NO +SYMBOL_CACHE_SIZE = 0 +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_GROUP_NAMES = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = NO +SHOW_FILES = YES +SHOW_NAMESPACES = YES +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = /home/piotr/MiejscePracy/gsm-receiver +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox \ + *.py \ + *.f90 \ + *.f \ + *.vhd \ + *.vhdl \ + *.C \ + *.CC \ + *.C++ \ + *.II \ + *.I++ \ + *.H \ + *.HH \ + *.H++ \ + *.CS \ + *.PHP \ + *.PHP3 \ + *.M \ + *.MM \ + *.PY \ + *.F90 \ + *.F \ + *.VHD \ + *.VHDL \ + *.C \ + *.H \ + *.tlh \ + *.diff \ + *.patch \ + *.moc \ + *.xpm \ + *.dox +RECURSIVE = yes +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +REFERENCES_LINK_SOURCE = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +GENERATE_DOCSET = NO +DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_BUNDLE_ID = org.doxygen.Project +HTML_DYNAMIC_SECTIONS = NO +CHM_FILE = +HHC_LOCATION = +QTHELP_FILE = +QTHELP_CONFIG = +DOXYGEN2QTHELP_LOC = +GENERATE_CHI = NO +CHM_INDEX_ENCODING = +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NONE +TREEVIEW_WIDTH = 250 +FORMULA_FONTSIZE = 10 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = YES +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = yes +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = gsm_receiver.tag +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +MSCGEN_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +DOT_FONTNAME = FreeSans +DOT_FONTPATH = +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 1000 +DOT_TRANSPARENT = YES +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/gsm-receiver/INSTALL b/gsm-receiver/INSTALL new file mode 100644 index 0000000..314b196 --- /dev/null +++ b/gsm-receiver/INSTALL @@ -0,0 +1,13 @@ +Under Ubuntu 9.04 install: + -add following lines to /etc/apt/sources.list + deb http://gnuradio.org/ubuntu stable main + deb-src http://gnuradio.org/ubuntu stable main + -type + $ sudo apt-get update + $ sudo apt-get install gnuradio libtool automake + +To build the GSM Receiver use: + $ ./bootstrap + $ cd debug + $ ../configure + $ make diff --git a/gsm-receiver/Makefile.am b/gsm-receiver/Makefile.am new file mode 100644 index 0000000..734941a --- /dev/null +++ b/gsm-receiver/Makefile.am @@ -0,0 +1,13 @@ +include $(top_srcdir)/Makefile.common + +SUBDIRS = src config +DIST_SUBDIRS = src config + +EXTRA_DIST = \ + configure \ + gsm-receiver.pc.in \ + config.h.in +# bootstrap + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = gsm-receiver.pc diff --git a/gsm-receiver/Makefile.common b/gsm-receiver/Makefile.common new file mode 100644 index 0000000..0b88813 --- /dev/null +++ b/gsm-receiver/Makefile.common @@ -0,0 +1,57 @@ +# -*- Makefile -*- +# +# Copyright 2004,2006 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. +# + +#!! remove this +TCH_DECODER_INCLUDEDIR = $(top_srcdir)/src/lib/decoder/openbtsstuff + +MAIN_INCLUDEDIR = $(top_srcdir)/src/lib +DECODER_INCLUDEDIR = $(top_srcdir)/src/lib/decoder +DECODER_LA = $(top_builddir)/src/lib/decoder/libdecoder.la + +STD_DEFINES_AND_INCLUDES = \ + -I$(DECODER_INCLUDEDIR) \ + -I$(MAIN_INCLUDEDIR) \ + -I$(GNURADIO_CORE_INCLUDEDIR) \ + -I$(TCH_DECODER_INCLUDEDIR) + +# includes +grincludedir = $(includedir)/gnuradio + +# swig includes +swigincludedir = $(grincludedir)/swig + +# Install this stuff in the appropriate subdirectory +# This usually ends up at: +# ${prefix}/lib/python${python_version}/site-packages/gnuradio + +grpythondir = $(pythondir)/gnuradio +grpyexecdir = $(pyexecdir)/gnuradio + +# swig flags +SWIGPYTHONFLAGS = -fvirtual -python -modern +SWIGGRFLAGS = -I$(GNURADIO_CORE_INCLUDEDIR)/swig -I$(GNURADIO_CORE_INCLUDEDIR) + +# Don't assume that make predefines $(RM), because BSD make does +# not. We define it now in configure.ac using AM_PATH_PROG, but now +# here have to add a -f to be like GNU make. +RM=$(RM_PROG) -f + diff --git a/gsm-receiver/NEWS b/gsm-receiver/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/gsm-receiver/README b/gsm-receiver/README new file mode 100644 index 0000000..96b560b --- /dev/null +++ b/gsm-receiver/README @@ -0,0 +1,5 @@ +Usage: + -capture cfile with usrp: + $ capture.sh + -run go.sh on this file: + $ go.sh diff --git a/gsm-receiver/bootstrap b/gsm-receiver/bootstrap new file mode 100755 index 0000000..7e0a2eb --- /dev/null +++ b/gsm-receiver/bootstrap @@ -0,0 +1,32 @@ +#!/bin/sh + +# Copyright 2001,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 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. + + +rm -fr config.cache autom4te*.cache + +aclocal -I config +autoconf +autoheader +libtoolize --automake +automake --add-missing +if test ! -d debug; then + mkdir debug +fi diff --git a/gsm-receiver/config/.gitignore b/gsm-receiver/config/.gitignore new file mode 100644 index 0000000..38066dd --- /dev/null +++ b/gsm-receiver/config/.gitignore @@ -0,0 +1,5 @@ +libtool.m4 +ltoptions.m4 +ltsugar.m4 +ltversion.m4 +lt~obsolete.m4 diff --git a/gsm-receiver/config/Makefile.am b/gsm-receiver/config/Makefile.am new file mode 100644 index 0000000..1c99d68 --- /dev/null +++ b/gsm-receiver/config/Makefile.am @@ -0,0 +1,70 @@ +# +# Copyright 2001 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 + +# Install m4 macros in this directory +m4datadir = $(datadir)/aclocal + +# List your m4 macros here +m4macros = \ + acx_pthread.m4 \ + bnv_have_qt.m4 \ + cppunit.m4 \ + gr_boost.m4 \ + gr_check_createfilemapping.m4 \ + gr_check_usrp.m4 \ + gr_check_mc4020.m4 \ + gr_check_shm_open.m4 \ + gr_doxygen.m4 \ + gr_gprof.m4 \ + gr_libgnuradio_core_extra_ldflags.m4 \ + gr_no_undefined.m4 \ + gr_omnithread.m4 \ + gr_pwin32.m4 \ + gr_python.m4 \ + gr_require_mc4020.m4 \ + gr_scripting.m4 \ + gr_set_md_cpu.m4 \ + gr_swig.m4 \ + gr_sysv_shm.m4 \ + gr_x86_64.m4 \ + lf_cc.m4 \ + lf_cxx.m4 \ + lf_warnings.m4 \ + lf_x11.m4 \ + mkstemp.m4 \ + onceonly.m4 \ + pkg.m4 \ + usrp_fusb_tech.m4 \ + usrp_libusb.m4 \ + usrp_sdcc.m4 + + +# Don't install m4 macros anymore +# m4data_DATA = $(m4macros) + +EXTRA_DIST = $(m4macros) \ + libtool.m4 \ + lt~obsolete.m4 \ + ltsugar.m4 \ + ltversion.m4 \ + ltoptions.m4 diff --git a/gsm-receiver/config/acx_pthread.m4 b/gsm-receiver/config/acx_pthread.m4 new file mode 100644 index 0000000..d318ab0 --- /dev/null +++ b/gsm-receiver/config/acx_pthread.m4 @@ -0,0 +1,190 @@ +dnl Available from the GNU Autoconf Macro Archive at: +dnl http://www.gnu.org/software/ac-archive/htmldoc/acx_pthread.html +dnl +AC_DEFUN([ACX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_SAVE +AC_LANG_C +acx_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) + AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) + AC_MSG_RESULT($acx_pthread_ok) + if test x"$acx_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all. + +acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# pthread: Linux, etcetera +# --thread-safe: KAI C++ + +case "${host_cpu}-${host_os}" in + *solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthread or + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags" + ;; +esac + +if test x"$acx_pthread_ok" = xno; then +for flag in $acx_pthread_flags; do + + case $flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $flag]) + PTHREAD_CFLAGS="$flag" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$flag]) + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + AC_TRY_LINK([#include ], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], + [acx_pthread_ok=yes]) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + AC_MSG_RESULT($acx_pthread_ok) + if test "x$acx_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$acx_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: threads are created detached by default + # and the JOINABLE attribute has a nonstandard name (UNDETACHED). + AC_MSG_CHECKING([for joinable pthread attribute]) + AC_TRY_LINK([#include ], + [int attr=PTHREAD_CREATE_JOINABLE;], + ok=PTHREAD_CREATE_JOINABLE, ok=unknown) + if test x"$ok" = xunknown; then + AC_TRY_LINK([#include ], + [int attr=PTHREAD_CREATE_UNDETACHED;], + ok=PTHREAD_CREATE_UNDETACHED, ok=unknown) + fi + if test x"$ok" != xPTHREAD_CREATE_JOINABLE; then + AC_DEFINE(PTHREAD_CREATE_JOINABLE, $ok, + [Define to the necessary symbol if this constant + uses a non-standard name on your system.]) + fi + AC_MSG_RESULT(${ok}) + if test x"$ok" = xunknown; then + AC_MSG_WARN([we do not know how to create joinable pthreads]) + fi + + AC_MSG_CHECKING([if more special flags are required for pthreads]) + flag=no + case "${host_cpu}-${host_os}" in + *-aix* | *-freebsd*) flag="-D_THREAD_SAFE";; + *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; + esac + AC_MSG_RESULT(${flag}) + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + # More AIX lossage: must compile with cc_r + AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC}) +else + PTHREAD_CC="$CC" +fi + +AC_SUBST(PTHREAD_LIBS) +AC_SUBST(PTHREAD_CFLAGS) +AC_SUBST(PTHREAD_CC) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$acx_pthread_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) + : +else + acx_pthread_ok=no + $2 +fi +AC_LANG_RESTORE +])dnl ACX_PTHREAD diff --git a/gsm-receiver/config/bnv_have_qt.m4 b/gsm-receiver/config/bnv_have_qt.m4 new file mode 100644 index 0000000..1469bfb --- /dev/null +++ b/gsm-receiver/config/bnv_have_qt.m4 @@ -0,0 +1,404 @@ +dnl Available from the GNU Autoconf Macro Archive at: +dnl http://www.gnu.org/software/ac-archive/htmldoc/bnv_have_qt.html +dnl +AC_DEFUN([BNV_HAVE_QT], +[ + dnl THANKS! This code includes bug fixes by: + dnl Tim McClarren. + + AC_REQUIRE([AC_PROG_CXX]) + AC_REQUIRE([AC_PATH_X]) + AC_REQUIRE([AC_PATH_XTRA]) + + AC_MSG_CHECKING(for Qt) + + AC_ARG_WITH([Qt-dir], + [ --with-Qt-dir=DIR DIR is equal to \$QTDIR if you have followed the + installation instructions of Trolltech. Header + files are in DIR/include, binary utilities are + in DIR/bin and the library is in DIR/lib]) + AC_ARG_WITH([Qt-include-dir], + [ --with-Qt-include-dir=DIR + Qt header files are in DIR]) + AC_ARG_WITH([Qt-bin-dir], + [ --with-Qt-bin-dir=DIR Qt utilities such as moc and uic are in DIR]) + AC_ARG_WITH([Qt-lib-dir], + [ --with-Qt-lib-dir=DIR The Qt library is in DIR]) + AC_ARG_WITH([Qt-lib], + [ --with-Qt-lib=LIB Use -lLIB to link with the Qt library]) + if test x"$with_Qt_dir" = x"no" || + test x"$with_Qt_include-dir" = x"no" || + test x"$with_Qt_bin_dir" = x"no" || + test x"$with_Qt_lib_dir" = x"no" || + test x"$with_Qt_lib" = x"no"; then + # user disabled Qt. Leave cache alone. + have_qt="User disabled Qt." + else + # "yes" is a bogus option + if test x"$with_Qt_dir" = xyes; then + with_Qt_dir= + fi + if test x"$with_Qt_include_dir" = xyes; then + with_Qt_include_dir= + fi + if test x"$with_Qt_bin_dir" = xyes; then + with_Qt_bin_dir= + fi + if test x"$with_Qt_lib_dir" = xyes; then + with_Qt_lib_dir= + fi + if test x"$with_Qt_lib" = xyes; then + with_Qt_lib= + fi + # No Qt unless we discover otherwise + have_qt=no + # Check whether we are requested to link with a specific version + if test x"$with_Qt_lib" != x; then + bnv_qt_lib="$with_Qt_lib" + fi + # Check whether we were supplied with an answer already + if test x"$with_Qt_dir" != x; then + have_qt=yes + bnv_qt_dir="$with_Qt_dir" + bnv_qt_include_dir="$with_Qt_dir/include" + bnv_qt_bin_dir="$with_Qt_dir/bin" + bnv_qt_lib_dir="$with_Qt_dir/lib" + # Only search for the lib if the user did not define one already + if test x"$bnv_qt_lib" = x; then + bnv_qt_lib="`ls $bnv_qt_lib_dir/libqt* | sed -n 1p | + sed s@$bnv_qt_lib_dir/lib@@ | [sed s@[.].*@@]`" + fi + bnv_qt_LIBS="-L$bnv_qt_lib_dir -l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" + else + # Use cached value or do search, starting with suggestions from + # the command line + AC_CACHE_VAL(bnv_cv_have_qt, + [ + # We are not given a solution and there is no cached value. + bnv_qt_dir=NO + bnv_qt_include_dir=NO + bnv_qt_lib_dir=NO + if test x"$bnv_qt_lib" = x; then + bnv_qt_lib=NO + fi + BNV_PATH_QT_DIRECT + if test "$bnv_qt_dir" = NO || + test "$bnv_qt_include_dir" = NO || + test "$bnv_qt_lib_dir" = NO || + test "$bnv_qt_lib" = NO; then + # Problem with finding complete Qt. Cache the known absence of Qt. + bnv_cv_have_qt="have_qt=no" + else + # Record where we found Qt for the cache. + bnv_cv_have_qt="have_qt=yes \ + bnv_qt_dir=$bnv_qt_dir \ + bnv_qt_include_dir=$bnv_qt_include_dir \ + bnv_qt_bin_dir=$bnv_qt_bin_dir \ + bnv_qt_LIBS=\"$bnv_qt_LIBS\"" + fi + ])dnl + eval "$bnv_cv_have_qt" + fi # all $bnv_qt_* are set + fi # $have_qt reflects the system status + if test x"$have_qt" = xyes; then + QT_CXXFLAGS="-I$bnv_qt_include_dir" + QT_DIR="$bnv_qt_dir" + QT_LIBS="$bnv_qt_LIBS" + # If bnv_qt_dir is defined, utilities are expected to be in the + # bin subdirectory + if test x"$bnv_qt_dir" != x; then + if test -x "$bnv_qt_dir/bin/uic"; then + QT_UIC="$bnv_qt_dir/bin/uic" + else + # Old versions of Qt don't have uic + QT_UIC= + fi + QT_MOC="$bnv_qt_dir/bin/moc" + else + # Or maybe we are told where to look for the utilities + if test x"$bnv_qt_bin_dir" != x; then + if test -x "$bnv_qt_bin_dir/uic"; then + QT_UIC="$bnv_qt_bin_dir/uic" + else + # Old versions of Qt don't have uic + QT_UIC= + fi + QT_MOC="$bnv_qt_bin_dir/moc" + else + # Last possibility is that they are in $PATH + QT_UIC="`which uic`" + QT_MOC="`which moc`" + fi + fi + # All variables are defined, report the result + AC_MSG_RESULT([$have_qt: + QT_CXXFLAGS=$QT_CXXFLAGS + QT_DIR=$QT_DIR + QT_LIBS=$QT_LIBS + QT_UIC=$QT_UIC + QT_MOC=$QT_MOC]) + else + # Qt was not found + QT_CXXFLAGS= + QT_DIR= + QT_LIBS= + QT_UIC= + QT_MOC= + AC_MSG_RESULT($have_qt) + fi + AC_SUBST(QT_CXXFLAGS) + AC_SUBST(QT_DIR) + AC_SUBST(QT_LIBS) + AC_SUBST(QT_UIC) + AC_SUBST(QT_MOC) + + #### Being paranoid: + if test x"$have_qt" = xyes; then + AC_MSG_CHECKING(correct functioning of Qt installation) + AC_CACHE_VAL(bnv_cv_qt_test_result, + [ + cat > bnv_qt_test.h << EOF +#include +class Test : public QObject +{ +Q_OBJECT +public: + Test() {} + ~Test() {} +public slots: + void receive() {} +signals: + void send(); +}; +EOF + + cat > bnv_qt_main.$ac_ext << EOF +#include "bnv_qt_test.h" +#include +int main( int argc, char **argv ) +{ + QApplication app( argc, argv ); + Test t; + QObject::connect( &t, SIGNAL(send()), &t, SLOT(receive()) ); +} +EOF + + bnv_cv_qt_test_result="failure" + bnv_try_1="$QT_MOC bnv_qt_test.h -o moc_bnv_qt_test.$ac_ext >/dev/null 2>bnv_qt_test_1.out" + AC_TRY_EVAL(bnv_try_1) + bnv_err_1=`grep -v '^ *+' bnv_qt_test_1.out | grep -v "^bnv_qt_test.h\$"` + if test x"$bnv_err_1" != x; then + echo "$bnv_err_1" >&AC_FD_CC + echo "configure: could not run $QT_MOC on:" >&AC_FD_CC + cat bnv_qt_test.h >&AC_FD_CC + else + bnv_try_2="$CXX $QT_CXXFLAGS -c $CXXFLAGS -o moc_bnv_qt_test.o moc_bnv_qt_test.$ac_ext >/dev/null 2>bnv_qt_test_2.out" + AC_TRY_EVAL(bnv_try_2) + bnv_err_2=`grep -v '^ *+' bnv_qt_test_2.out | grep -v "^bnv_qt_test.{$ac_ext}\$"` + if test x"$bnv_err_2" != x; then + echo "$bnv_err_2" >&AC_FD_CC + echo "configure: could not compile:" >&AC_FD_CC + cat bnv_qt_test.$ac_ext >&AC_FD_CC + else + bnv_try_3="$CXX $QT_CXXFLAGS -c $CXXFLAGS -o bnv_qt_main.o bnv_qt_main.$ac_ext >/dev/null 2>bnv_qt_test_3.out" + AC_TRY_EVAL(bnv_try_3) + bnv_err_3=`grep -v '^ *+' bnv_qt_test_3.out | grep -v "^bnv_qt_main.{$ac_ext}\$"` + if test x"$bnv_err_3" != x; then + echo "$bnv_err_3" >&AC_FD_CC + echo "configure: could not compile:" >&AC_FD_CC + cat bnv_qt_main.$ac_ext >&AC_FD_CC + else + bnv_try_4="$CXX $QT_LIBS $LIBS -o bnv_qt_main bnv_qt_main.o moc_bnv_qt_test.o >/dev/null 2>bnv_qt_test_4.out" + AC_TRY_EVAL(bnv_try_4) + bnv_err_4=`grep -v '^ *+' bnv_qt_test_4.out` + if test x"$bnv_err_4" != x; then + echo "$bnv_err_4" >&AC_FD_CC + else + bnv_cv_qt_test_result="success" + fi + fi + fi + fi + ])dnl AC_CACHE_VAL bnv_cv_qt_test_result + AC_MSG_RESULT([$bnv_cv_qt_test_result]); + if test x"$bnv_cv_qt_test_result" = "xfailure"; then + # working Qt was not found + QT_CXXFLAGS= + QT_DIR= + QT_LIBS= + QT_UIC= + QT_MOC= + have_qt=no + AC_MSG_WARN([Failed to find matching components of a complete + Qt installation. Try using more options, + see ./configure --help.]) + fi + + rm -f bnv_qt_test.h moc_bnv_qt_test.$ac_ext moc_bnv_qt_test.o \ + bnv_qt_main.$ac_ext bnv_qt_main.o bnv_qt_main \ + bnv_qt_test_1.out bnv_qt_test_2.out bnv_qt_test_3.out bnv_qt_test_4.out + fi +]) + +dnl Internal subroutine of BNV_HAVE_QT +dnl Set bnv_qt_dir bnv_qt_include_dir bnv_qt_bin_dir bnv_qt_lib_dir bnv_qt_lib +dnl Copyright 2001 Bastiaan N. Veelo +AC_DEFUN([BNV_PATH_QT_DIRECT], +[ + ## Binary utilities ## + if test x"$with_Qt_bin_dir" != x; then + bnv_qt_bin_dir=$with_Qt_bin_dir + fi + ## Look for header files ## + if test x"$with_Qt_include_dir" != x; then + bnv_qt_include_dir="$with_Qt_include_dir" + else + # The following header file is expected to define QT_VERSION. + qt_direct_test_header=qglobal.h + # Look for the header file in a standard set of common directories. + bnv_include_path_list=" + /usr/include + `ls -dr /usr/include/qt* 2>/dev/null` + `ls -dr /usr/lib/qt*/include 2>/dev/null` + `ls -dr /usr/local/qt*/include 2>/dev/null` + `ls -dr /opt/qt*/include 2>/dev/null` + " + for bnv_dir in $bnv_include_path_list; do + if test -r "$bnv_dir/$qt_direct_test_header"; then + bnv_dirs="$bnv_dirs $bnv_dir" + fi + done + # Now look for the newest in this list + bnv_prev_ver=0 + for bnv_dir in $bnv_dirs; do + bnv_this_ver=`egrep -w '#define QT_VERSION' $bnv_dir/$qt_direct_test_header | sed s/'#define QT_VERSION'//` + if expr $bnv_this_ver '>' $bnv_prev_ver > /dev/null; then + bnv_qt_include_dir=$bnv_dir + bnv_prev_ver=$bnv_this_ver + fi + done + fi dnl Found header files. + + # Are these headers located in a traditional Trolltech installation? + # That would be $bnv_qt_include_dir stripped from its last element: + bnv_possible_qt_dir=`dirname $bnv_qt_include_dir` + if test -x $bnv_possible_qt_dir/bin/moc && + ls $bnv_possible_qt_dir/lib/libqt* > /dev/null; then + # Then the rest is a piece of cake + bnv_qt_dir=$bnv_possible_qt_dir + bnv_qt_bin_dir="$bnv_qt_dir/bin" + bnv_qt_lib_dir="$bnv_qt_dir/lib" + # Only look for lib if the user did not supply it already + if test x"$bnv_qt_lib" = xNO; then + bnv_qt_lib="`ls $bnv_qt_lib_dir/libqt* | sed -n 1p | + sed s@$bnv_qt_lib_dir/lib@@ | [sed s@[.].*@@]`" + fi + bnv_qt_LIBS="-L$bnv_qt_lib_dir -l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" + else + # There is no valid definition for $QTDIR as Trolltech likes to see it + bnv_qt_dir= + ## Look for Qt library ## + if test x"$with_Qt_lib_dir" != x; then + bnv_qt_lib_dir="$with_Qt_lib_dir" + # Only look for lib if the user did not supply it already + if test x"$bnv_qt_lib" = xNO; then + bnv_qt_lib="`ls $bnv_qt_lib_dir/libqt* | sed -n 1p | + sed s@$bnv_qt_lib_dir/lib@@ | [sed s@[.].*@@]`" + fi + bnv_qt_LIBS="-L$bnv_qt_lib_dir -l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" + else + # Normally, when there is no traditional Trolltech installation, + # the library is installed in a place where the linker finds it + # automatically. + # If the user did not define the library name, try with qt + if test x"$bnv_qt_lib" = xNO; then + bnv_qt_lib=qt + fi + qt_direct_test_header=qapplication.h + qt_direct_test_main=" + int argc; + char ** argv; + QApplication app(argc,argv); + " + # See if we find the library without any special options. + # Don't add top $LIBS permanently yet + bnv_save_LIBS="$LIBS" + LIBS="-l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" + bnv_qt_LIBS="$LIBS" + bnv_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="-I$bnv_qt_include_dir" + AC_TRY_LINK([#include <$qt_direct_test_header>], + $qt_direct_test_main, + [ + # Success. + # We can link with no special library directory. + bnv_qt_lib_dir= + ], [ + # That did not work. Try the multi-threaded version + echo "Non-critical error, please neglect the above." >&AC_FD_CC + bnv_qt_lib=qt-mt + LIBS="-l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" + AC_TRY_LINK([#include <$qt_direct_test_header>], + $qt_direct_test_main, + [ + # Success. + # We can link with no special library directory. + bnv_qt_lib_dir= + ], [ + # That did not work. Try the OpenGL version + echo "Non-critical error, please neglect the above." >&AC_FD_CC + bnv_qt_lib=qt-gl + LIBS="-l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" + AC_TRY_LINK([#include <$qt_direct_test_header>], + $qt_direct_test_main, + [ + # Succes. + # We can link with no special library directory. + bnv_qt_lib_dir= + ], [ + # That did not work. Maybe a library version I don't know about? + echo "Non-critical error, please neglect the above." >&AC_FD_CC + # Look for some Qt lib in a standard set of common directories. + bnv_dir_list=" + `echo $bnv_qt_includes | sed ss/includess` + /lib + /usr/lib + /usr/local/lib + /opt/lib + `ls -dr /usr/lib/qt* 2>/dev/null` + `ls -dr /usr/local/qt* 2>/dev/null` + `ls -dr /opt/qt* 2>/dev/null` + " + for bnv_dir in $bnv_dir_list; do + if ls $bnv_dir/libqt*; then + # Gamble that it's the first one... + bnv_qt_lib="`ls $bnv_dir/libqt* | sed -n 1p | + sed s@$bnv_dir/lib@@ | sed s/[.].*//`" + bnv_qt_lib_dir="$bnv_dir" + break + fi + done + # Try with that one + LIBS="-l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" + AC_TRY_LINK([#include <$qt_direct_test_header>], + $qt_direct_test_main, + [ + # Succes. + # We can link with no special library directory. + bnv_qt_lib_dir= + ], [ + # Leave bnv_qt_lib_dir defined + ]) + ]) + ]) + ]) + if test x"$bnv_qt_lib_dir" != x; then + bnv_qt_LIBS="-l$bnv_qt_lib_dir $LIBS" + else + bnv_qt_LIBS="$LIBS" + fi + LIBS="$bnv_save_LIBS" + CXXFLAGS="$bnv_save_CXXFLAGS" + fi dnl $with_Qt_lib_dir was not given + fi dnl Done setting up for non-traditional Trolltech installation +]) diff --git a/gsm-receiver/config/cppunit.m4 b/gsm-receiver/config/cppunit.m4 new file mode 100644 index 0000000..0991d51 --- /dev/null +++ b/gsm-receiver/config/cppunit.m4 @@ -0,0 +1,80 @@ +dnl +dnl AM_PATH_CPPUNIT(MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +dnl +AC_DEFUN([AM_PATH_CPPUNIT], +[ + +AC_ARG_WITH(cppunit-prefix,[ --with-cppunit-prefix=PFX Prefix where CppUnit is installed (optional)], + cppunit_config_prefix="$withval", cppunit_config_prefix="") +AC_ARG_WITH(cppunit-exec-prefix,[ --with-cppunit-exec-prefix=PFX Exec prefix where CppUnit is installed (optional)], + cppunit_config_exec_prefix="$withval", cppunit_config_exec_prefix="") + + if test x$cppunit_config_exec_prefix != x ; then + cppunit_config_args="$cppunit_config_args --exec-prefix=$cppunit_config_exec_prefix" + if test x${CPPUNIT_CONFIG+set} != xset ; then + CPPUNIT_CONFIG=$cppunit_config_exec_prefix/bin/cppunit-config + fi + fi + if test x$cppunit_config_prefix != x ; then + cppunit_config_args="$cppunit_config_args --prefix=$cppunit_config_prefix" + if test x${CPPUNIT_CONFIG+set} != xset ; then + CPPUNIT_CONFIG=$cppunit_config_prefix/bin/cppunit-config + fi + fi + + AC_PATH_PROG(CPPUNIT_CONFIG, cppunit-config, no) + cppunit_version_min=$1 + + AC_MSG_CHECKING(for Cppunit - version >= $cppunit_version_min) + no_cppunit="" + if test "$CPPUNIT_CONFIG" = "no" ; then + no_cppunit=yes + else + CPPUNIT_CFLAGS=`$CPPUNIT_CONFIG --cflags` + CPPUNIT_LIBS=`$CPPUNIT_CONFIG --libs` + cppunit_version=`$CPPUNIT_CONFIG --version` + + cppunit_major_version=`echo $cppunit_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + cppunit_minor_version=`echo $cppunit_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + cppunit_micro_version=`echo $cppunit_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + + cppunit_major_min=`echo $cppunit_version_min | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + cppunit_minor_min=`echo $cppunit_version_min | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + cppunit_micro_min=`echo $cppunit_version_min | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + + cppunit_version_proper=`expr \ + $cppunit_major_version \> $cppunit_major_min \| \ + $cppunit_major_version \= $cppunit_major_min \& \ + $cppunit_minor_version \> $cppunit_minor_min \| \ + $cppunit_major_version \= $cppunit_major_min \& \ + $cppunit_minor_version \= $cppunit_minor_min \& \ + $cppunit_micro_version \>= $cppunit_micro_min ` + + if test "$cppunit_version_proper" = "1" ; then + AC_MSG_RESULT([$cppunit_major_version.$cppunit_minor_version.$cppunit_micro_version]) + else + AC_MSG_RESULT(no) + no_cppunit=yes + fi + fi + + if test "x$no_cppunit" = x ; then + ifelse([$2], , :, [$2]) + else + CPPUNIT_CFLAGS="" + CPPUNIT_LIBS="" + ifelse([$3], , :, [$3]) + fi + + AC_SUBST(CPPUNIT_CFLAGS) + AC_SUBST(CPPUNIT_LIBS) +]) + + + diff --git a/gsm-receiver/config/gr_boost.m4 b/gsm-receiver/config/gr_boost.m4 new file mode 100644 index 0000000..0664d36 --- /dev/null +++ b/gsm-receiver/config/gr_boost.m4 @@ -0,0 +1,111 @@ +dnl +dnl Copyright 2004,2005 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +dnl This tries to do the "right thing" to locate the boost include files. +dnl If the user explicitly specified --with-boost-include-dir= +dnl we believe them and use it. Otherwise, +dnl +dnl We look for boost/shared_ptr.hpp in the "normal places". That is, +dnl wherever AC_CHECK_HEADER looks. If the boost includes are in /usr/local/include +dnl this step will find them. +dnl +dnl Otherwise, we check to see if the boost stuff was installed in a version-specific +dnl directory under /usr/local/include. These look like: /usr/local/include/boost-1_33_1 +dnl If there's more than one version installed, we select the +dnl lexicographically greatest one. +dnl +dnl If none of these work, we bail. + +AC_DEFUN([GR_REQUIRE_BOOST_INCLUDES], +[ + AC_LANG_PUSH(C++) + gr_boost_include_dir= + AC_ARG_WITH([boost-include-dir], + AC_HELP_STRING([--with-boost-include-dir=], + [path to boost c++ include files]), + [ + # "yes" and "no" are bogus answers + if test x"$with_boost_include_dir" = xyes || + test x"$with_boost_include_dir" = xno; then + gr_boost_include_dir= + else + gr_boost_include_dir=$with_boost_include_dir + fi + ]) + echo "gr_boost_include_dir = $gr_boost_include_dir" + if test x$gr_boost_include_dir != x; then + # + # If the user specified a directory, then we use it + # + OLD_CPPFLAGS=$CPPFLAGS + CPPFLAGS="$CPPFLAGS -I$gr_boost_include_dir" + AC_CHECK_HEADER([boost/shared_ptr.hpp], + [BOOST_CFLAGS="-I$gr_boost_include_dir"], + [AC_MSG_ERROR( + [Failed to locate boost/shared_ptr.hpp. +Try using --with-boost-include-dir=, +E.g., --with-boost-include-dir=/usr/local/include/boost-1_33_1])]) + CPPFLAGS=$OLD_CPPFLAGS + else + # + # Otherwise we check in the default places + # + AC_CHECK_HEADER([boost/shared_ptr.hpp], + [BOOST_CFLAGS=""], + [ # Nope, look for latest version if any in $prefix/include/boost-* + + # Wipe out cached value. KLUDGE: AC should have API for this + unset AS_TR_SH([ac_cv_header_boost/shared_ptr.hpp]) + + boost_last_match(){ + #echo "boost_last_match: [$]*" + pattern="[$]1" + shift + if test "[$]pattern" = "[$]1" + then + LM='' + else + shift `expr [$]# - 1` + LM=[$]1 + fi + #echo "LM(1)='[$]LM'" + } + + pattern="/usr/local/include/boost-*" + boost_last_match "$pattern" $pattern + #echo "LM(2)='$LM'" + + OLD_CPPFLAGS=$CPP_FLAGS + CPPFLAGS="$CPPFLAGS -I$LM" + AC_CHECK_HEADER([boost/shared_ptr.hpp], + [BOOST_CFLAGS="-I$LM"], + [AC_MSG_ERROR( + [Failed to locate boost/shared_ptr.hpp. +Try using --with-boost-include-dir=, +E.g., --with-boost-include-dir=/usr/local/include/boost-1_33_1])]) + CPPFLAGS=$OLD_CPPFLAGS + ]) + + fi + unset boost_last_match LM + AC_LANG_POP + AC_SUBST(BOOST_CFLAGS) +]) diff --git a/gsm-receiver/config/gr_check_createfilemapping.m4 b/gsm-receiver/config/gr_check_createfilemapping.m4 new file mode 100644 index 0000000..5f9b4a4 --- /dev/null +++ b/gsm-receiver/config/gr_check_createfilemapping.m4 @@ -0,0 +1,52 @@ +dnl +dnl Copyright 2005 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. + +dnl AC_DEFUN([GR_CHECK_CREATEFILEMAPPING], +dnl [ +dnl AC_CHECK_FUNCS([CreateFileMapping]) +dnl ]) + +AC_DEFUN([GR_CHECK_CREATEFILEMAPPING],[ + AC_MSG_CHECKING([for CreateFileMapping function]) + AC_COMPILE_IFELSE([ +#include +int main (int argc, char **argv) +{ + HANDLE handle; + int size; + char seg_name[[1024]]; + handle = CreateFileMapping( + INVALID_HANDLE_VALUE, // use paging file + NULL, // default security + PAGE_READWRITE, // read/write access + 0, // max. object size + size, // buffer size + seg_name); // name of mapping object + return 0; +} +],[HAVE_CREATEFILEMAPPING=yes + AC_DEFINE(HAVE_CREATEFILEMAPPING,[1],[Define if you have the CreateFilemapping function(win32).])], + [HAVE_CREATEFILEMAPPING=no]) + + AC_MSG_RESULT($HAVE_CREATEFILEMAPPING) + AM_CONDITIONAL(HAVE_CREATEFILEMAPPING, test x$HAVE_CREATEFILEMAPPING = xyes) +]) + + diff --git a/gsm-receiver/config/gr_check_mc4020.m4 b/gsm-receiver/config/gr_check_mc4020.m4 new file mode 100644 index 0000000..28987c2 --- /dev/null +++ b/gsm-receiver/config/gr_check_mc4020.m4 @@ -0,0 +1,37 @@ +dnl +dnl Copyright 2003 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +AC_DEFUN([GR_CHECK_MC4020],[ + AC_MSG_CHECKING([for mc4020 A/D driver include file]) + AC_COMPILE_IFELSE([ +#include +int main (int argc, char **argv) +{ + return 0; +} +],[HAVE_MC4020=yes + AC_DEFINE(HAVE_MC4020,[1],[Define if you have a Measurement Computing PCI-DAS4020/12 A/D])], + [HAVE_MC4020=no]) + + AC_MSG_RESULT($HAVE_MC4020) + AM_CONDITIONAL(HAVE_MC4020, test x$HAVE_MC4020 = xyes) +]) + diff --git a/gsm-receiver/config/gr_check_shm_open.m4 b/gsm-receiver/config/gr_check_shm_open.m4 new file mode 100644 index 0000000..83d260b --- /dev/null +++ b/gsm-receiver/config/gr_check_shm_open.m4 @@ -0,0 +1,29 @@ +dnl +dnl Copyright 2003 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. + +AC_DEFUN([GR_CHECK_SHM_OPEN], +[ + SHM_OPEN_LIBS="" + save_LIBS="$LIBS" + AC_SEARCH_LIBS([shm_open], [rt], [SHM_OPEN_LIBS="$LIBS"]) + AC_CHECK_FUNCS([shm_open]) + LIBS="$save_LIBS" + AC_SUBST(SHM_OPEN_LIBS) +]) diff --git a/gsm-receiver/config/gr_check_usrp.m4 b/gsm-receiver/config/gr_check_usrp.m4 new file mode 100644 index 0000000..12a5d1c --- /dev/null +++ b/gsm-receiver/config/gr_check_usrp.m4 @@ -0,0 +1,32 @@ +dnl +dnl Copyright 2003 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +dnl Check for Universal Software Radio Peripheral + +AC_DEFUN([GR_CHECK_USRP],[ + PKG_CHECK_MODULES(USRP, usrp >= 0.2, + [HAVE_USRP=yes + AC_DEFINE(HAVE_USRP,[1],[Define if you have a USRP])], + [HAVE_USRP=no]) + + AM_CONDITIONAL(HAVE_USRP, test x$HAVE_USRP = xyes) +]) + diff --git a/gsm-receiver/config/gr_doxygen.m4 b/gsm-receiver/config/gr_doxygen.m4 new file mode 100644 index 0000000..4670c29 --- /dev/null +++ b/gsm-receiver/config/gr_doxygen.m4 @@ -0,0 +1,59 @@ +dnl +dnl Copyright 2003,2005 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +AC_DEFUN([GR_CHECK_DOXYGEN],[ + AC_ARG_ENABLE(doxygen, [ --enable-doxygen enable documentation generation with doxygen (no)]) + AC_ARG_ENABLE(dot, [ --enable-dot use 'dot' to generate graphs in doxygen (auto)]) + AC_ARG_ENABLE(html-docs, [ --enable-html-docs enable HTML generation with doxygen (yes)], [], [ enable_html_docs=yes]) + AC_ARG_ENABLE(latex-docs, [ --enable-latex-docs enable LaTeX doc generation with doxygen (no)], [], [ enable_latex_docs=no]) + + if test "x$enable_doxygen" = xyes; then + AC_PATH_PROG(DOXYGEN, doxygen, , $PATH) + if test x$DOXYGEN = x; then + if test "x$enable_doxygen" = xyes; then + AC_MSG_ERROR([could not find doxygen]) + fi + enable_doc=no + generate_docs= + else + enable_doc=yes + generate_docs=docs + AC_PATH_PROG(DOT, dot, , $PATH) + fi + else + enable_doc=no + fi + + AM_CONDITIONAL(DOC, test x$enable_doc = xyes) + + if test x$DOT = x; then + if test "x$enable_dot" = xyes; then + AC_MSG_ERROR([could not find dot]) + fi + enable_dot=no + else + enable_dot=yes + fi + AC_SUBST(enable_dot) + AC_SUBST(enable_html_docs) + AC_SUBST(enable_latex_docs) + AC_SUBST(generate_docs) +]) diff --git a/gsm-receiver/config/gr_gprof.m4 b/gsm-receiver/config/gr_gprof.m4 new file mode 100644 index 0000000..20bacf3 --- /dev/null +++ b/gsm-receiver/config/gr_gprof.m4 @@ -0,0 +1,72 @@ +dnl +dnl Copyright 2002 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +dnl FIXME probably need to add linker flag too... + +AC_DEFUN([GR_SET_GPROF],[ + dnl Check for --with-gprof + AC_MSG_CHECKING([whether user wants gprof]) + AC_ARG_WITH(gprof, + [ --with-gprof Turn on gprof profiling], + [], [ with_gprof=no ]) + AC_MSG_RESULT($with_gprof) + + dnl gprof profiling flags for the two main compilers + cc_profiling_flags="-pg" + cxx_profiling_flags="-pg" + ld_profiling_flags="-pg" + if test $with_gprof = yes + then + if test -n "${CC}" + then + LF_CHECK_CC_FLAG($cc_profiling_flags) + fi + if test -n "${CXX}" + then + LF_CHECK_CXX_FLAG($cxx_profiling_flags) + fi + fi +]) + +AC_DEFUN([GR_SET_PROF],[ + dnl Check for --with-prof + AC_MSG_CHECKING([whether user wants prof]) + AC_ARG_WITH(prof, + [ --with-prof Turn on prof profiling], + [], [ with_prof=no ]) + AC_MSG_RESULT($with_prof) + + dnl prof profiling flags for the two main compilers + cc_profiling_flags="-p" + cxx_profiling_flags="-p" + ld_profiling_flags="-p" + if test $with_prof = yes + then + if test -n "${CC}" + then + LF_CHECK_CC_FLAG($cc_profiling_flags) + fi + if test -n "${CXX}" + then + LF_CHECK_CXX_FLAG($cxx_profiling_flags) + fi + fi +]) diff --git a/gsm-receiver/config/gr_libgnuradio_core_extra_ldflags.m4 b/gsm-receiver/config/gr_libgnuradio_core_extra_ldflags.m4 new file mode 100644 index 0000000..43f872c --- /dev/null +++ b/gsm-receiver/config/gr_libgnuradio_core_extra_ldflags.m4 @@ -0,0 +1,40 @@ +# Check for (MinGW)win32 extra ld options. -*- Autoconf -*- + +# Copyright 2003,2004,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 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. + +dnl +AC_DEFUN([GR_LIBGNURADIO_CORE_EXTRA_LDFLAGS], [ +AC_REQUIRE([AC_PROG_LD]) +# on Mingw32 extra LDFLAGS are required to ease global variable linking +LIBGNURADIO_CORE_EXTRA_LDFLAGS="" + +AC_MSG_CHECKING([whether $LD accepts --enable-runtime-pseudo-reloc]) +if ${LD} --enable-runtime-pseudo-reloc --version >/dev/null 2>&1 +then + # libtool requires the quotes + LIBGNURADIO_CORE_EXTRA_LDFLAGS="\"-Wl,--enable-runtime-pseudo-reloc\"" + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +AC_SUBST(LIBGNURADIO_CORE_EXTRA_LDFLAGS) + +]) diff --git a/gsm-receiver/config/gr_no_undefined.m4 b/gsm-receiver/config/gr_no_undefined.m4 new file mode 100644 index 0000000..c8d745d --- /dev/null +++ b/gsm-receiver/config/gr_no_undefined.m4 @@ -0,0 +1,44 @@ +dnl +dnl Copyright 2005 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +# GR_NO_UNDEFINED() +# +# Detemine whether we need to use the -no-undefined linker flag +# when building shared libraries. +# Sets NO_UNDEFINED to "" or "-no-undefined" +# +# As far as I can tell, we need -no-undefined only when building +# windows DLLs. This occurs when using MinGW and Cygwin. +# +# For now, we stub this out. + +AC_DEFUN([GR_NO_UNDEFINED],[ + AC_REQUIRE([AC_CANONICAL_HOST]) + no_undefined="" + case "${host_os}" in + *mingw* | *cygwin*) + + # on MinGW/Cygwin extra LDFLAGS are required + no_undefined="-no-undefined" + ;; + esac + AC_SUBST(NO_UNDEFINED,[$no_undefined]) +]) diff --git a/gsm-receiver/config/gr_omnithread.m4 b/gsm-receiver/config/gr_omnithread.m4 new file mode 100644 index 0000000..b5e4090 --- /dev/null +++ b/gsm-receiver/config/gr_omnithread.m4 @@ -0,0 +1,51 @@ +# Check for Omnithread (pthread/NT) thread support. -*- Autoconf -*- + +# Copyright 2003 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, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Boston, MA +# 02110-1301, USA. + +AC_DEFUN([GR_OMNITHREAD], +[ + # Check first for POSIX + ACX_PTHREAD( + [ ot_posix="yes" + AC_DEFINE(OMNITHREAD_POSIX,[1],[Define to 1 to enable pthread]) + ],[ + # If no POSIX support found, then check for NT threads + AC_MSG_CHECKING([for NT threads]) + + AC_LINK_IFELSE([ + #include + #include + int main() { InitializeCriticalSection(NULL); return 0; } + ], + [ + ot_nt="yes" + AC_DEFINE(OMNITHREAD_NT,[1],[Define to 1 to enable NT thread]) + ], + [AC_MSG_FAILURE([GNU Radio requires POSIX threads. pthreads not found.])] + ) + AC_MSG_RESULT(yes) + ]) + AM_CONDITIONAL(OMNITHREAD_POSIX, test "x$ot_posix" = xyes) + AM_CONDITIONAL(OMNITHREAD_NT, test "x$ot_nt" = xyes) + + save_LIBS="$LIBS" + AC_SEARCH_LIBS([clock_gettime], [rt], [PTHREAD_LIBS="$PTHREAD_LIBS $LIBS"]) + AC_CHECK_FUNCS([clock_gettime gettimeofday nanosleep]) + LIBS="$save_LIBS" +]) + diff --git a/gsm-receiver/config/gr_pwin32.m4 b/gsm-receiver/config/gr_pwin32.m4 new file mode 100644 index 0000000..7b99cba --- /dev/null +++ b/gsm-receiver/config/gr_pwin32.m4 @@ -0,0 +1,146 @@ +# Check for (mingw)win32 POSIX replacements. -*- Autoconf -*- + +# Copyright 2003,2004,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 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. + + +AC_DEFUN([GR_PWIN32], +[ +AC_REQUIRE([AC_HEADER_TIME]) +AC_CHECK_HEADERS([sys/types.h fcntl.h io.h]) +AC_CHECK_HEADERS([windows.h]) +AC_CHECK_HEADERS([winioctl.h winbase.h], [], [], [ + #if HAVE_WINDOWS_H + #include + #endif +]) + +AC_CHECK_FUNCS([getopt usleep gettimeofday nanosleep rand srand random srandom sleep sigaction]) +AC_CHECK_TYPES([struct timezone, struct timespec, ssize_t],[],[],[ + #if HAVE_SYS_TYPES_H + # include + #endif + #if TIME_WITH_SYS_TIME + # include + # include + #else + # if HAVE_SYS_TIME_H + # include + # else + # include + # endif + #endif +]) + +dnl Checks for replacements +AC_REPLACE_FUNCS([getopt usleep gettimeofday]) + + +AC_MSG_CHECKING(for Sleep) +AC_TRY_LINK([ #include + #include + ], [ Sleep(0); ], + [AC_DEFINE(HAVE_SSLEEP,1,[Define to 1 if you have win32 Sleep]) + AC_MSG_RESULT(yes)], + AC_MSG_RESULT(no) + ) + +dnl Under Win32, mkdir prototype in io.h has only one arg +AC_MSG_CHECKING(whether mkdir accepts only one arg) +AC_TRY_COMPILE([#include + #include + #include ], [ + mkdir("") + ], [ AC_MSG_RESULT(yes) + AC_DEFINE(MKDIR_TAKES_ONE_ARG,[],[Define if mkdir accepts only one arg]) ], + [ AC_MSG_RESULT(no) + ]) + +AH_BOTTOM( +[ +/* Define missing prototypes, implemented in replacement lib */ +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef HAVE_GETOPT +int getopt (int argc, char * const argv[], const char * optstring); +extern char * optarg; +extern int optind, opterr, optopt; +#endif + +#ifndef HAVE_USLEEP +int usleep(unsigned long usec); /* SUSv2 */ +#endif + +#ifndef HAVE_NANOSLEEP +#ifndef HAVE_STRUCT_TIMESPEC +#if HAVE_SYS_TYPES_H +# include /* need time_t */ +#endif +struct timespec { + time_t tv_sec; + long tv_nsec; +}; +#endif +static inline int nanosleep(const struct timespec *req, struct timespec *rem) { return usleep(req->tv_sec*1000000+req->tv_nsec/1000); } +#endif + +#if defined(HAVE_SSLEEP) && !defined(HAVE_SLEEP) +#ifdef HAVE_WINBASE_H +#include +#include +#endif +/* TODO: what about SleepEx? */ +static inline unsigned int sleep (unsigned int nb_sec) { Sleep(nb_sec*1000); return 0; } +#endif + +#ifndef HAVE_GETTIMEOFDAY +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifndef HAVE_STRUCT_TIMEZONE +struct timezone { + int tz_minuteswest; + int tz_dsttime; +}; +#endif +int gettimeofday(struct timeval *tv, struct timezone *tz); +#endif + +#if !defined(HAVE_RANDOM) && defined(HAVE_RAND) +#include +static inline long int random (void) { return rand(); } +#endif + +#if !defined(HAVE_SRANDOM) && defined(HAVE_SRAND) +static inline void srandom (unsigned int seed) { srand(seed); } +#endif + +#ifndef HAVE_SSIZE_T +typedef size_t ssize_t; +#endif + +#ifdef __cplusplus +} +#endif +]) + + +]) diff --git a/gsm-receiver/config/gr_python.m4 b/gsm-receiver/config/gr_python.m4 new file mode 100644 index 0000000..5816b27 --- /dev/null +++ b/gsm-receiver/config/gr_python.m4 @@ -0,0 +1,111 @@ +dnl +dnl Copyright 2003,2004,2005 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +# PYTHON_DEVEL() +# +# Checks for Python and tries to get the include path to 'Python.h'. +# It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LDFLAGS) output variables. +# +AC_DEFUN([PYTHON_DEVEL],[ + AC_REQUIRE([AM_PATH_PYTHON]) + AC_REQUIRE([AC_CANONICAL_HOST]) + + # For Fedora Core 5 and 6, see ticket:39 in Trac + if test -f '/etc/redhat-release'; then + if (echo $pyexecdir | grep -q lib64); then + pythondir="$pyexecdir" + fi + fi + + # Check for Python include path + AC_MSG_CHECKING([for Python include path]) + if test -z "$PYTHON" ; then + AC_MSG_ERROR([cannot find Python path]) + fi + + # ask distutils which include path we should use + python_cmd=' +import distutils.sysconfig +import os +path = distutils.sysconfig.get_python_inc(plat_specific=False) +if os.sep == "\\": + path = path.replace("\\", "/") +print path +' + python_path=`$PYTHON -c "$python_cmd"` + AC_MSG_RESULT([$python_path]) + if test -z "$python_path" ; then + AC_MSG_ERROR([cannot find Python include path]) + fi + + AC_SUBST(PYTHON_CPPFLAGS,[-I$python_path]) + + # Check for Python headers usability + python_save_CPPFLAGS=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $PYTHON_CPPFLAGS" + AC_CHECK_HEADERS([Python.h], [], + [AC_MSG_ERROR([cannot find usable Python headers])]) + CPPFLAGS="$python_save_CPPFLAGS" + + # Only set this on mingw and cygwin hosts, (only implemented + # for mingw host, for crosscompiling you need to trick this) + + PYTHON_LDFLAGS="" + case $host_os in + *mingw* | *cygwin* ) + AC_MSG_CHECKING([for Python LDFLAGS]) + + python_cmd=' +import distutils.sysconfig +import os +path = distutils.sysconfig.get_config_var("LIBPL") +if path == None: + path = distutils.sysconfig.PREFIX + "/libs" +if os.sep == "\\": + path = path.replace("\\", "/") +print path +' + python_stdlib_path=`$PYTHON -c "$python_cmd"` + + python_version_nodot=`echo $PYTHON_VERSION | sed "s,\.,,"` + libpython_name="python$PYTHON_VERSION" + + # Standard install of python for win32 has libpython24.a + # instead of libpython2.4.a so we check for the library + # without the dot in the version number. + + python_stdlib_filename=`find $python_stdlib_path -type f -name libpython$python_version_nodot.* -print | sed "1q"` + if test -n "$python_stdlib_filename" ; then + libpython_name="python$python_version_nodot" + fi + + PYTHON_LDFLAGS="-L$python_stdlib_path -l$libpython_name" + AC_MSG_RESULT($PYTHON_LDFLAGS) + # Replace all backslashes in PYTHON Paths with forward slashes + pythondir=`echo $pythondir |sed 's,\\\\,/,g'` + pkgpythondir=`echo $pkgpythondir |sed 's,\\\\,/,g'` + pyexecdir=`echo $pyexecdir |sed 's,\\\\,/,g'` + pkgpyexecdir=`echo $pkgpyexecdir |sed 's,\\\\,/,g'` + ;; + esac + + AC_SUBST([PYTHON_LDFLAGS]) +]) diff --git a/gsm-receiver/config/gr_require_mc4020.m4 b/gsm-receiver/config/gr_require_mc4020.m4 new file mode 100644 index 0000000..90774fd --- /dev/null +++ b/gsm-receiver/config/gr_require_mc4020.m4 @@ -0,0 +1,33 @@ +dnl +dnl Copyright 2003,2004 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +AC_DEFUN([GR_REQUIRE_MC4020],[ + AC_MSG_CHECKING([for mc4020 A/D driver include file]) + AC_COMPILE_IFELSE([ +#include +int main (int argc, char **argv) +{ + return 0; +} +],[AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + AC_MSG_ERROR([mc4020.h not found.])]) +]) diff --git a/gsm-receiver/config/gr_scripting.m4 b/gsm-receiver/config/gr_scripting.m4 new file mode 100644 index 0000000..86870e7 --- /dev/null +++ b/gsm-receiver/config/gr_scripting.m4 @@ -0,0 +1,30 @@ +dnl +dnl Copyright 2003 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +AC_DEFUN([GR_SCRIPTING],[ + AC_REQUIRE([AC_PROG_LN_S]) + AC_REQUIRE([AC_PROG_CXX]) + AC_REQUIRE([AC_PROG_LIBTOOL]) + + SWIG_PROG(1.3.23) + SWIG_ENABLE_CXX + SWIG_PYTHON +]) diff --git a/gsm-receiver/config/gr_set_md_cpu.m4 b/gsm-receiver/config/gr_set_md_cpu.m4 new file mode 100644 index 0000000..ebc1fad --- /dev/null +++ b/gsm-receiver/config/gr_set_md_cpu.m4 @@ -0,0 +1,44 @@ +dnl +dnl Copyright 2003 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +AC_DEFUN([GR_SET_MD_CPU],[ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_ARG_WITH(md-cpu, + [ --with-md-cpu=ARCH set machine dependent speedups (auto)], + [cf_with_md_cpu="$withval"], + [cf_with_md_cpu="$host_cpu"]) + + AC_MSG_CHECKING([for machine dependent speedups]) + case "$cf_with_md_cpu" in + x86 | i[[3-7]]86) MD_CPU=x86 MD_SUBCPU=x86 ;; + x86_64) MD_CPU=x86 MD_SUBCPU=x86_64 ;; +# sparc) MD_CPU=sparc ;; + *) MD_CPU=generic ;; + esac + AC_MSG_RESULT($MD_CPU) + AC_SUBST(MD_CPU) + AC_SUBST(MD_SUBCPU) + + AM_CONDITIONAL(MD_CPU_x86, test $MD_CPU = x86) + AM_CONDITIONAL(MD_SUBCPU_x86_64, test $MD_SUBCPU = x86_64) + AM_CONDITIONAL(MD_CPU_generic, test $MD_CPU = generic) +]) + diff --git a/gsm-receiver/config/gr_swig.m4 b/gsm-receiver/config/gr_swig.m4 new file mode 100644 index 0000000..cdb2805 --- /dev/null +++ b/gsm-receiver/config/gr_swig.m4 @@ -0,0 +1,85 @@ +dnl +dnl Copyright 2003 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +# SWIG_PROG([required-version]) +# +# Checks for the SWIG program. If found you can (and should) call SWIG via $(SWIG). +# You can use the optional first argument to check if the version of the available SWIG +# is greater or equal to the value of the argument. It should have the format: +# N[.N[.N]] (N is a number between 0 and 999. Only the first N is mandatory.) +AC_DEFUN([SWIG_PROG],[ + AC_REQUIRE([AC_PROG_MAKE_SET]) + AC_CHECK_PROG(SWIG,swig,[`which swig`]) + if test -z "$SWIG" ; then + AC_MSG_ERROR([Cannot find 'swig' program. SWIG version >= $1 required]) + SWIG=false + elif test -n "$1" ; then + AC_MSG_CHECKING([for SWIG version]) + swig_version=`$SWIG -version 2>&1 | \ + awk '/^SWIG Version [[0-9]+\.[0-9]+\.[0-9]]+.*$/ { split($[3],a,"[[^.0-9]]"); print a[[1]] }'` + AC_MSG_RESULT([$swig_version]) + if test -n "$swig_version" ; then + swig_version=`echo $swig_version | \ + awk '{ split($[1],a,"\."); print [a[1]*1000000+a[2]*1000+a[3]] }' 2>/dev/null` + swig_required_version=`echo $1 | \ + awk '{ split($[1],a,"\."); print [a[1]*1000000+a[2]*1000+a[3]] }' 2>/dev/null` + if test $swig_required_version -gt $swig_version ; then + AC_MSG_ERROR([SWIG version >= $1 required]) + fi + else + AC_MSG_ERROR([cannot determine SWIG version]) + fi + fi +]) + +# SWIG_ENABLE_CXX() +# +# Enable swig C++ support. This effects all invocations of $(SWIG). +AC_DEFUN([SWIG_ENABLE_CXX],[ + AC_REQUIRE([SWIG_PROG]) + AC_REQUIRE([AC_PROG_CXX]) + if test "$SWIG" != "false" ; then + SWIG="$SWIG -c++" + fi +]) + +# SWIG_PYTHON([use-shadow-classes]) +# +# Checks for Python and provides the $(SWIG_PYTHON_CPPFLAGS), +# $(SWIG_PYTHON_LIB) and $(SWIG_PYTHON_OPT) output variables. +# $(SWIG_PYTHON_OPT) contains all necessary swig options to generate +# code for Python. If you need multi module support use +# $(SWIG_PYTHON_LIB) (provided by the SWIG_MULTI_MODULE_SUPPORT() +# macro) to link against the appropriate library. It contains the +# SWIG Python runtime library that is needed by the type check system +# for example. + +AC_DEFUN([SWIG_PYTHON],[ + AC_REQUIRE([SWIG_PROG]) + AC_REQUIRE([PYTHON_DEVEL]) + if test "$SWIG" != "false" ; then + AC_SUBST(SWIG_PYTHON_LIB,[-lswigpy]) +dnl test ! "x$1" = "xno" && swig_shadow=" -shadow" || swig_shadow="" +dnl AC_SUBST(SWIG_PYTHON_OPT,[-python$swig_shadow]) + AC_SUBST(SWIG_PYTHON_OPT,[-python]) + fi + AC_SUBST(SWIG_PYTHON_CPPFLAGS,[$PYTHON_CPPFLAGS]) +]) diff --git a/gsm-receiver/config/gr_sysv_shm.m4 b/gsm-receiver/config/gr_sysv_shm.m4 new file mode 100644 index 0000000..db5c835 --- /dev/null +++ b/gsm-receiver/config/gr_sysv_shm.m4 @@ -0,0 +1,36 @@ +# Check for IPC System V shm support. -*- Autoconf -*- + +# Copyright 2003 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, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Boston, MA +# 02110-1301, USA. + +AC_DEFUN([GR_SYSV_SHM], +[ + AC_LANG_SAVE + AC_LANG_C + + AC_CHECK_HEADERS([sys/ipc.h sys/shm.h]) + + save_LIBS="$LIBS" + AC_SEARCH_LIBS(shmat, [cygipc ipc], + [ IPC_LIBS="$LIBS" ], + [ AC_MSG_WARN([SystemV IPC support not found. ]) ] + ) + LIBS="$save_LIBS" + + AC_LANG_RESTORE + AC_SUBST(IPC_LIBS) +]) diff --git a/gsm-receiver/config/gr_x86_64.m4 b/gsm-receiver/config/gr_x86_64.m4 new file mode 100644 index 0000000..3f56c06 --- /dev/null +++ b/gsm-receiver/config/gr_x86_64.m4 @@ -0,0 +1,39 @@ +dnl +dnl Copyright 2005 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +# GR_X86_64() +# +# Checks to see if we're on a x86_64 machine, and if so, ensure +# that libdir ends in "64" +# +AC_DEFUN([GR_X86_64],[ + AC_REQUIRE([AC_CANONICAL_HOST]) + if test "$host_cpu" = "x86_64"; then + AC_MSG_CHECKING([libdir for lib64 suffix]) + t=${libdir##*/lib} + if test "$t" != 64 && test -d /lib64 && ! test -L /lib64; then + libdir=${libdir}64 + AC_MSG_RESULT([no. Setting libdir to $libdir]) + else + AC_MSG_RESULT([yes]) + fi + fi +]) diff --git a/gsm-receiver/config/lf_cc.m4 b/gsm-receiver/config/lf_cc.m4 new file mode 100644 index 0000000..b9d1c9c --- /dev/null +++ b/gsm-receiver/config/lf_cc.m4 @@ -0,0 +1,42 @@ +dnl Autoconf support for C++ +dnl Copyright (C) 1988 Eleftherios Gkioulekas +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301, USA. +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a configuration +dnl script generated by Autoconf, you may include it under the same +dnl distribution terms that you use for the rest of that program. + +# ------------------------------------------------------------------------- +# Use this macro to configure your C compiler +# When called the macro does the following things: +# 1. It finds an appropriate C compiler. +# If you passed the flag --with-cc=foo then it uses that +# particular compiler +# 2. Check whether the compiler works. +# 3. Checks whether the compiler accepts the -g +# ------------------------------------------------------------------------- + +AC_DEFUN([LF_CONFIGURE_CC],[ + dnl Sing the song + AC_REQUIRE([AC_PROG_CC])dnl + AC_REQUIRE([AC_PROG_CPP])dnl + AC_REQUIRE([AC_AIX])dnl + AC_REQUIRE([AC_ISC_POSIX])dnl + AC_REQUIRE([AC_MINIX])dnl + AC_REQUIRE([AC_HEADER_STDC])dnl +]) + diff --git a/gsm-receiver/config/lf_cxx.m4 b/gsm-receiver/config/lf_cxx.m4 new file mode 100644 index 0000000..c581c9b --- /dev/null +++ b/gsm-receiver/config/lf_cxx.m4 @@ -0,0 +1,121 @@ +dnl Autoconf support for C++ +dnl Copyright (C) 1988 Eleftherios Gkioulekas +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301, USA. +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a configuration +dnl script generated by Autoconf, you may include it under the same +dnl distribution terms that you use for the rest of that program. + +# ----------------------------------------------------------------- +# This macro should be called to configure your C++ compiler. +# When called, the macro does the following things: +# 1. It finds an appropriate C++ compiler +# If you passed the flag --with-cxx=foo, then it uses that +# particular compiler +# 2. Checks whether the compiler accepts the -g +# ------------------------------------------------------------------ + +AC_DEFUN([LF_CONFIGURE_CXX],[ + AC_REQUIRE([AC_PROG_CXX])dnl + AC_REQUIRE([AC_PROG_CXXCPP])dnl + LF_CXX_PORTABILITY +]) + +# ----------------------------------------------------------------------- +# This macro tests the C++ compiler for various portability problem. +# 1. Defines CXX_HAS_NO_BOOL if the compiler does not support the bool +# data type +# 2. Defines CXX_HAS_BUGGY_FOR_LOOPS if the compiler has buggy +# scoping for the for-loop +# 3. Defines USE_ASSERT if the user wants to use assertions +# ----------------------------------------------------------------------- + + +AC_DEFUN([LF_CXX_PORTABILITY],[ + + dnl + dnl Check for common C++ portability problems + dnl + + dnl AC_LANG_PUSH + dnl AC_LANG_CPLUSPLUS + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + + dnl Check whether we have bool + AC_MSG_CHECKING(whether C++ has bool) + AC_TRY_RUN([main() { bool b1=true; bool b2=false; }], + [ AC_MSG_RESULT(yes) ], + [ AC_MSG_RESULT(no) + AC_DEFINE(CXX_HAS_NO_BOOL,[],[Define if C++ is missing bool type]) ], + [ AC_MSG_WARN(Don't cross-compile)] + ) + + dnl Test whether C++ has buggy for-loops + AC_MSG_CHECKING(whether C++ has buggy scoping in for-loops) + AC_TRY_COMPILE([#include ], [ + for (int i=0;i<10;i++) { } + for (int i=0;i<10;i++) { } +], [ AC_MSG_RESULT(no) ], + [ AC_MSG_RESULT(yes) + AC_DEFINE(CXX_HAS_BUGGY_FOR_LOOPS,[],[Define if for loop scoping is broken]) ]) + + dnl Test whether the user wants to enable assertions + AC_MSG_CHECKING(whether user wants assertions) + AC_ARG_ENABLE(assert, + [ --disable-assert don't use cpp.h assert], + [ AC_DEFINE(NDEBUG,[],[Define to disable asserts (don't doit!)]) + AC_MSG_RESULT(no) ], + [ AC_MSG_RESULT(yes) ], + ) + + dnl Test whether C++ has std::isnan + AC_MSG_CHECKING(whether C++ has std::isnan) + AC_TRY_COMPILE([#include ], [ + std::isnan(0); +], [ AC_MSG_RESULT(yes) + AC_DEFINE(CXX_HAS_STD_ISNAN,[],[Define if has std::isnan]) ], + [ AC_MSG_RESULT(no) ]) + + dnl Done with the portability checks + dnl AC_LANG_POP([C++]) + AC_LANG_RESTORE +]) + +AH_BOTTOM([// Workaround for compilers with buggy for-loop scoping +// That's quite a few compilers actually including recent versions of +// Dec Alpha cxx, HP-UX CC and SGI CC. +// The trivial "if" statement provides the correct scoping to the +// for loop + +#ifdef CXX_HAS_BUGGY_FOR_LOOPS +#undef for +#define for if(1) for +#endif +]) + +AH_BOTTOM([// If the C++ compiler we use doesn't have bool, then +// the following is a near-perfect work-around. +// You must make sure your code does not depend on "int" and "bool" +// being two different types, in overloading for instance. + +#ifdef CXX_HAS_NO_BOOL +#define bool int +#define true 1 +#define false 0 +#endif +]) diff --git a/gsm-receiver/config/lf_warnings.m4 b/gsm-receiver/config/lf_warnings.m4 new file mode 100644 index 0000000..4e2ca91 --- /dev/null +++ b/gsm-receiver/config/lf_warnings.m4 @@ -0,0 +1,128 @@ +dnl Copyright (C) 1988 Eleftherios Gkioulekas +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301, USA. +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a configuration +dnl script generated by Autoconf, you may include it under the same +dnl distribution terms that you use for the rest of that program. + +# -------------------------------------------------------------------------- +# Check whether the C++ compiler accepts a certain flag +# If it does it adds the flag to CXXFLAGS +# If it does not then it returns an error to lf_ok +# Usage: +# LF_CHECK_CXX_FLAG(-flag1 -flag2 -flag3 ...) +# ------------------------------------------------------------------------- + +AC_DEFUN([LF_CHECK_CXX_FLAG],[ + echo 'void f(){}' > conftest.cc + for i in $1 + do + AC_MSG_CHECKING([whether $CXX accepts $i]) + if test -z "`${CXX} $i -c conftest.cc 2>&1`" + then + CXXFLAGS="${CXXFLAGS} $i" + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + done + rm -f conftest.cc conftest.o +]) + +# -------------------------------------------------------------------------- +# Check whether the C compiler accepts a certain flag +# If it does it adds the flag to CFLAGS +# If it does not then it returns an error to lf_ok +# Usage: +# LF_CHECK_CC_FLAG(-flag1 -flag2 -flag3 ...) +# ------------------------------------------------------------------------- + +AC_DEFUN([LF_CHECK_CC_FLAG],[ + echo 'void f(){}' > conftest.c + for i in $1 + do + AC_MSG_CHECKING([whether $CC accepts $i]) + if test -z "`${CC} $i -c conftest.c 2>&1`" + then + CFLAGS="${CFLAGS} $i" + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + done + rm -f conftest.c conftest.o +]) + +# -------------------------------------------------------------------------- +# Check whether the Fortran compiler accepts a certain flag +# If it does it adds the flag to FFLAGS +# If it does not then it returns an error to lf_ok +# Usage: +# LF_CHECK_F77_FLAG(-flag1 -flag2 -flag3 ...) +# ------------------------------------------------------------------------- + +AC_DEFUN([LF_CHECK_F77_FLAG],[ + cat << EOF > conftest.f +c....:++++++++++++++++++++++++ + PROGRAM MAIN + PRINT*,'Hello World!' + END +EOF + for i in $1 + do + AC_MSG_CHECKING([whether $F77 accepts $i]) + if test -z "`${F77} $i -c conftest.f 2>&1`" + then + FFLAGS="${FFLAGS} $i" + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + done + rm -f conftest.f conftest.o +]) + +# ---------------------------------------------------------------------- +# Provide the configure script with an --with-warnings option that +# turns on warnings. Call this command AFTER you have configured ALL your +# compilers. +# ---------------------------------------------------------------------- + +AC_DEFUN([LF_SET_WARNINGS],[ + dnl Check for --with-warnings + AC_MSG_CHECKING([whether user wants warnings]) + AC_ARG_WITH(warnings, + [ --with-warnings Turn on warnings], + [ lf_warnings=yes ], [ lf_warnings=no ]) + lf_warnings=yes # hard code for now -eb + AC_MSG_RESULT($lf_warnings) + + dnl Warnings for the two main compilers + cc_warning_flags="-Wall" + cxx_warning_flags="-Wall -Woverloaded-virtual" + if test $lf_warnings = yes + then + if test -n "${CC}" + then + LF_CHECK_CC_FLAG($cc_warning_flags) + fi + if test -n "${CXX}" + then + LF_CHECK_CXX_FLAG($cxx_warning_flags) + fi + fi +]) diff --git a/gsm-receiver/config/lf_x11.m4 b/gsm-receiver/config/lf_x11.m4 new file mode 100644 index 0000000..460cd60 --- /dev/null +++ b/gsm-receiver/config/lf_x11.m4 @@ -0,0 +1,39 @@ +dnl Copyright (C) 1988 Eleftherios Gkioulekas +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301, USA. +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a configuration +dnl script generated by Autoconf, you may include it under the same +dnl distribution terms that you use for the rest of that program. + + +#----------------------------------------------------------------------- +# This macro searches for Xlib and when it finds it it adds the +# appropriate flags to CXXFLAGS and export the link sequence to +# the variable XLIB. +# In your configure.in file add: +# LF_PATH_XLIB +# In your Makefile.am add +# program_LDADD = .... $(XLIB) +#------------------------------------------------------------------------ + +AC_DEFUN([LF_PATH_XLIB],[ + AC_PATH_XTRA + CXXFLAGS="$CXXFLAGS $X_CFLAGS" + XLIB="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS" + AC_SUBST(XLIB) +]) + diff --git a/gsm-receiver/config/mkstemp.m4 b/gsm-receiver/config/mkstemp.m4 new file mode 100644 index 0000000..4af0f0a --- /dev/null +++ b/gsm-receiver/config/mkstemp.m4 @@ -0,0 +1,89 @@ +#serial 4 + +# On some hosts (e.g., HP-UX 10.20, SunOS 4.1.4, Solaris 2.5.1), mkstemp has a +# silly limit that it can create no more than 26 files from a given template. +# Other systems lack mkstemp altogether. +# On OSF1/Tru64 V4.0F, the system-provided mkstemp function can create +# only 32 files per process. +# On systems like the above, arrange to use the replacement function. +AC_DEFUN([UTILS_FUNC_MKSTEMP], +[dnl + AC_REPLACE_FUNCS(mkstemp) + if test $ac_cv_func_mkstemp = no; then + utils_cv_func_mkstemp_limitations=yes + else + AC_CACHE_CHECK([for mkstemp limitations], + utils_cv_func_mkstemp_limitations, + [ + AC_TRY_RUN([ +# include + int main () + { + int i; + for (i = 0; i < 70; i++) + { + char template[] = "conftestXXXXXX"; + int fd = mkstemp (template); + if (fd == -1) + exit (1); + close (fd); + } + exit (0); + } + ], + utils_cv_func_mkstemp_limitations=no, + utils_cv_func_mkstemp_limitations=yes, + utils_cv_func_mkstemp_limitations=yes + ) + ] + ) + fi + + if test $utils_cv_func_mkstemp_limitations = yes; then + AC_LIBOBJ(mkstemp) + AC_LIBOBJ(tempname) + AC_DEFINE(mkstemp, rpl_mkstemp, + [Define to rpl_mkstemp if the replacement function should be used.]) + gl_PREREQ_MKSTEMP + jm_PREREQ_TEMPNAME + fi +]) + +# Prerequisites of lib/mkstemp.c. +AC_DEFUN([gl_PREREQ_MKSTEMP], +[ + AH_BOTTOM( + [ + #ifndef HAVE_MKSTEMP + #ifdef __cplusplus + extern "C" { + #endif + int rpl_mkstemp (char *templ); + #ifdef __cplusplus + } + #endif + #endif + ]) +]) + +# Prerequisites of lib/tempname.c. +AC_DEFUN([jm_PREREQ_TEMPNAME], +[ + AC_REQUIRE([AC_HEADER_STAT]) + AC_CHECK_HEADERS_ONCE(fcntl.h sys/time.h unistd.h) + AC_CHECK_HEADERS(stdint.h) + AC_CHECK_FUNCS(__secure_getenv gettimeofday lstat) + AC_CHECK_DECLS_ONCE(getenv) + # AC_REQUIRE([jm_AC_TYPE_UINTMAX_T]) + + dnl Under Win32, mkdir prototype in io.h has only one arg + AC_MSG_CHECKING(whether mkdir accepts only one arg) + AC_TRY_COMPILE([#include + #include + #include ], [ + mkdir("") + ], [ AC_MSG_RESULT(yes) + AC_DEFINE(MKDIR_TAKES_ONE_ARG,[],[Define if mkdir accepts only one arg]) ], + [ AC_MSG_RESULT(no) + ]) +]) diff --git a/gsm-receiver/config/onceonly.m4 b/gsm-receiver/config/onceonly.m4 new file mode 100644 index 0000000..f6fec37 --- /dev/null +++ b/gsm-receiver/config/onceonly.m4 @@ -0,0 +1,63 @@ +# onceonly.m4 serial 3 +dnl Copyright (C) 2002, 2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl This file defines some "once only" variants of standard autoconf macros. +dnl AC_CHECK_HEADERS_ONCE like AC_CHECK_HEADERS +dnl AC_CHECK_FUNCS_ONCE like AC_CHECK_FUNCS +dnl AC_CHECK_DECLS_ONCE like AC_CHECK_DECLS +dnl AC_REQUIRE([AC_HEADER_STDC]) like AC_HEADER_STDC +dnl The advantage is that the check for each of the headers/functions/decls +dnl will be put only once into the 'configure' file. It keeps the size of +dnl the 'configure' file down, and avoids redundant output when 'configure' +dnl is run. +dnl The drawback is that the checks cannot be conditionalized. If you write +dnl if some_condition; then gl_CHECK_HEADERS(stdlib.h); fi +dnl inside an AC_DEFUNed function, the gl_CHECK_HEADERS macro call expands to +dnl empty, and the check will be inserted before the body of the AC_DEFUNed +dnl function. + +dnl Autoconf version 2.57 or newer is recommended. +AC_PREREQ(2.54) + +# AC_CHECK_HEADERS_ONCE(HEADER1 HEADER2 ...) is a once-only variant of +# AC_CHECK_HEADERS(HEADER1 HEADER2 ...). +AC_DEFUN([AC_CHECK_HEADERS_ONCE], [ + : + AC_FOREACH([gl_HEADER_NAME], [$1], [ + AC_DEFUN([gl_CHECK_HEADER_]m4_quote(translit(defn([gl_HEADER_NAME]), + [-./], [___])), [ + AC_CHECK_HEADERS(gl_HEADER_NAME) + ]) + AC_REQUIRE([gl_CHECK_HEADER_]m4_quote(translit(gl_HEADER_NAME, + [-./], [___]))) + ]) +]) + +# AC_CHECK_FUNCS_ONCE(FUNC1 FUNC2 ...) is a once-only variant of +# AC_CHECK_FUNCS(FUNC1 FUNC2 ...). +AC_DEFUN([AC_CHECK_FUNCS_ONCE], [ + : + AC_FOREACH([gl_FUNC_NAME], [$1], [ + AC_DEFUN([gl_CHECK_FUNC_]defn([gl_FUNC_NAME]), [ + AC_CHECK_FUNCS(defn([gl_FUNC_NAME])) + ]) + AC_REQUIRE([gl_CHECK_FUNC_]defn([gl_FUNC_NAME])) + ]) +]) + +# AC_CHECK_DECLS_ONCE(DECL1 DECL2 ...) is a once-only variant of +# AC_CHECK_DECLS(DECL1, DECL2, ...). +AC_DEFUN([AC_CHECK_DECLS_ONCE], [ + : + AC_FOREACH([gl_DECL_NAME], [$1], [ + AC_DEFUN([gl_CHECK_DECL_]defn([gl_DECL_NAME]), [ + AC_CHECK_DECLS(defn([gl_DECL_NAME])) + ]) + AC_REQUIRE([gl_CHECK_DECL_]defn([gl_DECL_NAME])) + ]) +]) diff --git a/gsm-receiver/config/pkg.m4 b/gsm-receiver/config/pkg.m4 new file mode 100644 index 0000000..770f062 --- /dev/null +++ b/gsm-receiver/config/pkg.m4 @@ -0,0 +1,68 @@ +dnl PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not) +dnl defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page +dnl also defines GSTUFF_PKG_ERRORS on error +AC_DEFUN([PKG_CHECK_MODULES], [ + succeeded=no + + if test -z "$PKG_CONFIG"; then + AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + fi + + if test "$PKG_CONFIG" = "no" ; then + echo "*** The pkg-config script could not be found. Make sure it is" + echo "*** in your path, or set the PKG_CONFIG environment variable" + echo "*** to the full path to pkg-config." + echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." + else + dnl If PKG_CONFIG_PATH is not already set, add /usr/local/lib/pkgconfig. + dnl If it's set, assume the user knows what they're doing. + dnl This should help avoid failures while looking for fftw3f + if test -z "$PKG_CONFIG_PATH"; then + export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig" + fi + + PKG_CONFIG_MIN_VERSION=0.9.0 + if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then + AC_MSG_CHECKING(for $2) + + if $PKG_CONFIG --exists "$2" ; then + AC_MSG_RESULT(yes) + succeeded=yes + + AC_MSG_CHECKING($1_CFLAGS) + $1_CFLAGS=`$PKG_CONFIG --cflags "$2"` + AC_MSG_RESULT($$1_CFLAGS) + + AC_MSG_CHECKING($1_LIBS) + $1_LIBS=`$PKG_CONFIG --libs "$2"` + AC_MSG_RESULT($$1_LIBS) + + AC_MSG_CHECKING($1_INCLUDEDIR) + $1_INCLUDEDIR=`$PKG_CONFIG --variable=includedir "$2"` + AC_MSG_RESULT($$1_INCLUDEDIR) + else + $1_CFLAGS="" + $1_LIBS="" + ## If we have a custom action on failure, don't print errors, but + ## do set a variable so people can do so. + $1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` + ifelse([$4], ,echo $$1_PKG_ERRORS,) + fi + + AC_SUBST($1_CFLAGS) + AC_SUBST($1_LIBS) + AC_SUBST($1_INCLUDEDIR) + else + echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." + echo "*** See http://www.freedesktop.org/software/pkgconfig" + fi + fi + + if test $succeeded = yes; then + ifelse([$3], , :, [$3]) + else + ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4]) + fi +]) + + diff --git a/gsm-receiver/config/usrp_fusb_tech.m4 b/gsm-receiver/config/usrp_fusb_tech.m4 new file mode 100644 index 0000000..b5a930b --- /dev/null +++ b/gsm-receiver/config/usrp_fusb_tech.m4 @@ -0,0 +1,56 @@ +dnl +dnl Copyright 2003 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +AC_DEFUN([USRP_SET_FUSB_TECHNIQUE],[ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_ARG_WITH(fusb-tech, + [ --with-fusb-tech=OS set fast usb technique (auto)], + [cf_with_fusb_tech="$withval"], + [cf_with_fusb_tech="$host_os"]) + + + AC_CHECK_HEADER([linux/usbdevice_fs.h], + [x_have_usbdevice_fs_h=yes], + [x_have_usbdevice_fs_h=no]) + + AC_MSG_CHECKING([for fast usb technique to use]) + case "$cf_with_fusb_tech" in + linux*) if test x${x_have_usbdevice_fs_h} = xyes; + then + FUSB_TECH=linux + else + FUSB_TECH=generic + fi ;; + + darwin*) FUSB_TECH=darwin ;; + cygwin*|win*|mingw*) FUSB_TECH=win32 ;; + *) FUSB_TECH=generic ;; + esac + + AC_MSG_RESULT($FUSB_TECH) + AC_SUBST(FUSB_TECH) + + AM_CONDITIONAL(FUSB_TECH_darwin, test $FUSB_TECH = darwin) + AM_CONDITIONAL(FUSB_TECH_win32, test $FUSB_TECH = win32) + AM_CONDITIONAL(FUSB_TECH_generic, test $FUSB_TECH = generic) + AM_CONDITIONAL(FUSB_TECH_linux, test $FUSB_TECH = linux) +]) + diff --git a/gsm-receiver/config/usrp_libusb.m4 b/gsm-receiver/config/usrp_libusb.m4 new file mode 100644 index 0000000..9fe4753 --- /dev/null +++ b/gsm-receiver/config/usrp_libusb.m4 @@ -0,0 +1,43 @@ +# Check for libusb support. -*- Autoconf -*- + +# Copyright 2003 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, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Boston, MA +# 02110-1301, USA. + +AC_DEFUN([USRP_LIBUSB], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_LANG_PUSH(C) + + AC_CHECK_HEADERS([usb.h], + [], + [ AC_MSG_ERROR([USRP requires libusb. usb.h not found, stop. See http://libusb.sf.net]) ] + ) + + save_LIBS="$LIBS" + case "$host_os" in + darwin*) LIBS="$LIBS -lIOKit" ;; + *) ;; + esac + AC_SEARCH_LIBS(usb_bulk_write, [usb], + [ USB_LIBS="$LIBS" ], + [ AC_MSG_ERROR([USRP requires libusb. usb_bulk_write not found, stop. See http://libusb.sf.net]) ] + ) + LIBS="$save_LIBS" + + AC_LANG_POP + AC_SUBST(USB_LIBS) +]) diff --git a/gsm-receiver/config/usrp_sdcc.m4 b/gsm-receiver/config/usrp_sdcc.m4 new file mode 100644 index 0000000..37ce7c3 --- /dev/null +++ b/gsm-receiver/config/usrp_sdcc.m4 @@ -0,0 +1,67 @@ +# Check for sdcc support. -*- Autoconf -*- + +# Copyright 2004 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, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Boston, MA +# 02110-1301, USA. + +AC_DEFUN([USRP_SDCC], +[ + AC_CHECK_PROG(XCC, sdcc, sdcc -mmcs51 --no-xinit-opt,no) + AC_CHECK_PROG(XAS, asx8051, asx8051 -plosgff,no) + + if test "$XCC" = "no" -o "$XAS" = "no" ; then + AC_MSG_ERROR([USRP requires sdcc. sdcc not found, stop. See http://sdcc.sf.net]) + fi + + sdcc_version_min=$1 + + sdcc_version=`sdcc --version 2>&1 | \ + sed 's/\(SDCC.* \)\([[0-9]]*\.[[0-9]]*\.[[0-9]]*\)\( .*$\)/\2/'` + + AC_MSG_CHECKING([sdcc_version "$sdcc_version"]) + + sdcc_major_version=`echo $sdcc_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + sdcc_minor_version=`echo $sdcc_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + sdcc_micro_version=`echo $sdcc_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + + sdcc_major_min=`echo $sdcc_version_min | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + sdcc_minor_min=`echo $sdcc_version_min | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + sdcc_micro_min=`echo $sdcc_version_min | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + + sdcc_version_proper=`expr \ + "$sdcc_major_version" \> "$sdcc_major_min" \| \ + "$sdcc_major_version" \= "$sdcc_major_min" \& \ + "$sdcc_minor_version" \> "$sdcc_minor_min" \| \ + "$sdcc_major_version" \= "$sdcc_major_min" \& \ + "$sdcc_minor_version" \= "$sdcc_minor_min" \& \ + "$sdcc_micro_version" \>= "$sdcc_micro_min" ` + + if test "$sdcc_version_proper" = "1" ; then + AC_MSG_RESULT([$sdcc_major_version.$sdcc_minor_version.$sdcc_micro_version]) + else + AC_MSG_ERROR([USRP requires sdcc >= $sdcc_version_min. sdcc not found, stop. See http://sdcc.sf.net]) + fi + + AC_SUBST(XCC) + AC_SUBST(XAS) + +]) diff --git a/gsm-receiver/configure.ac b/gsm-receiver/configure.ac new file mode 100644 index 0000000..30fe57a --- /dev/null +++ b/gsm-receiver/configure.ac @@ -0,0 +1,120 @@ +dnl +dnl Copyright 2004,2005,2006,2007,2008 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +AC_INIT +AC_PREREQ(2.61) +AC_CONFIG_SRCDIR([src/lib/gsm.i]) +AM_CONFIG_HEADER(config.h) +AC_CANONICAL_TARGET([]) +AC_CONFIG_AUX_DIR([.]) +AM_INIT_AUTOMAKE(gsm-receiver,0.0.1) +AC_CONFIG_MACRO_DIR([config]) + +GR_X86_64 +dnl LF_CONFIGURE_CC +LF_CONFIGURE_CXX +LF_SET_WARNINGS + +dnl add ${prefix}/lib${gr_libdir_suffix}/pkgconfig to the head of the PKG_CONFIG_PATH +if test x${PKG_CONFIG_PATH} = x; then + PKG_CONFIG_PATH=${prefix}/lib${gr_libdir_suffix}/pkgconfig +else + PKG_CONFIG_PATH=${prefix}/lib${gr_libdir_suffix}/pkgconfig:${PKG_CONFIG_PATH} +fi +export PKG_CONFIG_PATH + + +GR_SET_GPROF +GR_SET_PROF +AM_PROG_AS +AC_PROG_LN_S +AC_PROG_MAKE_SET +AC_PROG_INSTALL +AC_PATH_PROG([RM_PROG], [rm]) + +AC_LIBTOOL_WIN32_DLL +AC_ENABLE_SHARED dnl do build shared libraries +AC_DISABLE_STATIC dnl don't build static libraries +m4_ifdef([LT_INIT],[LT_INIT],[AC_PROG_LIBTOOL]) +dnl Locate python, SWIG, etc +GR_NO_UNDEFINED +GR_SCRIPTING + +dnl Checks for libraries. + +dnl check for threads (mandatory) +GR_OMNITHREAD + +CFLAGS="${CFLAGS} $PTHREAD_CFLAGS" +CXXFLAGS="${CXXFLAGS} $PTHREAD_CFLAGS" + +if test "x$CXX_FOR_BUILD" = x +then + CXX_FOR_BUILD=${CXX} +fi +AC_SUBST(CXX_FOR_BUILD) + +dnl Checks for header files. +AC_HEADER_STDC +AC_HEADER_SYS_WAIT +AC_CHECK_HEADERS(fcntl.h limits.h strings.h sys/ioctl.h sys/time.h unistd.h) +AC_CHECK_HEADERS(sys/mman.h) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_INLINE +AC_TYPE_SIZE_T +AC_HEADER_TIME + +dnl Checks for library functions. +AC_CHECK_FUNCS([]) + +dnl Check for Mingw support +GR_PWIN32 + +PKG_CHECK_MODULES(GNURADIO_CORE, gnuradio-core >= 3) +dnl LIBS="$LIBS $GNURADIO_CORE_LIBS" + +dnl Define where to find boost includes +dnl defines BOOST_CFLAGS +GR_REQUIRE_BOOST_INCLUDES + +STD_DEFINES_AND_INCLUDES="$GNURADIO_CORE_CFLAGS $BOOST_CFLAGS" +AC_SUBST(STD_DEFINES_AND_INCLUDES) + + +AC_CONFIG_FILES([\ + Makefile \ + config/Makefile \ + src/Makefile \ + src/lib/Makefile \ + src/lib/decoder/Makefile \ + src/python/Makefile \ + src/lib/decoder/openbtsstuff/Makefile \ + gsm-receiver.pc \ + ]) +dnl # doc/Makefile \ +dnl # src/python/run_tests \ + +dnl run_tests is created from run_tests.in. Make it executable. +#AC_CONFIG_COMMANDS([run_tests], [chmod +x src/python/run_tests]) + +AC_OUTPUT diff --git a/gsm-receiver/gsm-receiver.pc.in b/gsm-receiver/gsm-receiver.pc.in new file mode 100644 index 0000000..0a18d4b --- /dev/null +++ b/gsm-receiver/gsm-receiver.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: gsm-receiver +Description: The GSM receiver block which does FCCH burst search, sch decoding and normal burst demodulation +Requires: gnuradio-core +Version: @VERSION@ +Libs: -L${libdir} -lgsm-receiver +Cflags: -I${includedir} diff --git a/gsm-receiver/py-compile b/gsm-receiver/py-compile new file mode 100755 index 0000000..d6e900b --- /dev/null +++ b/gsm-receiver/py-compile @@ -0,0 +1,146 @@ +#!/bin/sh +# py-compile - Compile a Python program + +scriptversion=2005-05-14.22 + +# Copyright (C) 2000, 2001, 2003, 2004, 2005 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 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +if [ -z "$PYTHON" ]; then + PYTHON=python +fi + +basedir= +destdir= +files= +while test $# -ne 0; do + case "$1" in + --basedir) + basedir=$2 + if test -z "$basedir"; then + echo "$0: Missing argument to --basedir." 1>&2 + exit 1 + fi + shift + ;; + --destdir) + destdir=$2 + if test -z "$destdir"; then + echo "$0: Missing argument to --destdir." 1>&2 + exit 1 + fi + shift + ;; + -h|--h*) + cat <<\EOF +Usage: py-compile [--help] [--version] [--basedir DIR] [--destdir DIR] FILES..." + +Byte compile some python scripts FILES. Use --destdir to specify any +leading directory path to the FILES that you don't want to include in the +byte compiled file. Specify --basedir for any additional path information you +do want to be shown in the byte compiled file. + +Example: + py-compile --destdir /tmp/pkg-root --basedir /usr/share/test test.py test2.py + +Report bugs to . +EOF + exit $? + ;; + -v|--v*) + echo "py-compile $scriptversion" + exit $? + ;; + *) + files="$files $1" + ;; + esac + shift +done + +if test -z "$files"; then + echo "$0: No files given. Try \`$0 --help' for more information." 1>&2 + exit 1 +fi + +# if basedir was given, then it should be prepended to filenames before +# byte compilation. +if [ -z "$basedir" ]; then + pathtrans="path = file" +else + pathtrans="path = os.path.join('$basedir', file)" +fi + +# if destdir was given, then it needs to be prepended to the filename to +# byte compile but not go into the compiled file. +if [ -z "$destdir" ]; then + filetrans="filepath = path" +else + filetrans="filepath = os.path.normpath('$destdir' + os.sep + path)" +fi + +$PYTHON -c " +import sys, os, string, py_compile + +files = '''$files''' + +print 'Byte-compiling python modules...' +for file in string.split(files): + $pathtrans + $filetrans + if not os.path.exists(filepath) or not (len(filepath) >= 3 + and filepath[-3:] == '.py'): + continue + print file, + sys.stdout.flush() + py_compile.compile(filepath, filepath + 'c', path) +print" || exit $? + +# this will fail for python < 1.5, but that doesn't matter ... +$PYTHON -O -c " +import sys, os, string, py_compile + +files = '''$files''' +print 'Byte-compiling python modules (optimized versions) ...' +for file in string.split(files): + $pathtrans + $filetrans + if not os.path.exists(filepath) or not (len(filepath) >= 3 + and filepath[-3:] == '.py'): + continue + print file, + sys.stdout.flush() + py_compile.compile(filepath, filepath + 'o', path) +print" 2>/dev/null || : + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/gsm-receiver/src/Makefile.am b/gsm-receiver/src/Makefile.am new file mode 100644 index 0000000..79cfa3e --- /dev/null +++ b/gsm-receiver/src/Makefile.am @@ -0,0 +1,23 @@ +# +# Copyright 2004 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. +# + +SUBDIRS = lib python + diff --git a/gsm-receiver/src/lib/Assert.h b/gsm-receiver/src/lib/Assert.h new file mode 100644 index 0000000..acfb3f7 --- /dev/null +++ b/gsm-receiver/src/lib/Assert.h @@ -0,0 +1,67 @@ +/* +* 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 . + +*/ + + +#ifndef ASSERT_H +#define ASSERT_H + +#include "stdio.h" +#include + +#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/gsm-receiver/src/lib/Makefile.am b/gsm-receiver/src/lib/Makefile.am new file mode 100644 index 0000000..925eaca --- /dev/null +++ b/gsm-receiver/src/lib/Makefile.am @@ -0,0 +1,109 @@ +# +# 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/gsm-receiver/src/lib/decoder/AUTHORS b/gsm-receiver/src/lib/decoder/AUTHORS new file mode 100644 index 0000000..dcc5998 --- /dev/null +++ b/gsm-receiver/src/lib/decoder/AUTHORS @@ -0,0 +1 @@ +Harald Welte diff --git a/gsm-receiver/src/lib/decoder/Makefile.am b/gsm-receiver/src/lib/decoder/Makefile.am new file mode 100644 index 0000000..1726d68 --- /dev/null +++ b/gsm-receiver/src/lib/decoder/Makefile.am @@ -0,0 +1,56 @@ +# +# 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/gsm-receiver/src/lib/decoder/a5-1-2.h b/gsm-receiver/src/lib/decoder/a5-1-2.h new file mode 100644 index 0000000..de764ee --- /dev/null +++ b/gsm-receiver/src/lib/decoder/a5-1-2.h @@ -0,0 +1,453 @@ +/* + * 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 + * Voice: +1 (925) 798-4042 + * + */ + + +#include + + +/* 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/gsm-receiver/src/lib/decoder/burst_types.h b/gsm-receiver/src/lib/decoder/burst_types.h new file mode 100644 index 0000000..ee51f9a --- /dev/null +++ b/gsm-receiver/src/lib/decoder/burst_types.h @@ -0,0 +1,214 @@ +// $Id: burst_types.h,v 1.5 2007/03/14 05:44:53 jl Exp $ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +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/gsm-receiver/src/lib/decoder/cch.c b/gsm-receiver/src/lib/decoder/cch.c new file mode 100644 index 0000000..f1da56d --- /dev/null +++ b/gsm-receiver/src/lib/decoder/cch.c @@ -0,0 +1,482 @@ +//TODO: this file shouldn't be part of the GSM Receiver +#include "system.h" +#include +#include +#include +#include +#include + +//#include +//#include +#include +//#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/gsm-receiver/src/lib/decoder/cch.h b/gsm-receiver/src/lib/decoder/cch.h new file mode 100644 index 0000000..a642721 --- /dev/null +++ b/gsm-receiver/src/lib/decoder/cch.h @@ -0,0 +1,56 @@ +//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/gsm-receiver/src/lib/decoder/fire_crc.c b/gsm-receiver/src/lib/decoder/fire_crc.c new file mode 100644 index 0000000..7cdfc0b --- /dev/null +++ b/gsm-receiver/src/lib/decoder/fire_crc.c @@ -0,0 +1,179 @@ +//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 +#include + +#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/gsm-receiver/src/lib/decoder/fire_crc.h b/gsm-receiver/src/lib/decoder/fire_crc.h new file mode 100644 index 0000000..aa6319c --- /dev/null +++ b/gsm-receiver/src/lib/decoder/fire_crc.h @@ -0,0 +1,47 @@ +//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/gsm-receiver/src/lib/decoder/gsmstack.c b/gsm-receiver/src/lib/decoder/gsmstack.c new file mode 100644 index 0000000..c3f1921 --- /dev/null +++ b/gsm-receiver/src/lib/decoder/gsmstack.c @@ -0,0 +1,206 @@ +/* + * Invoke gsmstack() with any kind of burst. Automaticly decode and retrieve + * information. + */ +#include "system.h" +#include +#include +#include +#include +#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/gsm-receiver/src/lib/decoder/gsmstack.h b/gsm-receiver/src/lib/decoder/gsmstack.h new file mode 100644 index 0000000..9355785 --- /dev/null +++ b/gsm-receiver/src/lib/decoder/gsmstack.h @@ -0,0 +1,43 @@ +//TODO: this file shouldn't be part of the GSM Receiver +#ifndef __GSMSTACK_H__ +#define __GSMSTACK_H__ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "interleave.h" + +struct gs_ts_ctx { + /* FIXME: later do this per each ts per each arfcn */ + unsigned char burst[4 * 58 * 2]; + int burst_count; +}; + +typedef struct +{ + int flags; + int fn; + int bsic; + char msg[23]; /* last decoded message */ + + INTERLEAVE_CTX interleave_ctx; + + 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/gsm-receiver/src/lib/decoder/gsmtap.h b/gsm-receiver/src/lib/decoder/gsmtap.h new file mode 100644 index 0000000..1022194 --- /dev/null +++ b/gsm-receiver/src/lib/decoder/gsmtap.h @@ -0,0 +1,41 @@ +#ifndef _GSMTAP_H +#define _GSMTAP_H + +/* gsmtap header, pseudo-header in front of the actua GSM payload*/ + +#include + +#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/gsm-receiver/src/lib/decoder/interleave.c b/gsm-receiver/src/lib/decoder/interleave.c new file mode 100644 index 0000000..7b45927 --- /dev/null +++ b/gsm-receiver/src/lib/decoder/interleave.c @@ -0,0 +1,47 @@ +//TODO: this file shouldn't be part of the GSM Receiver +#include +#include +#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/gsm-receiver/src/lib/decoder/interleave.h b/gsm-receiver/src/lib/decoder/interleave.h new file mode 100644 index 0000000..fa1912f --- /dev/null +++ b/gsm-receiver/src/lib/decoder/interleave.h @@ -0,0 +1,19 @@ +//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/gsm-receiver/src/lib/decoder/openbtsstuff/AUTHORS b/gsm-receiver/src/lib/decoder/openbtsstuff/AUTHORS new file mode 100644 index 0000000..8075492 --- /dev/null +++ b/gsm-receiver/src/lib/decoder/openbtsstuff/AUTHORS @@ -0,0 +1,173 @@ +# +# 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/gsm-receiver/src/lib/decoder/openbtsstuff/Assert.h b/gsm-receiver/src/lib/decoder/openbtsstuff/Assert.h new file mode 100644 index 0000000..00ad07d --- /dev/null +++ b/gsm-receiver/src/lib/decoder/openbtsstuff/Assert.h @@ -0,0 +1,49 @@ +/* +* 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 . + +*/ + + +#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/gsm-receiver/src/lib/decoder/openbtsstuff/BitVector.cpp b/gsm-receiver/src/lib/decoder/openbtsstuff/BitVector.cpp new file mode 100644 index 0000000..89d8d19 --- /dev/null +++ b/gsm-receiver/src/lib/decoder/openbtsstuff/BitVector.cpp @@ -0,0 +1,513 @@ +/* +* 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 . + +*/ + + + + +#include "BitVector.h" +#include + +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>i; + return sum & 0x01; +} + + + + + + +BitVector::BitVector(const char *valString) + :Vector(strlen(valString)) +{ + uint32_t accum = 0; + for (size_t i=0; i=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=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 (dpiState) << 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>1)&0x01][0]; + } +} + + +void ViterbiR2O4::pruneCandidates() +{ + const vCand* c1 = mCandidates; // 0-prefix + const vCand* c2 = mCandidates + mIStates; // 1-prefix + for (unsigned i=0; i=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; i0.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; i0.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=deferral) *op++ = (minCost.iState >> deferral); + oCount++; + } + } +} + + + + +ostream& operator<<(ostream& os, const SoftVector& sv) +{ + for (size_t i=0; i0.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. + +*/ + + +#ifndef FECVECTORS_H +#define FECVECTORS_H + +#include "Vector.h" +#include + + +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<>(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< { + + + public: + + /**@name Constructors. */ + //@{ + + /**@name Casts of Vector constructors. */ + //@{ + BitVector(char* wData, char* wStart, char* wEnd) + :Vector(wData,wStart,wEnd) + { } + BitVector(size_t len=0):Vector(len) {} + BitVector(const Vector& source):Vector(source) {} + BitVector(Vector& source):Vector(source) {} + BitVector(const Vector& source1, const Vector source2):Vector(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::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 { + + public: + + /** Build a SoftVector of a given length. */ + SoftVector(size_t wSize=0):Vector(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(wData,length) + {} + + SoftVector(float* wData, float* wStart, float* wEnd) + :Vector(wData,wStart,wEnd) + { } + + /** + Casting from a Vector. + Note that this is NOT pass-by-reference. + */ + SoftVector(Vector source) + :Vector(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::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(dp0.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/gsm-receiver/src/lib/decoder/openbtsstuff/GSM610Tables.cpp b/gsm-receiver/src/lib/decoder/openbtsstuff/GSM610Tables.cpp new file mode 100644 index 0000000..38f643f --- /dev/null +++ b/gsm-receiver/src/lib/decoder/openbtsstuff/GSM610Tables.cpp @@ -0,0 +1,492 @@ +/* +* 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 . + +*/ + + + +#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/gsm-receiver/src/lib/decoder/openbtsstuff/GSM610Tables.h b/gsm-receiver/src/lib/decoder/openbtsstuff/GSM610Tables.h new file mode 100644 index 0000000..53a8e1c --- /dev/null +++ b/gsm-receiver/src/lib/decoder/openbtsstuff/GSM610Tables.h @@ -0,0 +1,37 @@ +/* +* 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 . + +*/ + + + +#ifndef GSM610TABLES_H +#define GSM610TABLES_H + + + +namespace GSM { + +/** Table #2 from GSM 05.03 */ +extern unsigned int g610BitOrder[260]; + +} + + +#endif diff --git a/gsm-receiver/src/lib/decoder/openbtsstuff/GSMCommon.cpp b/gsm-receiver/src/lib/decoder/openbtsstuff/GSMCommon.cpp new file mode 100644 index 0000000..0bec812 --- /dev/null +++ b/gsm-receiver/src/lib/decoder/openbtsstuff/GSMCommon.cpp @@ -0,0 +1,315 @@ +/* +* 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 . + +*/ + + +#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='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/gsm-receiver/src/lib/decoder/openbtsstuff/GSMCommon.h b/gsm-receiver/src/lib/decoder/openbtsstuff/GSMCommon.h new file mode 100644 index 0000000..9dc1c95 --- /dev/null +++ b/gsm-receiver/src/lib/decoder/openbtsstuff/GSMCommon.h @@ -0,0 +1,537 @@ +/**@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 . + +*/ + + + +#ifndef GSMCOMMON_H +#define GSMCOMMON_H + +#include +#include +#include +#include + +#include +#include +#include + + + + +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(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/gsm-receiver/src/lib/decoder/openbtsstuff/GSML1FEC.cpp b/gsm-receiver/src/lib/decoder/openbtsstuff/GSML1FEC.cpp new file mode 100644 index 0000000..1c99a0f --- /dev/null +++ b/gsm-receiver/src/lib/decoder/openbtsstuff/GSML1FEC.cpp @@ -0,0 +1,256 @@ +/* +* 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 . + +*/ + + +#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="< + + + +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 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/gsm-receiver/src/lib/decoder/openbtsstuff/GSMTDMA.cpp b/gsm-receiver/src/lib/decoder/openbtsstuff/GSMTDMA.cpp new file mode 100644 index 0000000..27ebe0e --- /dev/null +++ b/gsm-receiver/src/lib/decoder/openbtsstuff/GSMTDMA.cpp @@ -0,0 +1,337 @@ +/* +* 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 . + +*/ + + +#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. + +*/ + + + +#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<. + +*/ + + + + +#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/gsm-receiver/src/lib/decoder/openbtsstuff/Threads.h b/gsm-receiver/src/lib/decoder/openbtsstuff/Threads.h new file mode 100644 index 0000000..14cff04 --- /dev/null +++ b/gsm-receiver/src/lib/decoder/openbtsstuff/Threads.h @@ -0,0 +1,150 @@ +/* +* 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 . + +*/ + + +#ifndef THREADS_H +#define THREADS_H + + +#include +#include +#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/gsm-receiver/src/lib/decoder/openbtsstuff/Timeval.cpp b/gsm-receiver/src/lib/decoder/openbtsstuff/Timeval.cpp new file mode 100644 index 0000000..e7590cb --- /dev/null +++ b/gsm-receiver/src/lib/decoder/openbtsstuff/Timeval.cpp @@ -0,0 +1,93 @@ +/* +* 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 . + +*/ + + + +#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/gsm-receiver/src/lib/decoder/openbtsstuff/Timeval.h b/gsm-receiver/src/lib/decoder/openbtsstuff/Timeval.h new file mode 100644 index 0000000..44618bc --- /dev/null +++ b/gsm-receiver/src/lib/decoder/openbtsstuff/Timeval.h @@ -0,0 +1,96 @@ +/* +* 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 . + +*/ + + +#ifndef TIMEVAL_H +#define TIMEVAL_H + +#include "sys/time.h" +#include + + + +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/gsm-receiver/src/lib/decoder/openbtsstuff/Vector.h b/gsm-receiver/src/lib/decoder/openbtsstuff/Vector.h new file mode 100644 index 0000000..cec278a --- /dev/null +++ b/gsm-receiver/src/lib/decoder/openbtsstuff/Vector.h @@ -0,0 +1,257 @@ +/**@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 . + +*/ + + + + +#ifndef VECTOR_H +#define VECTOR_H + +#include +#include +#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 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& 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& other) + :mData(other.mData),mStart(other.mStart),mEnd(other.mEnd) + { other.mData=NULL; } + + /** Build a Vector by copying another. */ + Vector(const Vector& 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& other1, const Vector& 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& other) + { + clear(); + mData=other.mData; + mStart=other.mStart; + mEnd=other.mEnd; + other.mData=NULL; + } + + /** Assign from another Vector, copying. */ + void operator=(const Vector& other) { clone(other); } + + //@} + + + //@{ + + /** Return an alias to a segment of this Vector. */ + Vector segment(size_t start, size_t span) + { + T* wStart = mStart + start; + T* wEnd = wStart + span; + assert(wEnd<=mEnd); + return Vector(NULL,wStart,wEnd); + } + + /** Return an alias to a segment of this Vector. */ + const Vector segment(size_t start, size_t span) const + { + T* wStart = mStart + start; + T* wEnd = wStart + span; + assert(wEnd<=mEnd); + return Vector(NULL,wStart,wEnd); + } + + Vector head(size_t span) { return segment(0,span); } + const Vector head(size_t span) const { return segment(0,span); } + Vector tail(size_t start) { return segment(start,size()-start); } + const Vector 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& 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& other, size_t start=0) const { copyToSegment(other,start,size()); } + + void copyTo(Vector& 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& 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 +std::ostream& operator<<(std::ostream& os, const Vector& v) +{ + for (unsigned i=0; i + */ + +#include +#include +#include +#include +#include +#include + +#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/gsm-receiver/src/lib/decoder/out_pcap.h b/gsm-receiver/src/lib/decoder/out_pcap.h new file mode 100644 index 0000000..5ae5e3c --- /dev/null +++ b/gsm-receiver/src/lib/decoder/out_pcap.h @@ -0,0 +1,9 @@ +#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/gsm-receiver/src/lib/decoder/sch.c b/gsm-receiver/src/lib/decoder/sch.c new file mode 100644 index 0000000..6f141dd --- /dev/null +++ b/gsm-receiver/src/lib/decoder/sch.c @@ -0,0 +1,333 @@ +#include "system.h" +#include +#include +#include +#include +#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/gsm-receiver/src/lib/decoder/sch.h b/gsm-receiver/src/lib/decoder/sch.h new file mode 100644 index 0000000..4d47eb5 --- /dev/null +++ b/gsm-receiver/src/lib/decoder/sch.h @@ -0,0 +1,17 @@ + +#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/gsm-receiver/src/lib/decoder/system.h b/gsm-receiver/src/lib/decoder/system.h new file mode 100644 index 0000000..414730a --- /dev/null +++ b/gsm-receiver/src/lib/decoder/system.h @@ -0,0 +1,11 @@ + +#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/gsm-receiver/src/lib/decoder/tun.c b/gsm-receiver/src/lib/decoder/tun.c new file mode 100644 index 0000000..2abda90 --- /dev/null +++ b/gsm-receiver/src/lib/decoder/tun.c @@ -0,0 +1,125 @@ +// $Id: tun.cc,v 1.2 2007-07-07 16:31:42 jl Exp $ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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/gsm-receiver/src/lib/decoder/tun.h b/gsm-receiver/src/lib/decoder/tun.h new file mode 100644 index 0000000..a7868c4 --- /dev/null +++ b/gsm-receiver/src/lib/decoder/tun.h @@ -0,0 +1,4 @@ +// $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/gsm-receiver/src/lib/gsm.i b/gsm-receiver/src/lib/gsm.i new file mode 100644 index 0000000..3a5c561 --- /dev/null +++ b/gsm-receiver/src/lib/gsm.i @@ -0,0 +1,49 @@ +/* -*- c++ -*- */ +/* + * @file + * @author Piotr Krysik + * @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 +/* #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/gsm-receiver/src/lib/gsm_constants.h b/gsm-receiver/src/lib/gsm_constants.h new file mode 100644 index 0000000..939099d --- /dev/null +++ b/gsm-receiver/src/lib/gsm_constants.h @@ -0,0 +1,150 @@ +#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/gsm-receiver/src/lib/gsm_receiver_cf.cc b/gsm-receiver/src/lib/gsm_receiver_cf.cc new file mode 100644 index 0000000..4742b33 --- /dev/null +++ b/gsm-receiver/src/lib/gsm_receiver_cf.cc @@ -0,0 +1,853 @@ +/* -*- c++ -*- */ +/* + * @file + * @author Piotr Krysik + * @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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#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 list_float; +typedef std::vector vector_float; + +typedef boost::circular_buffer 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 v(20); + std::vector::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/gsm-receiver/src/lib/gsm_receiver_cf.h b/gsm-receiver/src/lib/gsm_receiver_cf.h new file mode 100644 index 0000000..21cb1ff --- /dev/null +++ b/gsm-receiver/src/lib/gsm_receiver_cf.h @@ -0,0 +1,254 @@ +/* -*- c++ -*- */ +/* + * @file + * @author Piotr Krysik + * @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 +#include +#include +#include +#include +#include +#include + +#include //TODO: remember to remove this line in the future! +#include "GSML1FEC.h" //!! +#include //!! +#include //!! +#include //!! + +class gsm_receiver_cf; + +typedef boost::shared_ptr gsm_receiver_cf_sptr; +typedef std::vector 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 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]; /// 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/gsm-receiver/src/lib/gsm_receiver_config.cc b/gsm-receiver/src/lib/gsm_receiver_config.cc new file mode 100644 index 0000000..44344f7 --- /dev/null +++ b/gsm-receiver/src/lib/gsm_receiver_config.cc @@ -0,0 +1,84 @@ +/* -*- c++ -*- */ +/* + * @file + * @author Piotr Krysik + * @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 + +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/gsm-receiver/src/lib/gsm_receiver_config.h b/gsm-receiver/src/lib/gsm_receiver_config.h new file mode 100644 index 0000000..b7ba43a --- /dev/null +++ b/gsm-receiver/src/lib/gsm_receiver_config.h @@ -0,0 +1,164 @@ +/* -*- c++ -*- */ +/* + * @file + * @author Piotr Krysik + * @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 +#include +#include +#include +#include + +class multiframe_configuration +{ + private: + multiframe_type d_type; + std::vector 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/gsm-receiver/src/lib/viterbi_detector.cc b/gsm-receiver/src/lib/viterbi_detector.cc new file mode 100644 index 0000000..f3445cf --- /dev/null +++ b/gsm-receiver/src/lib/viterbi_detector.cc @@ -0,0 +1,554 @@ +/* -*- c++ -*- */ +/* + * @file + * @author Piotr Krysik + * @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 +#include +#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 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 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/gsm-receiver/src/lib/viterbi_detector.h b/gsm-receiver/src/lib/viterbi_detector.h new file mode 100644 index 0000000..0360f83 --- /dev/null +++ b/gsm-receiver/src/lib/viterbi_detector.h @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +/* + * @file + * @author Piotr Krysik + * @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 */ diff --git a/gsm-receiver/src/python/Makefile.am b/gsm-receiver/src/python/Makefile.am new file mode 100644 index 0000000..9a4befd --- /dev/null +++ b/gsm-receiver/src/python/Makefile.am @@ -0,0 +1,24 @@ +# +# Copyright 2004 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., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +include $(top_srcdir)/Makefile.common + +EXTRA_DIST = gsm_findfcch.py gsm_findfcch_usrp.py diff --git a/gsm-receiver/src/python/capture.sh b/gsm-receiver/src/python/capture.sh new file mode 100755 index 0000000..ef205d8 --- /dev/null +++ b/gsm-receiver/src/python/capture.sh @@ -0,0 +1,45 @@ +#! /bin/sh + +if [ $1"x" = x ]; then + echo "./capture.sh [duration==10] [decim==112] [gain==52]" + echo "Example: ./capture.sh 940.4M" + exit 1 +fi +FREQ=$1 + +DURATION=$2 +if [ $2"x" = x ]; then + DURATION=10 +fi +DECIM=$3 +if [ $3"x" = x ]; then + DECIM=112 +fi + +GAIN=$4 +if [ $4"x" = x ]; then + GAIN=52 +fi + + +USRP_PROG=usrp_rx_cfile.py +while :; do + which "$USRP_PROG" + if [ $? -eq 0 ]; then + break + fi + USRP_PROG=/usr/share/gnuradio/usrp/usrp_rx_cfile.py + which "$USRP_PROG" + if [ $? -eq 0 ]; then + break + fi + + echo "ERROR: usrp_rx_cfile.py not found. Make sure it's in your PATH!" + exit 1 +done + +FILE="capture_${FREQ}_${DECIM}.cfile" +samples=`expr 64000000 / $DECIM '*' $DURATION` +echo "Capturing for $DURATION seconds to $FILE ($samples samples)" +$USRP_PROG -g $GAIN -d "$DECIM" -f "$FREQ" -N $samples $FILE + diff --git a/gsm-receiver/src/python/cfile b/gsm-receiver/src/python/cfile new file mode 100644 index 0000000..943e35f Binary files /dev/null and b/gsm-receiver/src/python/cfile differ diff --git a/gsm-receiver/src/python/go.sh b/gsm-receiver/src/python/go.sh new file mode 100755 index 0000000..e0d1290 --- /dev/null +++ b/gsm-receiver/src/python/go.sh @@ -0,0 +1,12 @@ +#! /bin/sh + +#echo "go.sh [decim==112]" + +DECIM=$2 +FILE=$1 + +if [ $DECIM"x" = x ]; then + DECIM=112 +fi + +./gsm_receive.py -d "$DECIM" -I "$FILE" | ../../../gsmdecode/src/gsmdecode -i diff --git a/gsm-receiver/src/python/gsm_receive.py b/gsm-receiver/src/python/gsm_receive.py new file mode 100755 index 0000000..4cfb876 --- /dev/null +++ b/gsm-receiver/src/python/gsm_receive.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python + +from gnuradio import gr, gru, blks2 +#, gsm +from gnuradio.eng_option import eng_option +from optparse import OptionParser +from os import sys + +for extdir in ['../../debug/src/lib','../../debug/src/lib/.libs','../lib','../lib/.libs','../..debug/src/lib/decoder/openbts/SIP']: + if extdir not in sys.path: + sys.path.append(extdir) +import gsm + +class tuner(gr.feval_dd): + def __init__(self, top_block): + gr.feval_dd.__init__(self) + self.top_block = top_block + def eval(self, freq_offet): + self.top_block.set_center_frequency(freq_offet) + return freq_offet + +class synchronizer(gr.feval_dd): + def __init__(self, top_block): + gr.feval_dd.__init__(self) + self.top_block = top_block + + def eval(self, timing_offset): + self.top_block.set_timing(timing_offset) + return freq_offet + +class gsm_receiver_first_blood(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + (options, args) = self._process_options() + self.tuner_callback = tuner(self) + self.synchronizer_callback = synchronizer(self) + self.options = options + self.args = args + self._set_rates() + self.source = self._set_source() + self.filtr = self._set_filter() + self.interpolator = self._set_interpolator() + self.receiver = self._set_receiver() + self.converter = self._set_converter() + self.sink = self._set_sink() + + self.connect(self.source, self.filtr, self.interpolator, self.receiver, self.converter, self.sink) + + def _set_sink(self): + nazwa_pliku_wy = self.options.outputfile + ujscie = gr.file_sink(gr.sizeof_float, nazwa_pliku_wy) + return ujscie + + def _set_source(self): + nazwa_pliku = self.options.inputfile + zrodlo = gr.file_source(gr.sizeof_gr_complex, nazwa_pliku, False) + return zrodlo + + def _set_rates(self): + options = self.options + clock_rate = 64e6 + self.clock_rate = clock_rate + self.input_rate = clock_rate / options.decim + self.gsm_symb_rate = 1625000.0 / 6.0 + self.sps = self.input_rate / self.gsm_symb_rate / self.options.osr + + def _set_filter(self): + filter_cutoff = 145e3 + filter_t_width = 10e3 + offset = 0 +# print "input_rate:", self.input_rate, "sample rate:", self.sps, " filter_cutoff:", filter_cutoff, " filter_t_width:", filter_t_width + filter_taps = gr.firdes.low_pass(1.0, self.input_rate, filter_cutoff, filter_t_width, gr.firdes.WIN_HAMMING) + filtr = gr.freq_xlating_fir_filter_ccf(1, filter_taps, offset, self.input_rate) + return filtr + + def _set_converter(self): + v2s = gr.vector_to_stream(gr.sizeof_float, 142) + return v2s + + def _set_interpolator(self): + interpolator = gr.fractional_interpolator_cc(0, self.sps) + return interpolator + + def _set_receiver(self): + receiver = gsm.receiver_cf(self.tuner_callback, self.synchronizer_callback, self.options.osr, self.options.key.replace(' ', '').lower()) + return receiver + + def _process_options(self): + parser = OptionParser(option_class=eng_option) + parser.add_option("-d", "--decim", type="int", default=128, + help="Set USRP decimation rate to DECIM [default=%default]") + parser.add_option("-r", "--osr", type="int", default=4, + help="Oversampling ratio [default=%default]") + parser.add_option("-I", "--inputfile", type="string", default="cfile", + help="Input filename") + parser.add_option("-O", "--outputfile", type="string", default="cfile2.out", + help="Output filename") + parser.add_option("-k", "--key", type="string", default="2B 08 74 9F DD 0D 9C 00", + help="KC session key") + + (options, args) = parser.parse_args () + return (options, args) + + def set_center_frequency(self, center_freq): + self.filtr.set_center_freq(center_freq) + + def set_timing(self, timing_offset): + pass + +def main(): + try: + gsm_receiver_first_blood().run() + except KeyboardInterrupt: + pass + +if __name__ == '__main__': + main() diff --git a/gsm-receiver/src/python/gsm_receive_usrp.py b/gsm-receiver/src/python/gsm_receive_usrp.py new file mode 100755 index 0000000..a4e9720 --- /dev/null +++ b/gsm-receiver/src/python/gsm_receive_usrp.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python +#this file isn't ready to use now - gsm-receiver lacks realtime processing capability +#there are many underruns of buffer for samples from usrp's, many blocks of samples get lost and +#receiver isn't prepared for this situation too well + +from gnuradio import gr, gru, blks2 +#, gsm +from gnuradio import usrp +from gnuradio.eng_option import eng_option +from optparse import OptionParser +from os import sys + +for extdir in ['../../debug/src/lib','../../debug/src/lib/.libs']: + if extdir not in sys.path: + sys.path.append(extdir) +import gsm + +def pick_subdevice(u): + if u.db[0][0].dbid() >= 0: + return (0, 0) + if u.db[1][0].dbid() >= 0: + return (1, 0) + return (0, 0) + +class tune(gr.feval_dd): + def __init__(self, top_block): + gr.feval_dd.__init__(self) + self.top_block = top_block + # self.center_freq = 0 + def eval(self, freq_offet): + # self.center_freq = self.center_freq - freq_offet + self.top_block.set_frequency(freq_offet) + return freq_offet + +class gsm_receiver_first_blood(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + (options, args) = self._process_options() + self.tune_callback = tune(self) + self.options = options + self.args = args + self._set_rates() + self.source = self._set_source() + self.filtr = self._set_filter() + self.interpolator = self._set_interpolator() + self.receiver = self._set_receiver() + self.converter = self._set_converter() + self.sink = self._set_sink() + + self.connect(self.source, self.filtr, self.interpolator, self.receiver, self.converter, self.sink) + + def _set_sink(self): + nazwa_pliku_wy = self.options.outputfile + ujscie = gr.file_sink(gr.sizeof_float, nazwa_pliku_wy) + return ujscie + + def _set_source(self): + options = self.options + fusb_block_size = gr.prefs().get_long('fusb', 'block_size', 4096) + fusb_nblocks = gr.prefs().get_long('fusb', 'nblocks', 16) + self.usrp = usrp.source_c(decim_rate=options.decim, fusb_block_size=fusb_block_size, fusb_nblocks=fusb_nblocks) + + if options.rx_subdev_spec is None: + options.rx_subdev_spec = pick_subdevice(self.usrp) + + self.usrp.set_mux(usrp.determine_rx_mux_value(self.usrp, options.rx_subdev_spec)) + # determine the daughterboard subdevice + self.subdev = usrp.selected_subdev(self.usrp, options.rx_subdev_spec) + input_rate = self.usrp.adc_freq() / self.usrp.decim_rate() + + # set initial values + if options.gain is None: + # if no gain was specified, use the mid-point in dB + g = self.subdev.gain_range() + options.gain = float(g[0]+g[1])/2 + + r = self.usrp.tune(0, self.subdev, options.freq) + self.subdev.set_gain(options.gain) + return self.usrp + + def _set_rates(self): + options = self.options + clock_rate = 64e6 + self.clock_rate = clock_rate + self.input_rate = clock_rate / options.decim + self.gsm_symb_rate = 1625000.0 / 6.0 + self.sps = self.input_rate / self.gsm_symb_rate / self.options.osr + + def _set_filter(self): + filter_cutoff = 145e3 + filter_t_width = 10e3 + offset = 0 +# print "input_rate:", self.input_rate, "sample rate:", self.sps, " filter_cutoff:", filter_cutoff, " filter_t_width:", filter_t_width + filter_taps = gr.firdes.low_pass(1.0, self.input_rate, filter_cutoff, filter_t_width, gr.firdes.WIN_HAMMING) + filtr = gr.freq_xlating_fir_filter_ccf(1, filter_taps, offset, self.input_rate) + return filtr + + def _set_converter(self): + v2s = gr.vector_to_stream(gr.sizeof_float, 142) + return v2s + + def _set_interpolator(self): + interpolator = gr.fractional_interpolator_cc(0, self.sps) + return interpolator + + def _set_receiver(self): + receiver = gsm.receiver_cf(self.tune_callback, self.options.osr) + return receiver + + def _process_options(self): + parser = OptionParser(option_class=eng_option) + parser.add_option("-d", "--decim", type="int", default=128, + help="Set USRP decimation rate to DECIM [default=%default]") + parser.add_option("-I", "--inputfile", type="string", default="cfile", + help="Input filename") + parser.add_option("-O", "--outputfile", type="string", default="cfile2.out", + help="Output filename") + parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, + help="Select USRP Rx side A or B (default=first one with a daughterboard)") + parser.add_option("-r", "--osr", type="int", default=4, + help="Oversampling ratio [default=%default]") + parser.add_option("-f", "--freq", type="eng_float", default="950.4M", + help="set frequency to FREQ", metavar="FREQ") + parser.add_option("-g", "--gain", type="eng_float", default=None, + help="Set gain in dB (default is midpoint)") + (options, args) = parser.parse_args () + return (options, args) + + def set_frequency(self, center_freq): + self.filtr.set_center_freq(center_freq) + +def main(): + try: + gsm_receiver_first_blood().run() + except KeyboardInterrupt: + pass + +if __name__ == '__main__': + main() + + diff --git a/gsm-receiver/src/python/test.sh b/gsm-receiver/src/python/test.sh new file mode 100755 index 0000000..0a828e9 --- /dev/null +++ b/gsm-receiver/src/python/test.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +./gsm_receive.py -I cfile > receiver-test.out 2> /dev/null +echo " 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b\n 15 06 21 00 01 00 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b" > receiver-comp.out +diff receiver-test.out receiver-comp.out > receiver-test-diff.out +test_result=`cat receiver-test-diff.out` + +rm receiver-test.out receiver-test-diff.out receiver-comp.out + +if [ "x$test_result" = "x" ]; then + echo "Test: passed" + exit 0 +else + echo "Test: failed" + exit 1 +fi diff --git a/py-compile b/py-compile deleted file mode 100755 index d6e900b..0000000 --- a/py-compile +++ /dev/null @@ -1,146 +0,0 @@ -#!/bin/sh -# py-compile - Compile a Python program - -scriptversion=2005-05-14.22 - -# Copyright (C) 2000, 2001, 2003, 2004, 2005 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 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# This file is maintained in Automake, please report -# bugs to or send patches to -# . - -if [ -z "$PYTHON" ]; then - PYTHON=python -fi - -basedir= -destdir= -files= -while test $# -ne 0; do - case "$1" in - --basedir) - basedir=$2 - if test -z "$basedir"; then - echo "$0: Missing argument to --basedir." 1>&2 - exit 1 - fi - shift - ;; - --destdir) - destdir=$2 - if test -z "$destdir"; then - echo "$0: Missing argument to --destdir." 1>&2 - exit 1 - fi - shift - ;; - -h|--h*) - cat <<\EOF -Usage: py-compile [--help] [--version] [--basedir DIR] [--destdir DIR] FILES..." - -Byte compile some python scripts FILES. Use --destdir to specify any -leading directory path to the FILES that you don't want to include in the -byte compiled file. Specify --basedir for any additional path information you -do want to be shown in the byte compiled file. - -Example: - py-compile --destdir /tmp/pkg-root --basedir /usr/share/test test.py test2.py - -Report bugs to . -EOF - exit $? - ;; - -v|--v*) - echo "py-compile $scriptversion" - exit $? - ;; - *) - files="$files $1" - ;; - esac - shift -done - -if test -z "$files"; then - echo "$0: No files given. Try \`$0 --help' for more information." 1>&2 - exit 1 -fi - -# if basedir was given, then it should be prepended to filenames before -# byte compilation. -if [ -z "$basedir" ]; then - pathtrans="path = file" -else - pathtrans="path = os.path.join('$basedir', file)" -fi - -# if destdir was given, then it needs to be prepended to the filename to -# byte compile but not go into the compiled file. -if [ -z "$destdir" ]; then - filetrans="filepath = path" -else - filetrans="filepath = os.path.normpath('$destdir' + os.sep + path)" -fi - -$PYTHON -c " -import sys, os, string, py_compile - -files = '''$files''' - -print 'Byte-compiling python modules...' -for file in string.split(files): - $pathtrans - $filetrans - if not os.path.exists(filepath) or not (len(filepath) >= 3 - and filepath[-3:] == '.py'): - continue - print file, - sys.stdout.flush() - py_compile.compile(filepath, filepath + 'c', path) -print" || exit $? - -# this will fail for python < 1.5, but that doesn't matter ... -$PYTHON -O -c " -import sys, os, string, py_compile - -files = '''$files''' -print 'Byte-compiling python modules (optimized versions) ...' -for file in string.split(files): - $pathtrans - $filetrans - if not os.path.exists(filepath) or not (len(filepath) >= 3 - and filepath[-3:] == '.py'): - continue - print file, - sys.stdout.flush() - py_compile.compile(filepath, filepath + 'o', path) -print" 2>/dev/null || : - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" -# End: diff --git a/src/Makefile.am b/src/Makefile.am deleted file mode 100644 index 79cfa3e..0000000 --- a/src/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright 2004 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. -# - -SUBDIRS = lib python - 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 . - -*/ - - -#ifndef ASSERT_H -#define ASSERT_H - -#include "stdio.h" -#include - -#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 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 - * Voice: +1 (925) 798-4042 - * - */ - - -#include - - -/* 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 - -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 -#include -#include -#include -#include - -//#include -//#include -#include -//#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 -#include - -#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 -#include -#include -#include -#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 -#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 - -#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 -#include -#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 . - -*/ - - -#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 . - -*/ - - - - -#include "BitVector.h" -#include - -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>i; - return sum & 0x01; -} - - - - - - -BitVector::BitVector(const char *valString) - :Vector(strlen(valString)) -{ - uint32_t accum = 0; - for (size_t i=0; i=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=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 (dpiState) << 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>1)&0x01][0]; - } -} - - -void ViterbiR2O4::pruneCandidates() -{ - const vCand* c1 = mCandidates; // 0-prefix - const vCand* c2 = mCandidates + mIStates; // 1-prefix - for (unsigned i=0; i=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; i0.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; i0.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=deferral) *op++ = (minCost.iState >> deferral); - oCount++; - } - } -} - - - - -ostream& operator<<(ostream& os, const SoftVector& sv) -{ - for (size_t i=0; i0.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. - -*/ - - -#ifndef FECVECTORS_H -#define FECVECTORS_H - -#include "Vector.h" -#include - - -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<>(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< { - - - public: - - /**@name Constructors. */ - //@{ - - /**@name Casts of Vector constructors. */ - //@{ - BitVector(char* wData, char* wStart, char* wEnd) - :Vector(wData,wStart,wEnd) - { } - BitVector(size_t len=0):Vector(len) {} - BitVector(const Vector& source):Vector(source) {} - BitVector(Vector& source):Vector(source) {} - BitVector(const Vector& source1, const Vector source2):Vector(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::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 { - - public: - - /** Build a SoftVector of a given length. */ - SoftVector(size_t wSize=0):Vector(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(wData,length) - {} - - SoftVector(float* wData, float* wStart, float* wEnd) - :Vector(wData,wStart,wEnd) - { } - - /** - Casting from a Vector. - Note that this is NOT pass-by-reference. - */ - SoftVector(Vector source) - :Vector(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::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(dp0.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 . - -*/ - - - -#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 . - -*/ - - - -#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 . - -*/ - - -#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='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 . - -*/ - - - -#ifndef GSMCOMMON_H -#define GSMCOMMON_H - -#include -#include -#include -#include - -#include -#include -#include - - - - -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(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 . - -*/ - - -#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="< - - - -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 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 . - -*/ - - -#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. - -*/ - - - -#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<. - -*/ - - - - -#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 . - -*/ - - -#ifndef THREADS_H -#define THREADS_H - - -#include -#include -#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 . - -*/ - - - -#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 . - -*/ - - -#ifndef TIMEVAL_H -#define TIMEVAL_H - -#include "sys/time.h" -#include - - - -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 . - -*/ - - - - -#ifndef VECTOR_H -#define VECTOR_H - -#include -#include -#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 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& 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& other) - :mData(other.mData),mStart(other.mStart),mEnd(other.mEnd) - { other.mData=NULL; } - - /** Build a Vector by copying another. */ - Vector(const Vector& 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& other1, const Vector& 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& other) - { - clear(); - mData=other.mData; - mStart=other.mStart; - mEnd=other.mEnd; - other.mData=NULL; - } - - /** Assign from another Vector, copying. */ - void operator=(const Vector& other) { clone(other); } - - //@} - - - //@{ - - /** Return an alias to a segment of this Vector. */ - Vector segment(size_t start, size_t span) - { - T* wStart = mStart + start; - T* wEnd = wStart + span; - assert(wEnd<=mEnd); - return Vector(NULL,wStart,wEnd); - } - - /** Return an alias to a segment of this Vector. */ - const Vector segment(size_t start, size_t span) const - { - T* wStart = mStart + start; - T* wEnd = wStart + span; - assert(wEnd<=mEnd); - return Vector(NULL,wStart,wEnd); - } - - Vector head(size_t span) { return segment(0,span); } - const Vector head(size_t span) const { return segment(0,span); } - Vector tail(size_t start) { return segment(start,size()-start); } - const Vector 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& 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& other, size_t start=0) const { copyToSegment(other,start,size()); } - - void copyTo(Vector& 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& 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 -std::ostream& operator<<(std::ostream& os, const Vector& v) -{ - for (unsigned i=0; i - */ - -#include -#include -#include -#include -#include -#include - -#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 -#include -#include -#include -#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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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 - * @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 -/* #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 - * @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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#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 list_float; -typedef std::vector vector_float; - -typedef boost::circular_buffer 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 v(20); - std::vector::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 - * @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 -#include -#include -#include -#include -#include -#include - -#include //TODO: remember to remove this line in the future! -#include "GSML1FEC.h" //!! -#include //!! -#include //!! -#include //!! - -class gsm_receiver_cf; - -typedef boost::shared_ptr gsm_receiver_cf_sptr; -typedef std::vector 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 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]; /// 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 - * @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 - -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 - * @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 -#include -#include -#include -#include - -class multiframe_configuration -{ - private: - multiframe_type d_type; - std::vector 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 - * @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 -#include -#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 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 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 - * @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 */ diff --git a/src/python/Makefile.am b/src/python/Makefile.am deleted file mode 100644 index 9a4befd..0000000 --- a/src/python/Makefile.am +++ /dev/null @@ -1,24 +0,0 @@ -# -# Copyright 2004 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., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -include $(top_srcdir)/Makefile.common - -EXTRA_DIST = gsm_findfcch.py gsm_findfcch_usrp.py diff --git a/src/python/capture.sh b/src/python/capture.sh deleted file mode 100755 index ef205d8..0000000 --- a/src/python/capture.sh +++ /dev/null @@ -1,45 +0,0 @@ -#! /bin/sh - -if [ $1"x" = x ]; then - echo "./capture.sh [duration==10] [decim==112] [gain==52]" - echo "Example: ./capture.sh 940.4M" - exit 1 -fi -FREQ=$1 - -DURATION=$2 -if [ $2"x" = x ]; then - DURATION=10 -fi -DECIM=$3 -if [ $3"x" = x ]; then - DECIM=112 -fi - -GAIN=$4 -if [ $4"x" = x ]; then - GAIN=52 -fi - - -USRP_PROG=usrp_rx_cfile.py -while :; do - which "$USRP_PROG" - if [ $? -eq 0 ]; then - break - fi - USRP_PROG=/usr/share/gnuradio/usrp/usrp_rx_cfile.py - which "$USRP_PROG" - if [ $? -eq 0 ]; then - break - fi - - echo "ERROR: usrp_rx_cfile.py not found. Make sure it's in your PATH!" - exit 1 -done - -FILE="capture_${FREQ}_${DECIM}.cfile" -samples=`expr 64000000 / $DECIM '*' $DURATION` -echo "Capturing for $DURATION seconds to $FILE ($samples samples)" -$USRP_PROG -g $GAIN -d "$DECIM" -f "$FREQ" -N $samples $FILE - diff --git a/src/python/cfile b/src/python/cfile deleted file mode 100644 index 943e35f..0000000 Binary files a/src/python/cfile and /dev/null differ diff --git a/src/python/go.sh b/src/python/go.sh deleted file mode 100755 index e0d1290..0000000 --- a/src/python/go.sh +++ /dev/null @@ -1,12 +0,0 @@ -#! /bin/sh - -#echo "go.sh [decim==112]" - -DECIM=$2 -FILE=$1 - -if [ $DECIM"x" = x ]; then - DECIM=112 -fi - -./gsm_receive.py -d "$DECIM" -I "$FILE" | ../../../gsmdecode/src/gsmdecode -i diff --git a/src/python/gsm_receive.py b/src/python/gsm_receive.py deleted file mode 100755 index 4cfb876..0000000 --- a/src/python/gsm_receive.py +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env python - -from gnuradio import gr, gru, blks2 -#, gsm -from gnuradio.eng_option import eng_option -from optparse import OptionParser -from os import sys - -for extdir in ['../../debug/src/lib','../../debug/src/lib/.libs','../lib','../lib/.libs','../..debug/src/lib/decoder/openbts/SIP']: - if extdir not in sys.path: - sys.path.append(extdir) -import gsm - -class tuner(gr.feval_dd): - def __init__(self, top_block): - gr.feval_dd.__init__(self) - self.top_block = top_block - def eval(self, freq_offet): - self.top_block.set_center_frequency(freq_offet) - return freq_offet - -class synchronizer(gr.feval_dd): - def __init__(self, top_block): - gr.feval_dd.__init__(self) - self.top_block = top_block - - def eval(self, timing_offset): - self.top_block.set_timing(timing_offset) - return freq_offet - -class gsm_receiver_first_blood(gr.top_block): - def __init__(self): - gr.top_block.__init__(self) - (options, args) = self._process_options() - self.tuner_callback = tuner(self) - self.synchronizer_callback = synchronizer(self) - self.options = options - self.args = args - self._set_rates() - self.source = self._set_source() - self.filtr = self._set_filter() - self.interpolator = self._set_interpolator() - self.receiver = self._set_receiver() - self.converter = self._set_converter() - self.sink = self._set_sink() - - self.connect(self.source, self.filtr, self.interpolator, self.receiver, self.converter, self.sink) - - def _set_sink(self): - nazwa_pliku_wy = self.options.outputfile - ujscie = gr.file_sink(gr.sizeof_float, nazwa_pliku_wy) - return ujscie - - def _set_source(self): - nazwa_pliku = self.options.inputfile - zrodlo = gr.file_source(gr.sizeof_gr_complex, nazwa_pliku, False) - return zrodlo - - def _set_rates(self): - options = self.options - clock_rate = 64e6 - self.clock_rate = clock_rate - self.input_rate = clock_rate / options.decim - self.gsm_symb_rate = 1625000.0 / 6.0 - self.sps = self.input_rate / self.gsm_symb_rate / self.options.osr - - def _set_filter(self): - filter_cutoff = 145e3 - filter_t_width = 10e3 - offset = 0 -# print "input_rate:", self.input_rate, "sample rate:", self.sps, " filter_cutoff:", filter_cutoff, " filter_t_width:", filter_t_width - filter_taps = gr.firdes.low_pass(1.0, self.input_rate, filter_cutoff, filter_t_width, gr.firdes.WIN_HAMMING) - filtr = gr.freq_xlating_fir_filter_ccf(1, filter_taps, offset, self.input_rate) - return filtr - - def _set_converter(self): - v2s = gr.vector_to_stream(gr.sizeof_float, 142) - return v2s - - def _set_interpolator(self): - interpolator = gr.fractional_interpolator_cc(0, self.sps) - return interpolator - - def _set_receiver(self): - receiver = gsm.receiver_cf(self.tuner_callback, self.synchronizer_callback, self.options.osr, self.options.key.replace(' ', '').lower()) - return receiver - - def _process_options(self): - parser = OptionParser(option_class=eng_option) - parser.add_option("-d", "--decim", type="int", default=128, - help="Set USRP decimation rate to DECIM [default=%default]") - parser.add_option("-r", "--osr", type="int", default=4, - help="Oversampling ratio [default=%default]") - parser.add_option("-I", "--inputfile", type="string", default="cfile", - help="Input filename") - parser.add_option("-O", "--outputfile", type="string", default="cfile2.out", - help="Output filename") - parser.add_option("-k", "--key", type="string", default="2B 08 74 9F DD 0D 9C 00", - help="KC session key") - - (options, args) = parser.parse_args () - return (options, args) - - def set_center_frequency(self, center_freq): - self.filtr.set_center_freq(center_freq) - - def set_timing(self, timing_offset): - pass - -def main(): - try: - gsm_receiver_first_blood().run() - except KeyboardInterrupt: - pass - -if __name__ == '__main__': - main() diff --git a/src/python/gsm_receive_usrp.py b/src/python/gsm_receive_usrp.py deleted file mode 100755 index a4e9720..0000000 --- a/src/python/gsm_receive_usrp.py +++ /dev/null @@ -1,141 +0,0 @@ -#!/usr/bin/env python -#this file isn't ready to use now - gsm-receiver lacks realtime processing capability -#there are many underruns of buffer for samples from usrp's, many blocks of samples get lost and -#receiver isn't prepared for this situation too well - -from gnuradio import gr, gru, blks2 -#, gsm -from gnuradio import usrp -from gnuradio.eng_option import eng_option -from optparse import OptionParser -from os import sys - -for extdir in ['../../debug/src/lib','../../debug/src/lib/.libs']: - if extdir not in sys.path: - sys.path.append(extdir) -import gsm - -def pick_subdevice(u): - if u.db[0][0].dbid() >= 0: - return (0, 0) - if u.db[1][0].dbid() >= 0: - return (1, 0) - return (0, 0) - -class tune(gr.feval_dd): - def __init__(self, top_block): - gr.feval_dd.__init__(self) - self.top_block = top_block - # self.center_freq = 0 - def eval(self, freq_offet): - # self.center_freq = self.center_freq - freq_offet - self.top_block.set_frequency(freq_offet) - return freq_offet - -class gsm_receiver_first_blood(gr.top_block): - def __init__(self): - gr.top_block.__init__(self) - (options, args) = self._process_options() - self.tune_callback = tune(self) - self.options = options - self.args = args - self._set_rates() - self.source = self._set_source() - self.filtr = self._set_filter() - self.interpolator = self._set_interpolator() - self.receiver = self._set_receiver() - self.converter = self._set_converter() - self.sink = self._set_sink() - - self.connect(self.source, self.filtr, self.interpolator, self.receiver, self.converter, self.sink) - - def _set_sink(self): - nazwa_pliku_wy = self.options.outputfile - ujscie = gr.file_sink(gr.sizeof_float, nazwa_pliku_wy) - return ujscie - - def _set_source(self): - options = self.options - fusb_block_size = gr.prefs().get_long('fusb', 'block_size', 4096) - fusb_nblocks = gr.prefs().get_long('fusb', 'nblocks', 16) - self.usrp = usrp.source_c(decim_rate=options.decim, fusb_block_size=fusb_block_size, fusb_nblocks=fusb_nblocks) - - if options.rx_subdev_spec is None: - options.rx_subdev_spec = pick_subdevice(self.usrp) - - self.usrp.set_mux(usrp.determine_rx_mux_value(self.usrp, options.rx_subdev_spec)) - # determine the daughterboard subdevice - self.subdev = usrp.selected_subdev(self.usrp, options.rx_subdev_spec) - input_rate = self.usrp.adc_freq() / self.usrp.decim_rate() - - # set initial values - if options.gain is None: - # if no gain was specified, use the mid-point in dB - g = self.subdev.gain_range() - options.gain = float(g[0]+g[1])/2 - - r = self.usrp.tune(0, self.subdev, options.freq) - self.subdev.set_gain(options.gain) - return self.usrp - - def _set_rates(self): - options = self.options - clock_rate = 64e6 - self.clock_rate = clock_rate - self.input_rate = clock_rate / options.decim - self.gsm_symb_rate = 1625000.0 / 6.0 - self.sps = self.input_rate / self.gsm_symb_rate / self.options.osr - - def _set_filter(self): - filter_cutoff = 145e3 - filter_t_width = 10e3 - offset = 0 -# print "input_rate:", self.input_rate, "sample rate:", self.sps, " filter_cutoff:", filter_cutoff, " filter_t_width:", filter_t_width - filter_taps = gr.firdes.low_pass(1.0, self.input_rate, filter_cutoff, filter_t_width, gr.firdes.WIN_HAMMING) - filtr = gr.freq_xlating_fir_filter_ccf(1, filter_taps, offset, self.input_rate) - return filtr - - def _set_converter(self): - v2s = gr.vector_to_stream(gr.sizeof_float, 142) - return v2s - - def _set_interpolator(self): - interpolator = gr.fractional_interpolator_cc(0, self.sps) - return interpolator - - def _set_receiver(self): - receiver = gsm.receiver_cf(self.tune_callback, self.options.osr) - return receiver - - def _process_options(self): - parser = OptionParser(option_class=eng_option) - parser.add_option("-d", "--decim", type="int", default=128, - help="Set USRP decimation rate to DECIM [default=%default]") - parser.add_option("-I", "--inputfile", type="string", default="cfile", - help="Input filename") - parser.add_option("-O", "--outputfile", type="string", default="cfile2.out", - help="Output filename") - parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, - help="Select USRP Rx side A or B (default=first one with a daughterboard)") - parser.add_option("-r", "--osr", type="int", default=4, - help="Oversampling ratio [default=%default]") - parser.add_option("-f", "--freq", type="eng_float", default="950.4M", - help="set frequency to FREQ", metavar="FREQ") - parser.add_option("-g", "--gain", type="eng_float", default=None, - help="Set gain in dB (default is midpoint)") - (options, args) = parser.parse_args () - return (options, args) - - def set_frequency(self, center_freq): - self.filtr.set_center_freq(center_freq) - -def main(): - try: - gsm_receiver_first_blood().run() - except KeyboardInterrupt: - pass - -if __name__ == '__main__': - main() - - diff --git a/src/python/test.sh b/src/python/test.sh deleted file mode 100755 index 0a828e9..0000000 --- a/src/python/test.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -./gsm_receive.py -I cfile > receiver-test.out 2> /dev/null -echo " 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b\n 15 06 21 00 01 00 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b" > receiver-comp.out -diff receiver-test.out receiver-comp.out > receiver-test-diff.out -test_result=`cat receiver-test-diff.out` - -rm receiver-test.out receiver-test-diff.out receiver-comp.out - -if [ "x$test_result" = "x" ]; then - echo "Test: passed" - exit 0 -else - echo "Test: failed" - exit 1 -fi -- cgit v1.2.3