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