From dbc3a50c313906cba0c2536b934f6a563adabe67 Mon Sep 17 00:00:00 2001 From: Roman Khassraf Date: Mon, 3 Aug 2015 23:20:20 +0200 Subject: [PATCH 1/4] Implemented burst timeslot splitter for flow control. Issue #100 --- grc/CMakeLists.txt | 1 + grc/flow_control/CMakeLists.txt | 22 +++ .../gsm_burst_timeslot_splitter.xml | 24 +++ grc/gsm_block_tree.xml | 4 + include/grgsm/CMakeLists.txt | 2 +- include/grgsm/flow_control/CMakeLists.txt | 25 +++ .../flow_control/burst_timeslot_splitter.h | 55 ++++++ lib/CMakeLists.txt | 1 + .../burst_timeslot_splitter_impl.cc | 114 +++++++++++++ .../burst_timeslot_splitter_impl.h | 43 +++++ python/CMakeLists.txt | 3 +- python/qa_burst_timeslot_splitter.py | 161 ++++++++++++++++++ swig/grgsm_swig.i | 5 +- 13 files changed, 456 insertions(+), 4 deletions(-) create mode 100644 grc/flow_control/CMakeLists.txt create mode 100644 grc/flow_control/gsm_burst_timeslot_splitter.xml create mode 100644 include/grgsm/flow_control/CMakeLists.txt create mode 100644 include/grgsm/flow_control/burst_timeslot_splitter.h create mode 100644 lib/flow_control/burst_timeslot_splitter_impl.cc create mode 100644 lib/flow_control/burst_timeslot_splitter_impl.h create mode 100755 python/qa_burst_timeslot_splitter.py diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt index caf2660..4665e89 100644 --- a/grc/CMakeLists.txt +++ b/grc/CMakeLists.txt @@ -21,6 +21,7 @@ add_subdirectory(decoding) add_subdirectory(decryption) add_subdirectory(demapping) add_subdirectory(receiver) +add_subdirectory(flow_control) add_subdirectory(misc_utils) install(FILES gsm_block_tree.xml diff --git a/grc/flow_control/CMakeLists.txt b/grc/flow_control/CMakeLists.txt new file mode 100644 index 0000000..c11943f --- /dev/null +++ b/grc/flow_control/CMakeLists.txt @@ -0,0 +1,22 @@ +# Copyright 2011,2012 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. + +install(FILES + gsm_burst_timeslot_splitter.xml DESTINATION share/gnuradio/grc/blocks +) diff --git a/grc/flow_control/gsm_burst_timeslot_splitter.xml b/grc/flow_control/gsm_burst_timeslot_splitter.xml new file mode 100644 index 0000000..91db4db --- /dev/null +++ b/grc/flow_control/gsm_burst_timeslot_splitter.xml @@ -0,0 +1,24 @@ + + + Burst timeslot splitter + gsm_burst_timeslot_splitter + import grgsm + grgsm.burst_timeslot_splitter() + + + in + message + + + + out + message + 8 + 1 + + + +Burst timeslot splitter distributes bursts to eight different output ports depending on the timeslots of the bursts. +This means timeslot 0 bursts are sent to port out0, timeslot 1 bursts on port out1, and so on. + + diff --git a/grc/gsm_block_tree.xml b/grc/gsm_block_tree.xml index 2503710..1679ad1 100644 --- a/grc/gsm_block_tree.xml +++ b/grc/gsm_block_tree.xml @@ -37,6 +37,10 @@ gsm_control_channels_decoder gsm_tch_f_decoder + + Flow control + gsm_burst_timeslot_splitter + Utilities gsm_bursts_printer diff --git a/include/grgsm/CMakeLists.txt b/include/grgsm/CMakeLists.txt index fd44c54..385572a 100644 --- a/include/grgsm/CMakeLists.txt +++ b/include/grgsm/CMakeLists.txt @@ -32,4 +32,4 @@ add_subdirectory(decryption) add_subdirectory(demapping) add_subdirectory(receiver) add_subdirectory(misc_utils) - +add_subdirectory(flow_control) diff --git a/include/grgsm/flow_control/CMakeLists.txt b/include/grgsm/flow_control/CMakeLists.txt new file mode 100644 index 0000000..e701592 --- /dev/null +++ b/include/grgsm/flow_control/CMakeLists.txt @@ -0,0 +1,25 @@ +# Copyright 2011,2012 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. + +######################################################################## +# Install public header files +######################################################################## +install(FILES + burst_timeslot_splitter.h DESTINATION include/grgsm/flow_control +) diff --git a/include/grgsm/flow_control/burst_timeslot_splitter.h b/include/grgsm/flow_control/burst_timeslot_splitter.h new file mode 100644 index 0000000..ee6298e --- /dev/null +++ b/include/grgsm/flow_control/burst_timeslot_splitter.h @@ -0,0 +1,55 @@ +/* -*- c++ -*- */ +/* @file + * @author Roman Khassraf + * @section LICENSE + * + * Gr-gsm 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. + * + * Gr-gsm 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 gr-gsm; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef INCLUDED_GSM_BURST_TIMESLOT_SPLITTER_H +#define INCLUDED_GSM_BURST_TIMESLOT_SPLITTER_H + +#include +#include + +namespace gr { + namespace gsm { + + /*! + * \brief <+description of block+> + * \ingroup gsm + * + */ + class GSM_API burst_timeslot_splitter : virtual public gr::block + { + public: + typedef boost::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of grgsm::burst_timeslot_splitter. + * + * To avoid accidental use of raw pointers, grgsm::burst_timeslot_splitter's + * constructor is in a private implementation + * class. grgsm::burst_timeslot_splitter::make is the public interface for + * creating new instances. + */ + static sptr make(); + }; + } // namespace gsm +} // namespace gr + +#endif /* INCLUDED_GSM_BURST_TIMESLOT_SPLITTER_H */ diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 61f0858..4a61f0b 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -46,6 +46,7 @@ list(APPEND grgsm_sources decoding/GSM660Tables.cpp decoding/GSM503Tables.cpp decoding/ViterbiR204.cpp + flow_control/burst_timeslot_splitter_impl.cc misc_utils/controlled_rotator_cc_impl.cc misc_utils/controlled_const_source_f_impl.cc misc_utils/message_printer_impl.cc diff --git a/lib/flow_control/burst_timeslot_splitter_impl.cc b/lib/flow_control/burst_timeslot_splitter_impl.cc new file mode 100644 index 0000000..99964b7 --- /dev/null +++ b/lib/flow_control/burst_timeslot_splitter_impl.cc @@ -0,0 +1,114 @@ +/* -*- c++ -*- */ +/* @file + * @author Roman Khassraf + * @section LICENSE + * + * Gr-gsm 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. + * + * Gr-gsm 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 gr-gsm; 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 "burst_timeslot_splitter_impl.h" +#include +#include +#include + + +namespace gr { + namespace gsm { + + burst_timeslot_splitter::sptr + burst_timeslot_splitter::make() + { + return gnuradio::get_initial_sptr + (new burst_timeslot_splitter_impl()); + } + + /* + * The private constructor + */ + burst_timeslot_splitter_impl::burst_timeslot_splitter_impl() + : gr::block("burst_timeslot_splitter", + gr::io_signature::make(0, 0, 0), + gr::io_signature::make(0, 0, 0)) + { + message_port_register_in(pmt::mp("in")); + + message_port_register_out(pmt::mp("out0")); + message_port_register_out(pmt::mp("out1")); + message_port_register_out(pmt::mp("out2")); + message_port_register_out(pmt::mp("out3")); + message_port_register_out(pmt::mp("out4")); + message_port_register_out(pmt::mp("out5")); + message_port_register_out(pmt::mp("out6")); + message_port_register_out(pmt::mp("out7")); + + set_msg_handler(pmt::mp("in"), boost::bind(&burst_timeslot_splitter_impl::process_burst, this, _1)); + } + + /* + * Our virtual destructor. + */ + burst_timeslot_splitter_impl::~burst_timeslot_splitter_impl() {} + + void burst_timeslot_splitter_impl::process_burst(pmt::pmt_t msg) + { + pmt::pmt_t header_plus_burst = pmt::cdr(msg); + gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(header_plus_burst); + + unsigned int timeslot = header->timeslot; + + std::string port("out"); + + switch (timeslot) + { + case 0: + port.append("0"); + break; + case 1: + port.append("1"); + break; + case 2: + port.append("2"); + break; + case 3: + port.append("3"); + break; + case 4: + port.append("4"); + break; + case 5: + port.append("5"); + break; + case 6: + port.append("6"); + break; + case 7: + port.append("7"); + break; + default: + port.append("0"); + break; + } + + message_port_pub(pmt::mp(port), msg); + } + } /* namespace gsm */ +} /* namespace gr */ diff --git a/lib/flow_control/burst_timeslot_splitter_impl.h b/lib/flow_control/burst_timeslot_splitter_impl.h new file mode 100644 index 0000000..47a9115 --- /dev/null +++ b/lib/flow_control/burst_timeslot_splitter_impl.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- */ +/* @file + * @author Roman Khassraf + * @section LICENSE + * + * Gr-gsm 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. + * + * Gr-gsm 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 gr-gsm; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef INCLUDED_GSM_BURST_TIMESLOT_SPLITTER_IMPL_H +#define INCLUDED_GSM_BURST_TIMESLOT_SPLITTER_IMPL_H + +#include + +namespace gr { + namespace gsm { + + class burst_timeslot_splitter_impl : public burst_timeslot_splitter + { + public: + burst_timeslot_splitter_impl(); + ~burst_timeslot_splitter_impl(); + void process_burst(pmt::pmt_t msg); + }; + + } // namespace gsm +} // namespace gr + +#endif /* INCLUDED_GSM_BURST_TIMESLOT_SPLITTER_IMPL_H */ + diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index cb4b2b2..f84c458 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -47,5 +47,4 @@ include(GrTest) set(GR_TEST_TARGET_DEPS gr-gsm) set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/swig) GR_ADD_TEST(qa_decryption ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_decryption.py) -#GR_ADD_TEST(qa_receiver ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_receiver.py) -#GR_ADD_TEST(qa_receiver_hier ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_receiver_hier.py) +GR_ADD_TEST(qa_burst_timeslot_splitter ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_burst_timeslot_splitter.py) diff --git a/python/qa_burst_timeslot_splitter.py b/python/qa_burst_timeslot_splitter.py new file mode 100755 index 0000000..8be3e52 --- /dev/null +++ b/python/qa_burst_timeslot_splitter.py @@ -0,0 +1,161 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @file +# @author Roman Khassraf +# @section LICENSE +# +# Gr-gsm 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. +# +# Gr-gsm 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 gr-gsm; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# +# + +from gnuradio import gr, gr_unittest, blocks +import grgsm +import pmt + +class qa_burst_timeslot_splitter (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_001 (self): + """ + 24 random framenumbers, timeslots and bursts as input + """ + framenumbers_input = [1259192, 1076346, 1076242, 235879, 1259218, 2194302, 2714322, 1588, 1259244, 1563637, 1435624, 1928543, 503726, 1571144, 2658397, 1807445, 869789, 624070, 2005511, 1306953, 2284894, 1600339, 551375, 1259270] + timeslots_input = [6, 3, 4, 3, 5, 3, 2, 7, 1, 6, 0, 7, 2, 3, 2, 0, 7, 1, 0, 6, 0, 6, 5, 7] + bursts_input = [ + "0001100001000111100111101111100101000100101011000010011110011101001111101100010100111111100000110100011111101011101100100111110011000100010001010000", + "0001000101000000001001111110000110010110110111110111101000001101001111101100010100111111001110001001110101110001010001000111011010010001011011000000", + "0001001101101101000111001000101011001101001110110001001100111101001111101100010100111111111001001010011010011111010010010101011001001011011100110000", + "0000010010100000001001101010100001011100010001101100111111101101001111101100010100111111101101001110100010101110010110101111100010010000110010110000", + "0000010101010110010011110101010101101100000000001000100100101010000111011101001000011101011101110000101011001111000100001000000000001110010001111000", + "0001000000000010111010100000010101000010001010111010000000011010000111011101001000011101000000100010111110101000000001000000000010111010100000000000", + "0001010101111111111010000001010101011111111111101000000001001010000111011101001000011101010111111111111010101000000001010101011011101010000001000000", + "0000000000111110101010100001000000100010101110101010000101001010000111011101001000011101001010001111101010001000010000000000101110101010100000010000", + "0000010000000010000001001000011001010010000011000101000000001010000111011101001000011101010100100000000001001000001000000100100011000101001000111000", + "0001010100110111100000110111100110010100011100011000110110001010000111011101001000011101011111111001111001101010010100000000011111001101000111110000", + "0001100110000001011110001000001100101001010100111111000100111010000111011101001000011101000011010010001010111101000100110011111010100010010101000000", + "0000010101100101010110000011010000000000000010111001110110101010000111011101001000011101000001000100100001111001100011000101010001110001010100111000", + "0001000100000011001010111001111100011010000000000000001001001010000111011101001000011101010110000101111010011001110110001001011010101000011110110000", + "0001100001000111111111100001011000000011010110111010110000111010000111011101001000011101100010111100100101110001101000110100110000001010101110011000", + "0000000100111011000000000010100100001100101010000000010010101010000111011101001000011101000110110001110110000100110100110110011001100100000101100000", + "0000100101111010011110111010100111010100011011011101100111001010000111011101001000011101010000111010000110100000001000010011101011001001110100011000", + "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000", + "0000110101000011011010110000110011010000000001001010110010001010000111011101001000011101010000011000111001101110000000110010100001101110101000100000", + "0000001000010001011111111111101010100000010101011101101010101010000111011101001000011101100010010101010101011110101010101000010001011101111010101000", + "0000101110101111011001011001000011110010100010011100110010001010000111011101001000011101100000001110000100010100110111001001100010101101100010101000", + "0001100010000001000111011100101101101010100001111101001000101010000111011101001000011101111010000011010110010111011111010010001000001101100011111000", + "0001011101101101011100001111001100010001000011011001101110011010000111011101001000011101010010111011100111000001011100100001111010100101111000100000", + "0000001000100011000000000000110100000000010000001010100100001010000111011101001000011101000010010000000000001001000001011000000001010000000100010000", + "0000100000110001000000000100000110001011100001001000000000001010000111011101001000011101001010010001010000000111010000000011000001000000000101010000" + ] + + bursts_expected_0 = [ + "0001100110000001011110001000001100101001010100111111000100111010000111011101001000011101000011010010001010111101000100110011111010100010010101000000", + "0000100101111010011110111010100111010100011011011101100111001010000111011101001000011101010000111010000110100000001000010011101011001001110100011000", + "0000001000010001011111111111101010100000010101011101101010101010000111011101001000011101100010010101010101011110101010101000010001011101111010101000", + "0001100010000001000111011100101101101010100001111101001000101010000111011101001000011101111010000011010110010111011111010010001000001101100011111000" + ] + + bursts_expected_1 = [ + "0000010000000010000001001000011001010010000011000101000000001010000111011101001000011101010100100000000001001000001000000100100011000101001000111000", + "0000110101000011011010110000110011010000000001001010110010001010000111011101001000011101010000011000111001101110000000110010100001101110101000100000" + ] + + bursts_expected_2 = [ + "0001010101111111111010000001010101011111111111101000000001001010000111011101001000011101010111111111111010101000000001010101011011101010000001000000", + "0001000100000011001010111001111100011010000000000000001001001010000111011101001000011101010110000101111010011001110110001001011010101000011110110000", + "0000000100111011000000000010100100001100101010000000010010101010000111011101001000011101000110110001110110000100110100110110011001100100000101100000" + ] + + bursts_expected_3 = [ + "0001000101000000001001111110000110010110110111110111101000001101001111101100010100111111001110001001110101110001010001000111011010010001011011000000", + "0000010010100000001001101010100001011100010001101100111111101101001111101100010100111111101101001110100010101110010110101111100010010000110010110000", + "0001000000000010111010100000010101000010001010111010000000011010000111011101001000011101000000100010111110101000000001000000000010111010100000000000", + "0001100001000111111111100001011000000011010110111010110000111010000111011101001000011101100010111100100101110001101000110100110000001010101110011000" + ] + + bursts_expected_4 = [ + "0001001101101101000111001000101011001101001110110001001100111101001111101100010100111111111001001010011010011111010010010101011001001011011100110000" + ] + + bursts_expected_5 = [ + "0000010101010110010011110101010101101100000000001000100100101010000111011101001000011101011101110000101011001111000100001000000000001110010001111000", + "0000001000100011000000000000110100000000010000001010100100001010000111011101001000011101000010010000000000001001000001011000000001010000000100010000" + ] + + bursts_expected_6 = [ + "0001100001000111100111101111100101000100101011000010011110011101001111101100010100111111100000110100011111101011101100100111110011000100010001010000", + "0001010100110111100000110111100110010100011100011000110110001010000111011101001000011101011111111001111001101010010100000000011111001101000111110000", + "0000101110101111011001011001000011110010100010011100110010001010000111011101001000011101100000001110000100010100110111001001100010101101100010101000", + "0001011101101101011100001111001100010001000011011001101110011010000111011101001000011101010010111011100111000001011100100001111010100101111000100000" + ] + + bursts_expected_7 = [ + "0000000000111110101010100001000000100010101110101010000101001010000111011101001000011101001010001111101010001000010000000000101110101010100000010000", + "0000010101100101010110000011010000000000000010111001110110101010000111011101001000011101000001000100100001111001100011000101010001110001010100111000", + "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000", + "0000100000110001000000000100000110001011100001001000000000001010000111011101001000011101001010010001010000000111010000000011000001000000000101010000" + ] + + + src = grgsm.burst_source_qa(framenumbers_input, timeslots_input, bursts_input) + splitter = grgsm.burst_timeslot_splitter() + sink_0 = grgsm.burst_sink_qa() + sink_1 = grgsm.burst_sink_qa() + sink_2 = grgsm.burst_sink_qa() + sink_3 = grgsm.burst_sink_qa() + sink_4 = grgsm.burst_sink_qa() + sink_5 = grgsm.burst_sink_qa() + sink_6 = grgsm.burst_sink_qa() + sink_7 = grgsm.burst_sink_qa() + + self.tb.msg_connect(src, "out", splitter, "in") + self.tb.msg_connect(splitter, "out0", sink_0, "in") + self.tb.msg_connect(splitter, "out1", sink_1, "in") + self.tb.msg_connect(splitter, "out2", sink_2, "in") + self.tb.msg_connect(splitter, "out3", sink_3, "in") + self.tb.msg_connect(splitter, "out4", sink_4, "in") + self.tb.msg_connect(splitter, "out5", sink_5, "in") + self.tb.msg_connect(splitter, "out6", sink_6, "in") + self.tb.msg_connect(splitter, "out7", sink_7, "in") + + self.tb.run () + + bursts_result_0 = list(sink_0.get_burst_data()) + bursts_result_1 = list(sink_1.get_burst_data()) + bursts_result_2 = list(sink_2.get_burst_data()) + bursts_result_3 = list(sink_3.get_burst_data()) + bursts_result_4 = list(sink_4.get_burst_data()) + bursts_result_5 = list(sink_5.get_burst_data()) + bursts_result_6 = list(sink_6.get_burst_data()) + bursts_result_7 = list(sink_7.get_burst_data()) + + self.assertEqual(bursts_expected_0, bursts_result_0) + self.assertEqual(bursts_expected_1, bursts_result_1) + self.assertEqual(bursts_expected_2, bursts_result_2) + self.assertEqual(bursts_expected_3, bursts_result_3) + self.assertEqual(bursts_expected_4, bursts_result_4) + self.assertEqual(bursts_expected_5, bursts_result_5) + self.assertEqual(bursts_expected_6, bursts_result_6) + self.assertEqual(bursts_expected_7, bursts_result_7) + + +if __name__ == '__main__': + gr_unittest.run(qa_burst_timeslot_splitter, "qa_burst_timeslot_splitter.xml") diff --git a/swig/grgsm_swig.i b/swig/grgsm_swig.i index 5dc1bcd..600281a 100644 --- a/swig/grgsm_swig.i +++ b/swig/grgsm_swig.i @@ -16,6 +16,7 @@ #include "grgsm/decryption/decryption.h" #include "grgsm/demapping/universal_ctrl_chans_demapper.h" #include "grgsm/demapping/tch_f_chans_demapper.h" +#include "grgsm/flow_control/burst_timeslot_splitter.h" #include "grgsm/misc_utils/bursts_printer.h" #include "grgsm/misc_utils/controlled_const_source_f.h" #include "grgsm/misc_utils/controlled_rotator_cc.h" @@ -29,7 +30,6 @@ #include "grgsm/misc_utils/burst_source_qa.h" %} - %include "grgsm/receiver/receiver.h" GR_SWIG_BLOCK_MAGIC2(gsm, receiver); %include "grgsm/receiver/clock_offset_control.h" @@ -50,6 +50,9 @@ GR_SWIG_BLOCK_MAGIC2(gsm, universal_ctrl_chans_demapper); %include "grgsm/demapping/tch_f_chans_demapper.h" GR_SWIG_BLOCK_MAGIC2(gsm, tch_f_chans_demapper); +%include "grgsm/flow_control/burst_timeslot_splitter.h" +GR_SWIG_BLOCK_MAGIC2(gsm, burst_timeslot_splitter); + %include "grgsm/misc_utils/bursts_printer.h" GR_SWIG_BLOCK_MAGIC2(gsm, bursts_printer); %include "grgsm/misc_utils/burst_sink.h" From 8e3b0eca898706383bf7dfbbef8f37dfea5d10be Mon Sep 17 00:00:00 2001 From: Roman Khassraf Date: Tue, 4 Aug 2015 11:16:04 +0200 Subject: [PATCH 2/4] Implemented burst framenumber filter. Issue #100 --- grc/flow_control/CMakeLists.txt | 3 +- grc/flow_control/gsm_burst_fnr_filter.xml | 42 +++++ grc/gsm_block_tree.xml | 1 + include/grgsm/flow_control/CMakeLists.txt | 3 +- include/grgsm/flow_control/burst_fnr_filter.h | 64 +++++++ lib/CMakeLists.txt | 1 + lib/flow_control/burst_fnr_filter_impl.cc | 79 ++++++++ lib/flow_control/burst_fnr_filter_impl.h | 46 +++++ python/CMakeLists.txt | 1 + python/qa_burst_fnr_filter.py | 168 ++++++++++++++++++ swig/grgsm_swig.i | 3 + 11 files changed, 409 insertions(+), 2 deletions(-) create mode 100644 grc/flow_control/gsm_burst_fnr_filter.xml create mode 100644 include/grgsm/flow_control/burst_fnr_filter.h create mode 100644 lib/flow_control/burst_fnr_filter_impl.cc create mode 100644 lib/flow_control/burst_fnr_filter_impl.h create mode 100755 python/qa_burst_fnr_filter.py diff --git a/grc/flow_control/CMakeLists.txt b/grc/flow_control/CMakeLists.txt index c11943f..37fa830 100644 --- a/grc/flow_control/CMakeLists.txt +++ b/grc/flow_control/CMakeLists.txt @@ -18,5 +18,6 @@ # Boston, MA 02110-1301, USA. install(FILES - gsm_burst_timeslot_splitter.xml DESTINATION share/gnuradio/grc/blocks + gsm_burst_timeslot_splitter.xml + gsm_burst_fnr_filter.xml DESTINATION share/gnuradio/grc/blocks ) diff --git a/grc/flow_control/gsm_burst_fnr_filter.xml b/grc/flow_control/gsm_burst_fnr_filter.xml new file mode 100644 index 0000000..d09b6e6 --- /dev/null +++ b/grc/flow_control/gsm_burst_fnr_filter.xml @@ -0,0 +1,42 @@ + + + Burst framenumber filter + gsm_burst_fnr_filter + import grgsm + grgsm.burst_fnr_filter($mode, $fnr) + + + Mode + mode + enum + + + + + Framenumber + fnr + 1500123 + int + + + + in + message + + + + out + message + 1 + + + +Burst framenumber filter forwards only blocks with a framenumber satisfying the configured mode, i.e. if mode is "Less or equal", then only bursts with a smaller or equal framenumber are forwarded. + + diff --git a/grc/gsm_block_tree.xml b/grc/gsm_block_tree.xml index 1679ad1..2c48aff 100644 --- a/grc/gsm_block_tree.xml +++ b/grc/gsm_block_tree.xml @@ -40,6 +40,7 @@ Flow control gsm_burst_timeslot_splitter + gsm_burst_fnr_filter Utilities diff --git a/include/grgsm/flow_control/CMakeLists.txt b/include/grgsm/flow_control/CMakeLists.txt index e701592..1063aae 100644 --- a/include/grgsm/flow_control/CMakeLists.txt +++ b/include/grgsm/flow_control/CMakeLists.txt @@ -21,5 +21,6 @@ # Install public header files ######################################################################## install(FILES - burst_timeslot_splitter.h DESTINATION include/grgsm/flow_control + burst_timeslot_splitter.h + burst_fnr_filter.h DESTINATION include/grgsm/flow_control ) diff --git a/include/grgsm/flow_control/burst_fnr_filter.h b/include/grgsm/flow_control/burst_fnr_filter.h new file mode 100644 index 0000000..9451d58 --- /dev/null +++ b/include/grgsm/flow_control/burst_fnr_filter.h @@ -0,0 +1,64 @@ +/* -*- c++ -*- */ +/* + * @file + * @author Roman Khassraf + * @section LICENSE + * + * Gr-gsm 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. + * + * Gr-gsm 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 gr-gsm; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_GSM_BURST_FNR_FILTER_H +#define INCLUDED_GSM_BURST_FNR_FILTER_H + +#include +#include + +namespace gr { + namespace gsm { + + enum filter_mode + { + FILTER_LESS_OR_EQUAL, + FILTER_GREATER_OR_EQUAL + }; + + /*! + * \brief <+description of block+> + * \ingroup gsm + * + */ + class GSM_API burst_fnr_filter : virtual public gr::block + { + public: + typedef boost::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of gsm::burst_fnr_filter. + * + * To avoid accidental use of raw pointers, gsm::burst_fnr_filter's + * constructor is in a private implementation + * class. gsm::burst_fnr_filter::make is the public interface for + * creating new instances. + */ + static sptr make(filter_mode mode, unsigned int fnr); + + }; + + } // namespace gsm +} // namespace gr + +#endif /* INCLUDED_GSM_BURST_FNR_FILTER_H */ diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 4a61f0b..83948b7 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -47,6 +47,7 @@ list(APPEND grgsm_sources decoding/GSM503Tables.cpp decoding/ViterbiR204.cpp flow_control/burst_timeslot_splitter_impl.cc + flow_control/burst_fnr_filter_impl.cc misc_utils/controlled_rotator_cc_impl.cc misc_utils/controlled_const_source_f_impl.cc misc_utils/message_printer_impl.cc diff --git a/lib/flow_control/burst_fnr_filter_impl.cc b/lib/flow_control/burst_fnr_filter_impl.cc new file mode 100644 index 0000000..1aa6f5b --- /dev/null +++ b/lib/flow_control/burst_fnr_filter_impl.cc @@ -0,0 +1,79 @@ +/* -*- c++ -*- */ +/* @file + * @author Roman Khassraf + * @section LICENSE + * + * Gr-gsm 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. + * + * Gr-gsm 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 gr-gsm; 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 "burst_fnr_filter_impl.h" +#include +#include +#include + + +namespace gr { + namespace gsm { + + burst_fnr_filter::sptr + burst_fnr_filter::make(filter_mode mode, unsigned int fnr) + { + return gnuradio::get_initial_sptr + (new burst_fnr_filter_impl(mode, fnr)); + } + + /* + * The private constructor + */ + burst_fnr_filter_impl::burst_fnr_filter_impl(filter_mode mode, unsigned int fnr) + : gr::block("burst_fnr_filter", + gr::io_signature::make(0, 0, 0), + gr::io_signature::make(0, 0, 0)), + d_mode(mode), + d_framenr(fnr) + { + message_port_register_in(pmt::mp("in")); + message_port_register_out(pmt::mp("out")); + + set_msg_handler(pmt::mp("in"), boost::bind(&burst_fnr_filter_impl::process_burst, this, _1)); + } + + /* + * Our virtual destructor. + */ + burst_fnr_filter_impl::~burst_fnr_filter_impl() {} + + void burst_fnr_filter_impl::process_burst(pmt::pmt_t msg) + { + pmt::pmt_t header_plus_burst = pmt::cdr(msg); + gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(header_plus_burst); + + unsigned int frame_nr = be32toh(header->frame_number); + + if ((d_mode == FILTER_LESS_OR_EQUAL && frame_nr <= d_framenr) + || d_mode == FILTER_GREATER_OR_EQUAL && frame_nr >= d_framenr) + { + message_port_pub(pmt::mp("out"), msg); + } + } + } /* namespace gsm */ +} /* namespace gr */ diff --git a/lib/flow_control/burst_fnr_filter_impl.h b/lib/flow_control/burst_fnr_filter_impl.h new file mode 100644 index 0000000..5d9850d --- /dev/null +++ b/lib/flow_control/burst_fnr_filter_impl.h @@ -0,0 +1,46 @@ +/* -*- c++ -*- */ +/* @file + * @author Roman Khassraf + * @section LICENSE + * + * Gr-gsm 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. + * + * Gr-gsm 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 gr-gsm; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef INCLUDED_GSM_BURST_FNR_FILTER_IMPL_H +#define INCLUDED_GSM_BURST_FNR_FILTER_IMPL_H + +#include + +namespace gr { + namespace gsm { + + class burst_fnr_filter_impl : public burst_fnr_filter + { + private: + unsigned int d_framenr; + filter_mode d_mode; + public: + burst_fnr_filter_impl(filter_mode mode, unsigned int fnr); + ~burst_fnr_filter_impl(); + void process_burst(pmt::pmt_t msg); + }; + + } // namespace gsm +} // namespace gr + +#endif /* INCLUDED_GSM_BURST_FNR_FILTER_IMPL_H */ + diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index f84c458..0bd5042 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -48,3 +48,4 @@ set(GR_TEST_TARGET_DEPS gr-gsm) set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/swig) GR_ADD_TEST(qa_decryption ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_decryption.py) GR_ADD_TEST(qa_burst_timeslot_splitter ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_burst_timeslot_splitter.py) +GR_ADD_TEST(qa_burst_fnr_filter ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_burst_fnr_filter.py) diff --git a/python/qa_burst_fnr_filter.py b/python/qa_burst_fnr_filter.py new file mode 100755 index 0000000..a1d3d11 --- /dev/null +++ b/python/qa_burst_fnr_filter.py @@ -0,0 +1,168 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @file +# @author Roman Khassraf +# @section LICENSE +# +# Gr-gsm 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. +# +# Gr-gsm 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 gr-gsm; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# +# + +from gnuradio import gr, gr_unittest, blocks +import grgsm +import pmt + +class qa_burst_fnr_filter (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_001_less_or_equal (self): + """ + filter mode less_or_equal, limiting frame number 1500123 + 25 random framenumbers, timeslots and bursts as input + """ + framenumbers_input = [1259192, 1076346, 1076242, 235879, 1259218, 2194302, 2714322, 1588, 1259244, 1563637, 1435624, 1928543, 503726, 1571144, 2658397, 1807445, 869789, 624070, 2005511, 1306953, 2284894, 1600339, 551375, 1259270, 1500123] + timeslots_input = [6, 3, 4, 3, 5, 3, 2, 7, 1, 6, 0, 7, 2, 3, 2, 0, 7, 1, 0, 6, 0, 6, 5, 7, 0] + bursts_input = [ + "0001100001000111100111101111100101000100101011000010011110011101001111101100010100111111100000110100011111101011101100100111110011000100010001010000", + "0001000101000000001001111110000110010110110111110111101000001101001111101100010100111111001110001001110101110001010001000111011010010001011011000000", + "0001001101101101000111001000101011001101001110110001001100111101001111101100010100111111111001001010011010011111010010010101011001001011011100110000", + "0000010010100000001001101010100001011100010001101100111111101101001111101100010100111111101101001110100010101110010110101111100010010000110010110000", + "0000010101010110010011110101010101101100000000001000100100101010000111011101001000011101011101110000101011001111000100001000000000001110010001111000", + "0001000000000010111010100000010101000010001010111010000000011010000111011101001000011101000000100010111110101000000001000000000010111010100000000000", + "0001010101111111111010000001010101011111111111101000000001001010000111011101001000011101010111111111111010101000000001010101011011101010000001000000", + "0000000000111110101010100001000000100010101110101010000101001010000111011101001000011101001010001111101010001000010000000000101110101010100000010000", + "0000010000000010000001001000011001010010000011000101000000001010000111011101001000011101010100100000000001001000001000000100100011000101001000111000", + "0001010100110111100000110111100110010100011100011000110110001010000111011101001000011101011111111001111001101010010100000000011111001101000111110000", + "0001100110000001011110001000001100101001010100111111000100111010000111011101001000011101000011010010001010111101000100110011111010100010010101000000", + "0000010101100101010110000011010000000000000010111001110110101010000111011101001000011101000001000100100001111001100011000101010001110001010100111000", + "0001000100000011001010111001111100011010000000000000001001001010000111011101001000011101010110000101111010011001110110001001011010101000011110110000", + "0001100001000111111111100001011000000011010110111010110000111010000111011101001000011101100010111100100101110001101000110100110000001010101110011000", + "0000000100111011000000000010100100001100101010000000010010101010000111011101001000011101000110110001110110000100110100110110011001100100000101100000", + "0000100101111010011110111010100111010100011011011101100111001010000111011101001000011101010000111010000110100000001000010011101011001001110100011000", + "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000", + "0000110101000011011010110000110011010000000001001010110010001010000111011101001000011101010000011000111001101110000000110010100001101110101000100000", + "0000001000010001011111111111101010100000010101011101101010101010000111011101001000011101100010010101010101011110101010101000010001011101111010101000", + "0000101110101111011001011001000011110010100010011100110010001010000111011101001000011101100000001110000100010100110111001001100010101101100010101000", + "0001100010000001000111011100101101101010100001111101001000101010000111011101001000011101111010000011010110010111011111010010001000001101100011111000", + "0001011101101101011100001111001100010001000011011001101110011010000111011101001000011101010010111011100111000001011100100001111010100101111000100000", + "0000001000100011000000000000110100000000010000001010100100001010000111011101001000011101000010010000000000001001000001011000000001010000000100010000", + "0000100000110001000000000100000110001011100001001000000000001010000111011101001000011101001010010001010000000111010000000011000001000000000101010000", + "0000100000110001000000000101000100001010100001001000000000001010000111011101001000011101001010010001101011001011101111101000010001000000000101010000" + ] + + bursts_expected = [ + "0001100001000111100111101111100101000100101011000010011110011101001111101100010100111111100000110100011111101011101100100111110011000100010001010000", + "0001000101000000001001111110000110010110110111110111101000001101001111101100010100111111001110001001110101110001010001000111011010010001011011000000", + "0001001101101101000111001000101011001101001110110001001100111101001111101100010100111111111001001010011010011111010010010101011001001011011100110000", + "0000010010100000001001101010100001011100010001101100111111101101001111101100010100111111101101001110100010101110010110101111100010010000110010110000", + "0000010101010110010011110101010101101100000000001000100100101010000111011101001000011101011101110000101011001111000100001000000000001110010001111000", + "0000000000111110101010100001000000100010101110101010000101001010000111011101001000011101001010001111101010001000010000000000101110101010100000010000", + "0000010000000010000001001000011001010010000011000101000000001010000111011101001000011101010100100000000001001000001000000100100011000101001000111000", + "0001100110000001011110001000001100101001010100111111000100111010000111011101001000011101000011010010001010111101000100110011111010100010010101000000", + "0001000100000011001010111001111100011010000000000000001001001010000111011101001000011101010110000101111010011001110110001001011010101000011110110000", + "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000", + "0000110101000011011010110000110011010000000001001010110010001010000111011101001000011101010000011000111001101110000000110010100001101110101000100000", + "0000101110101111011001011001000011110010100010011100110010001010000111011101001000011101100000001110000100010100110111001001100010101101100010101000", + "0000001000100011000000000000110100000000010000001010100100001010000111011101001000011101000010010000000000001001000001011000000001010000000100010000", + "0000100000110001000000000100000110001011100001001000000000001010000111011101001000011101001010010001010000000111010000000011000001000000000101010000", + "0000100000110001000000000101000100001010100001001000000000001010000111011101001000011101001010010001101011001011101111101000010001000000000101010000" + ] + + fnr_filter = grgsm.burst_fnr_filter(grgsm.FILTER_LESS_OR_EQUAL, 1500123) + + src = grgsm.burst_source_qa(framenumbers_input, timeslots_input, bursts_input) + sink = grgsm.burst_sink_qa() + + self.tb.msg_connect(src, "out", fnr_filter, "in") + self.tb.msg_connect(fnr_filter, "out", sink, "in") + + self.tb.run () + + bursts_result = list(sink.get_burst_data()) + + self.assertEqual(bursts_expected, bursts_result) + + + def test_002_greater_or_equal (self): + """ + filter mode greater_or_equal, limiting frame number 1500123 + 25 random framenumbers, timeslots and bursts as input + """ + framenumbers_input = [1259192, 1076346, 1076242, 235879, 1259218, 2194302, 2714322, 1588, 1259244, 1563637, 1435624, 1928543, 503726, 1571144, 2658397, 1807445, 869789, 624070, 2005511, 1306953, 2284894, 1600339, 551375, 1259270, 1500123] + timeslots_input = [6, 3, 4, 3, 5, 3, 2, 7, 1, 6, 0, 7, 2, 3, 2, 0, 7, 1, 0, 6, 0, 6, 5, 7, 0] + bursts_input = [ + "0001100001000111100111101111100101000100101011000010011110011101001111101100010100111111100000110100011111101011101100100111110011000100010001010000", + "0001000101000000001001111110000110010110110111110111101000001101001111101100010100111111001110001001110101110001010001000111011010010001011011000000", + "0001001101101101000111001000101011001101001110110001001100111101001111101100010100111111111001001010011010011111010010010101011001001011011100110000", + "0000010010100000001001101010100001011100010001101100111111101101001111101100010100111111101101001110100010101110010110101111100010010000110010110000", + "0000010101010110010011110101010101101100000000001000100100101010000111011101001000011101011101110000101011001111000100001000000000001110010001111000", + "0001000000000010111010100000010101000010001010111010000000011010000111011101001000011101000000100010111110101000000001000000000010111010100000000000", + "0001010101111111111010000001010101011111111111101000000001001010000111011101001000011101010111111111111010101000000001010101011011101010000001000000", + "0000000000111110101010100001000000100010101110101010000101001010000111011101001000011101001010001111101010001000010000000000101110101010100000010000", + "0000010000000010000001001000011001010010000011000101000000001010000111011101001000011101010100100000000001001000001000000100100011000101001000111000", + "0001010100110111100000110111100110010100011100011000110110001010000111011101001000011101011111111001111001101010010100000000011111001101000111110000", + "0001100110000001011110001000001100101001010100111111000100111010000111011101001000011101000011010010001010111101000100110011111010100010010101000000", + "0000010101100101010110000011010000000000000010111001110110101010000111011101001000011101000001000100100001111001100011000101010001110001010100111000", + "0001000100000011001010111001111100011010000000000000001001001010000111011101001000011101010110000101111010011001110110001001011010101000011110110000", + "0001100001000111111111100001011000000011010110111010110000111010000111011101001000011101100010111100100101110001101000110100110000001010101110011000", + "0000000100111011000000000010100100001100101010000000010010101010000111011101001000011101000110110001110110000100110100110110011001100100000101100000", + "0000100101111010011110111010100111010100011011011101100111001010000111011101001000011101010000111010000110100000001000010011101011001001110100011000", + "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000", + "0000110101000011011010110000110011010000000001001010110010001010000111011101001000011101010000011000111001101110000000110010100001101110101000100000", + "0000001000010001011111111111101010100000010101011101101010101010000111011101001000011101100010010101010101011110101010101000010001011101111010101000", + "0000101110101111011001011001000011110010100010011100110010001010000111011101001000011101100000001110000100010100110111001001100010101101100010101000", + "0001100010000001000111011100101101101010100001111101001000101010000111011101001000011101111010000011010110010111011111010010001000001101100011111000", + "0001011101101101011100001111001100010001000011011001101110011010000111011101001000011101010010111011100111000001011100100001111010100101111000100000", + "0000001000100011000000000000110100000000010000001010100100001010000111011101001000011101000010010000000000001001000001011000000001010000000100010000", + "0000100000110001000000000100000110001011100001001000000000001010000111011101001000011101001010010001010000000111010000000011000001000000000101010000", + "0000100000110001000000000101000100001010100001001000000000001010000111011101001000011101001010010001101011001011101111101000010001000000000101010000" + ] + + bursts_expected = [ + "0001000000000010111010100000010101000010001010111010000000011010000111011101001000011101000000100010111110101000000001000000000010111010100000000000", + "0001010101111111111010000001010101011111111111101000000001001010000111011101001000011101010111111111111010101000000001010101011011101010000001000000", + "0001010100110111100000110111100110010100011100011000110110001010000111011101001000011101011111111001111001101010010100000000011111001101000111110000", + "0000010101100101010110000011010000000000000010111001110110101010000111011101001000011101000001000100100001111001100011000101010001110001010100111000", + "0001100001000111111111100001011000000011010110111010110000111010000111011101001000011101100010111100100101110001101000110100110000001010101110011000", + "0000000100111011000000000010100100001100101010000000010010101010000111011101001000011101000110110001110110000100110100110110011001100100000101100000", + "0000100101111010011110111010100111010100011011011101100111001010000111011101001000011101010000111010000110100000001000010011101011001001110100011000", + "0000001000010001011111111111101010100000010101011101101010101010000111011101001000011101100010010101010101011110101010101000010001011101111010101000", + "0001100010000001000111011100101101101010100001111101001000101010000111011101001000011101111010000011010110010111011111010010001000001101100011111000", + "0001011101101101011100001111001100010001000011011001101110011010000111011101001000011101010010111011100111000001011100100001111010100101111000100000", + "0000100000110001000000000101000100001010100001001000000000001010000111011101001000011101001010010001101011001011101111101000010001000000000101010000" + ] + + fnr_filter = grgsm.burst_fnr_filter(grgsm.FILTER_GREATER_OR_EQUAL, 1500123) + + src = grgsm.burst_source_qa(framenumbers_input, timeslots_input, bursts_input) + sink = grgsm.burst_sink_qa() + + self.tb.msg_connect(src, "out", fnr_filter, "in") + self.tb.msg_connect(fnr_filter, "out", sink, "in") + + self.tb.run () + + bursts_result = list(sink.get_burst_data()) + + self.assertEqual(bursts_expected, bursts_result) + +if __name__ == '__main__': + gr_unittest.run(qa_burst_fnr_filter, "qa_burst_fnr_filter.xml") diff --git a/swig/grgsm_swig.i b/swig/grgsm_swig.i index 600281a..eacabb6 100644 --- a/swig/grgsm_swig.i +++ b/swig/grgsm_swig.i @@ -17,6 +17,7 @@ #include "grgsm/demapping/universal_ctrl_chans_demapper.h" #include "grgsm/demapping/tch_f_chans_demapper.h" #include "grgsm/flow_control/burst_timeslot_splitter.h" +#include "grgsm/flow_control/burst_fnr_filter.h" #include "grgsm/misc_utils/bursts_printer.h" #include "grgsm/misc_utils/controlled_const_source_f.h" #include "grgsm/misc_utils/controlled_rotator_cc.h" @@ -52,6 +53,8 @@ GR_SWIG_BLOCK_MAGIC2(gsm, tch_f_chans_demapper); %include "grgsm/flow_control/burst_timeslot_splitter.h" GR_SWIG_BLOCK_MAGIC2(gsm, burst_timeslot_splitter); +%include "grgsm/flow_control/burst_fnr_filter.h" +GR_SWIG_BLOCK_MAGIC2(gsm, burst_fnr_filter); %include "grgsm/misc_utils/bursts_printer.h" GR_SWIG_BLOCK_MAGIC2(gsm, bursts_printer); From 7cccb52ef3a1ab52167f59d10c74413d76ef1726 Mon Sep 17 00:00:00 2001 From: Roman Khassraf Date: Tue, 4 Aug 2015 12:26:54 +0200 Subject: [PATCH 3/4] Implemented dummy burst filter. Issue #100 --- grc/flow_control/CMakeLists.txt | 3 +- grc/flow_control/gsm_dummy_burst_filter.xml | 24 ++++ grc/gsm_block_tree.xml | 1 + include/grgsm/flow_control/CMakeLists.txt | 3 +- .../grgsm/flow_control/dummy_burst_filter.h | 55 +++++++++ lib/CMakeLists.txt | 1 + lib/flow_control/dummy_burst_filter_impl.cc | 105 ++++++++++++++++++ lib/flow_control/dummy_burst_filter_impl.h | 48 ++++++++ python/CMakeLists.txt | 1 + python/qa_dummy_burst_filter.py | 102 +++++++++++++++++ swig/grgsm_swig.i | 3 + 11 files changed, 344 insertions(+), 2 deletions(-) create mode 100644 grc/flow_control/gsm_dummy_burst_filter.xml create mode 100644 include/grgsm/flow_control/dummy_burst_filter.h create mode 100644 lib/flow_control/dummy_burst_filter_impl.cc create mode 100644 lib/flow_control/dummy_burst_filter_impl.h create mode 100755 python/qa_dummy_burst_filter.py diff --git a/grc/flow_control/CMakeLists.txt b/grc/flow_control/CMakeLists.txt index 37fa830..6531501 100644 --- a/grc/flow_control/CMakeLists.txt +++ b/grc/flow_control/CMakeLists.txt @@ -19,5 +19,6 @@ install(FILES gsm_burst_timeslot_splitter.xml - gsm_burst_fnr_filter.xml DESTINATION share/gnuradio/grc/blocks + gsm_burst_fnr_filter.xml + gsm_dummy_burst_filter.xml DESTINATION share/gnuradio/grc/blocks ) diff --git a/grc/flow_control/gsm_dummy_burst_filter.xml b/grc/flow_control/gsm_dummy_burst_filter.xml new file mode 100644 index 0000000..046abbf --- /dev/null +++ b/grc/flow_control/gsm_dummy_burst_filter.xml @@ -0,0 +1,24 @@ + + + Dummy burst filter + gsm_dummy_burst_filter + import grgsm + grgsm.dummy_burst_filter() + + + in + message + + + + out + message + 1 + + + +This block filters dummy bursts. + +For more information on dummy bursts, see GSM 05.02. + + diff --git a/grc/gsm_block_tree.xml b/grc/gsm_block_tree.xml index 2c48aff..1b8cd03 100644 --- a/grc/gsm_block_tree.xml +++ b/grc/gsm_block_tree.xml @@ -41,6 +41,7 @@ Flow control gsm_burst_timeslot_splitter gsm_burst_fnr_filter + gsm_dummy_burst_filter Utilities diff --git a/include/grgsm/flow_control/CMakeLists.txt b/include/grgsm/flow_control/CMakeLists.txt index 1063aae..380dd73 100644 --- a/include/grgsm/flow_control/CMakeLists.txt +++ b/include/grgsm/flow_control/CMakeLists.txt @@ -22,5 +22,6 @@ ######################################################################## install(FILES burst_timeslot_splitter.h - burst_fnr_filter.h DESTINATION include/grgsm/flow_control + burst_fnr_filter.h + dummy_burst_filter.h DESTINATION include/grgsm/flow_control ) diff --git a/include/grgsm/flow_control/dummy_burst_filter.h b/include/grgsm/flow_control/dummy_burst_filter.h new file mode 100644 index 0000000..0922433 --- /dev/null +++ b/include/grgsm/flow_control/dummy_burst_filter.h @@ -0,0 +1,55 @@ +/* -*- c++ -*- */ +/* @file + * @author Roman Khassraf + * @section LICENSE + * + * Gr-gsm 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. + * + * Gr-gsm 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 gr-gsm; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef INCLUDED_GSM_DUMMY_BURST_FILTER_H +#define INCLUDED_GSM_DUMMY_BURST_FILTER_H + +#include +#include + +namespace gr { + namespace gsm { + + /*! + * \brief <+description of block+> + * \ingroup gsm + * + */ + class GSM_API dummy_burst_filter : virtual public gr::block + { + public: + typedef boost::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of grgsm::dummy_burst_filter. + * + * To avoid accidental use of raw pointers, grgsm::dummy_burst_filter's + * constructor is in a private implementation + * class. grgsm::dummy_burst_filter::make is the public interface for + * creating new instances. + */ + static sptr make(); + }; + } // namespace gsm +} // namespace gr + +#endif /* INCLUDED_GSM_DUMMY_BURST_FILTER_H */ diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 83948b7..10e2e4b 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -48,6 +48,7 @@ list(APPEND grgsm_sources decoding/ViterbiR204.cpp flow_control/burst_timeslot_splitter_impl.cc flow_control/burst_fnr_filter_impl.cc + flow_control/dummy_burst_filter_impl.cc misc_utils/controlled_rotator_cc_impl.cc misc_utils/controlled_const_source_f_impl.cc misc_utils/message_printer_impl.cc diff --git a/lib/flow_control/dummy_burst_filter_impl.cc b/lib/flow_control/dummy_burst_filter_impl.cc new file mode 100644 index 0000000..33c24cb --- /dev/null +++ b/lib/flow_control/dummy_burst_filter_impl.cc @@ -0,0 +1,105 @@ +/* -*- c++ -*- */ +/* @file + * @author Roman Khassraf + * @section LICENSE + * + * Gr-gsm 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. + * + * Gr-gsm 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 gr-gsm; 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 "dummy_burst_filter_impl.h" +#include +#include +#include + + +namespace gr { + namespace gsm { + + // dummy burst defined in gsm 05.02, section 5.2.6 + const int8_t dummy_burst_filter_impl::d_dummy_burst[] = {0,0,0, + 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, + 0,0,0 }; + + dummy_burst_filter::sptr + dummy_burst_filter::make() + { + return gnuradio::get_initial_sptr + (new dummy_burst_filter_impl()); + } + + /* + * The private constructor + */ + dummy_burst_filter_impl::dummy_burst_filter_impl() + : gr::block("dummy_burst_filter", + gr::io_signature::make(0, 0, 0), + gr::io_signature::make(0, 0, 0)) + { + message_port_register_in(pmt::mp("in")); + message_port_register_out(pmt::mp("out")); + + set_msg_handler(pmt::mp("in"), boost::bind(&dummy_burst_filter_impl::process_burst, this, _1)); + } + + /* + * Our virtual destructor. + */ + dummy_burst_filter_impl::~dummy_burst_filter_impl() {} + + void dummy_burst_filter_impl::process_burst(pmt::pmt_t msg) + { + pmt::pmt_t header_plus_burst = pmt::cdr(msg); + int8_t * burst = (int8_t *)(pmt::blob_data(header_plus_burst)) + sizeof(gsmtap_hdr); + size_t burst_len = pmt::blob_length(header_plus_burst) - sizeof(gsmtap_hdr); + + if (!is_dummy_burst(burst, burst_len)) + { + message_port_pub(pmt::mp("out"), msg); + } + } + + bool dummy_burst_filter_impl::is_dummy_burst(int8_t *burst, size_t burst_len) + { + if (burst_len != DUMMY_BURST_LEN) + { + return false; + } + for (int i=0; i + * @section LICENSE + * + * Gr-gsm 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. + * + * Gr-gsm 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 gr-gsm; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef INCLUDED_GSM_DUMMY_BURST_FILTER_IMPL_H +#define INCLUDED_GSM_DUMMY_BURST_FILTER_IMPL_H + +#define DUMMY_BURST_LEN 148 + +#include + +namespace gr { + namespace gsm { + + class dummy_burst_filter_impl : public dummy_burst_filter + { + private: + bool is_dummy_burst(int8_t *burst, size_t burst_len); + static const int8_t d_dummy_burst[]; + public: + dummy_burst_filter_impl(); + ~dummy_burst_filter_impl(); + void process_burst(pmt::pmt_t msg); + }; + + } // namespace gsm +} // namespace gr + +#endif /* INCLUDED_GSM_DUMMY_BURST_FILTER_IMPL_H */ + diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 0bd5042..8ff87e0 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -49,3 +49,4 @@ set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/swig) GR_ADD_TEST(qa_decryption ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_decryption.py) GR_ADD_TEST(qa_burst_timeslot_splitter ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_burst_timeslot_splitter.py) GR_ADD_TEST(qa_burst_fnr_filter ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_burst_fnr_filter.py) +GR_ADD_TEST(qa_dummy_burst_filter ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_dummy_burst_filter.py) diff --git a/python/qa_dummy_burst_filter.py b/python/qa_dummy_burst_filter.py new file mode 100755 index 0000000..3988ce8 --- /dev/null +++ b/python/qa_dummy_burst_filter.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @file +# @author Roman Khassraf +# @section LICENSE +# +# Gr-gsm 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. +# +# Gr-gsm 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 gr-gsm; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# +# + +from gnuradio import gr, gr_unittest, blocks +import grgsm + +class qa_dummy_burst_filter (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_001 (self): + """ + filter mode less_or_equal, limiting frame number 1500123 + 24 bursts as input, 10 of them dummy bursts + """ + framenumbers_input = [1259192, 1076346, 1076242, 235879, 1259218, 2194302, 2714322, 1588, 1259244, 1563637, 1435624, 1928543, 503726, 1571144, 2658397, 1807445, 869789, 624070, 2005511, 1306953, 2284894, 1600339, 551375, 1259270] + timeslots_input = [6, 3, 4, 3, 5, 3, 2, 7, 1, 6, 0, 7, 2, 3, 2, 0, 7, 1, 0, 6, 0, 6, 5, 7] + bursts_input = [ + "0001100001000111100111101111100101000100101011000010011110011101001111101100010100111111100000110100011111101011101100100111110011000100010001010000", + "0001000101000000001001111110000110010110110111110111101000001101001111101100010100111111001110001001110101110001010001000111011010010001011011000000", + "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000", + "0000010010100000001001101010100001011100010001101100111111101101001111101100010100111111101101001110100010101110010110101111100010010000110010110000", + "0000010101010110010011110101010101101100000000001000100100101010000111011101001000011101011101110000101011001111000100001000000000001110010001111000", + "0001000000000010111010100000010101000010001010111010000000011010000111011101001000011101000000100010111110101000000001000000000010111010100000000000", + "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000", + "0000000000111110101010100001000000100010101110101010000101001010000111011101001000011101001010001111101010001000010000000000101110101010100000010000", + "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000", + "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000", + "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000", + "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000", + "0001000100000011001010111001111100011010000000000000001001001010000111011101001000011101010110000101111010011001110110001001011010101000011110110000", + "0001100001000111111111100001011000000011010110111010110000111010000111011101001000011101100010111100100101110001101000110100110000001010101110011000", + "0000000100111011000000000010100100001100101010000000010010101010000111011101001000011101000110110001110110000100110100110110011001100100000101100000", + "0000100101111010011110111010100111010100011011011101100111001010000111011101001000011101010000111010000110100000001000010011101011001001110100011000", + "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000", + "0000110101000011011010110000110011010000000001001010110010001010000111011101001000011101010000011000111001101110000000110010100001101110101000100000", + "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000", + "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000", + "0001100010000001000111011100101101101010100001111101001000101010000111011101001000011101111010000011010110010111011111010010001000001101100011111000", + "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000", + "0000001000100011000000000000110100000000010000001010100100001010000111011101001000011101000010010000000000001001000001011000000001010000000100010000", + "0000100000110001000000000100000110001011100001001000000000001010000111011101001000011101001010010001010000000111010000000011000001000000000101010000", + ] + + bursts_expected = [ + "0001100001000111100111101111100101000100101011000010011110011101001111101100010100111111100000110100011111101011101100100111110011000100010001010000", + "0001000101000000001001111110000110010110110111110111101000001101001111101100010100111111001110001001110101110001010001000111011010010001011011000000", + "0000010010100000001001101010100001011100010001101100111111101101001111101100010100111111101101001110100010101110010110101111100010010000110010110000", + "0000010101010110010011110101010101101100000000001000100100101010000111011101001000011101011101110000101011001111000100001000000000001110010001111000", + "0001000000000010111010100000010101000010001010111010000000011010000111011101001000011101000000100010111110101000000001000000000010111010100000000000", + "0000000000111110101010100001000000100010101110101010000101001010000111011101001000011101001010001111101010001000010000000000101110101010100000010000", + "0001000100000011001010111001111100011010000000000000001001001010000111011101001000011101010110000101111010011001110110001001011010101000011110110000", + "0001100001000111111111100001011000000011010110111010110000111010000111011101001000011101100010111100100101110001101000110100110000001010101110011000", + "0000000100111011000000000010100100001100101010000000010010101010000111011101001000011101000110110001110110000100110100110110011001100100000101100000", + "0000100101111010011110111010100111010100011011011101100111001010000111011101001000011101010000111010000110100000001000010011101011001001110100011000", + "0000110101000011011010110000110011010000000001001010110010001010000111011101001000011101010000011000111001101110000000110010100001101110101000100000", + "0001100010000001000111011100101101101010100001111101001000101010000111011101001000011101111010000011010110010111011111010010001000001101100011111000", + "0000001000100011000000000000110100000000010000001010100100001010000111011101001000011101000010010000000000001001000001011000000001010000000100010000", + "0000100000110001000000000100000110001011100001001000000000001010000111011101001000011101001010010001010000000111010000000011000001000000000101010000" + ] + + dummy_burst_filter = grgsm.dummy_burst_filter() + + src = grgsm.burst_source_qa(framenumbers_input, timeslots_input, bursts_input) + sink = grgsm.burst_sink_qa() + + self.tb.msg_connect(src, "out", dummy_burst_filter, "in") + self.tb.msg_connect(dummy_burst_filter, "out", sink, "in") + + self.tb.run() + + bursts_result = list(sink.get_burst_data()) + + self.assertEqual(bursts_expected, bursts_result) + + +if __name__ == '__main__': + gr_unittest.run(qa_dummy_burst_filter, "qa_dummy_burst_filter.xml") diff --git a/swig/grgsm_swig.i b/swig/grgsm_swig.i index eacabb6..ba53b78 100644 --- a/swig/grgsm_swig.i +++ b/swig/grgsm_swig.i @@ -18,6 +18,7 @@ #include "grgsm/demapping/tch_f_chans_demapper.h" #include "grgsm/flow_control/burst_timeslot_splitter.h" #include "grgsm/flow_control/burst_fnr_filter.h" +#include "grgsm/flow_control/dummy_burst_filter.h" #include "grgsm/misc_utils/bursts_printer.h" #include "grgsm/misc_utils/controlled_const_source_f.h" #include "grgsm/misc_utils/controlled_rotator_cc.h" @@ -55,6 +56,8 @@ GR_SWIG_BLOCK_MAGIC2(gsm, tch_f_chans_demapper); GR_SWIG_BLOCK_MAGIC2(gsm, burst_timeslot_splitter); %include "grgsm/flow_control/burst_fnr_filter.h" GR_SWIG_BLOCK_MAGIC2(gsm, burst_fnr_filter); +%include "grgsm/flow_control/dummy_burst_filter.h" +GR_SWIG_BLOCK_MAGIC2(gsm, dummy_burst_filter); %include "grgsm/misc_utils/bursts_printer.h" GR_SWIG_BLOCK_MAGIC2(gsm, bursts_printer); From a1eb188b97d12737d58eed9162102798f440ba43 Mon Sep 17 00:00:00 2001 From: Roman Khassraf Date: Wed, 5 Aug 2015 12:30:29 +0200 Subject: [PATCH 4/4] Implemented burst sub-slot splitter. Issue #100 --- grc/flow_control/CMakeLists.txt | 3 +- .../gsm_burst_sdcch_subslot_splitter.xml | 44 ++ grc/gsm_block_tree.xml | 1 + include/grgsm/flow_control/CMakeLists.txt | 1 + .../burst_sdcch_subslot_splitter.h | 61 +++ lib/CMakeLists.txt | 1 + .../burst_sdcch_subslot_splitter_impl.cc | 135 ++++++ .../burst_sdcch_subslot_splitter_impl.h | 54 +++ python/CMakeLists.txt | 1 + python/qa_burst_sdcch_subslot_splitter.py | 401 ++++++++++++++++++ swig/grgsm_swig.i | 3 + 11 files changed, 704 insertions(+), 1 deletion(-) create mode 100644 grc/flow_control/gsm_burst_sdcch_subslot_splitter.xml create mode 100644 include/grgsm/flow_control/burst_sdcch_subslot_splitter.h create mode 100644 lib/flow_control/burst_sdcch_subslot_splitter_impl.cc create mode 100644 lib/flow_control/burst_sdcch_subslot_splitter_impl.h create mode 100755 python/qa_burst_sdcch_subslot_splitter.py diff --git a/grc/flow_control/CMakeLists.txt b/grc/flow_control/CMakeLists.txt index 6531501..107fac7 100644 --- a/grc/flow_control/CMakeLists.txt +++ b/grc/flow_control/CMakeLists.txt @@ -20,5 +20,6 @@ install(FILES gsm_burst_timeslot_splitter.xml gsm_burst_fnr_filter.xml - gsm_dummy_burst_filter.xml DESTINATION share/gnuradio/grc/blocks + gsm_dummy_burst_filter.xml + gsm_burst_sdcch_subslot_splitter.xml DESTINATION share/gnuradio/grc/blocks ) diff --git a/grc/flow_control/gsm_burst_sdcch_subslot_splitter.xml b/grc/flow_control/gsm_burst_sdcch_subslot_splitter.xml new file mode 100644 index 0000000..4812d0b --- /dev/null +++ b/grc/flow_control/gsm_burst_sdcch_subslot_splitter.xml @@ -0,0 +1,44 @@ + + + Burst SDCCH subslot splitter + gsm_burst_sdcch_subslot_splitter + import grgsm + grgsm.burst_sdcch_subslot_splitter( +#if int($ports())==4 # +grgsm.SPLITTER_SDCCH4 +#else +grgsm.SPLITTER_SDCCH8 +#end if + ) + + + Mode + ports + enum + + + + + + in + message + + + + out + message + $ports + 1 + + + +Burst SDCCH subslot splitter distributes bursts to eight different output ports depending on the subslots to which the bursts belong. +This means subslot 0 bursts are sent to port out0, subslot 1 bursts on port out1, and so on. + + \ No newline at end of file diff --git a/grc/gsm_block_tree.xml b/grc/gsm_block_tree.xml index 1b8cd03..a76547a 100644 --- a/grc/gsm_block_tree.xml +++ b/grc/gsm_block_tree.xml @@ -40,6 +40,7 @@ Flow control gsm_burst_timeslot_splitter + gsm_burst_sdcch_subslot_splitter gsm_burst_fnr_filter gsm_dummy_burst_filter diff --git a/include/grgsm/flow_control/CMakeLists.txt b/include/grgsm/flow_control/CMakeLists.txt index 380dd73..0a1a95a 100644 --- a/include/grgsm/flow_control/CMakeLists.txt +++ b/include/grgsm/flow_control/CMakeLists.txt @@ -22,6 +22,7 @@ ######################################################################## install(FILES burst_timeslot_splitter.h + burst_sdcch_subslot_splitter.h burst_fnr_filter.h dummy_burst_filter.h DESTINATION include/grgsm/flow_control ) diff --git a/include/grgsm/flow_control/burst_sdcch_subslot_splitter.h b/include/grgsm/flow_control/burst_sdcch_subslot_splitter.h new file mode 100644 index 0000000..aee2a24 --- /dev/null +++ b/include/grgsm/flow_control/burst_sdcch_subslot_splitter.h @@ -0,0 +1,61 @@ +/* -*- c++ -*- */ +/* @file + * @author Roman Khassraf + * @section LICENSE + * + * Gr-gsm 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. + * + * Gr-gsm 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 gr-gsm; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef INCLUDED_GSM_BURST_SDCCH_SUBSLOT_SPLITTER_H +#define INCLUDED_GSM_BURST_SDCCH_SUBSLOT_SPLITTER_H + +#include +#include + +namespace gr { + namespace gsm { + + enum splitter_mode + { + SPLITTER_SDCCH8, + SPLITTER_SDCCH4 + }; + + /*! + * \brief <+description of block+> + * \ingroup gsm + * + */ + class GSM_API burst_sdcch_subslot_splitter : virtual public gr::block + { + public: + typedef boost::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of grgsm::burst_sdcch_subslot_splitter. + * + * To avoid accidental use of raw pointers, grgsm::burst_sdcch_subslot_splitter's + * constructor is in a private implementation + * class. grgsm::burst_sdcch_subslot_splitter::make is the public interface for + * creating new instances. + */ + static sptr make(splitter_mode mode); + }; + } // namespace gsm +} // namespace gr + +#endif /* INCLUDED_GSM_BURST_SDCCH_SUBSLOT_SPLITTER_H */ diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 10e2e4b..05455a3 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -47,6 +47,7 @@ list(APPEND grgsm_sources decoding/GSM503Tables.cpp decoding/ViterbiR204.cpp flow_control/burst_timeslot_splitter_impl.cc + flow_control/burst_sdcch_subslot_splitter_impl.cc flow_control/burst_fnr_filter_impl.cc flow_control/dummy_burst_filter_impl.cc misc_utils/controlled_rotator_cc_impl.cc diff --git a/lib/flow_control/burst_sdcch_subslot_splitter_impl.cc b/lib/flow_control/burst_sdcch_subslot_splitter_impl.cc new file mode 100644 index 0000000..260fe11 --- /dev/null +++ b/lib/flow_control/burst_sdcch_subslot_splitter_impl.cc @@ -0,0 +1,135 @@ +/* -*- c++ -*- */ +/* @file + * @author Roman Khassraf + * @section LICENSE + * + * Gr-gsm 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. + * + * Gr-gsm 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 gr-gsm; 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 "burst_sdcch_subslot_splitter_impl.h" +#include +#include +#include + + +namespace gr { + namespace gsm { + + burst_sdcch_subslot_splitter::sptr + burst_sdcch_subslot_splitter::make(splitter_mode mode) + { + return gnuradio::get_initial_sptr + (new burst_sdcch_subslot_splitter_impl(mode)); + } + + /* + * The private constructor + */ + burst_sdcch_subslot_splitter_impl::burst_sdcch_subslot_splitter_impl(splitter_mode mode) + : gr::block("burst_sdcch_subslot_splitter", + gr::io_signature::make(0, 0, 0), + gr::io_signature::make(0, 0, 0)), + d_mode(mode) + { + message_port_register_in(pmt::mp("in")); + + message_port_register_out(pmt::mp("out0")); + message_port_register_out(pmt::mp("out1")); + message_port_register_out(pmt::mp("out2")); + message_port_register_out(pmt::mp("out3")); + if (d_mode == SPLITTER_SDCCH8) + { + message_port_register_out(pmt::mp("out4")); + message_port_register_out(pmt::mp("out5")); + message_port_register_out(pmt::mp("out6")); + message_port_register_out(pmt::mp("out7")); + } + + set_msg_handler(pmt::mp("in"), boost::bind(&burst_sdcch_subslot_splitter_impl::process_burst, this, _1)); + } + + /* + * Our virtual destructor. + */ + burst_sdcch_subslot_splitter_impl::~burst_sdcch_subslot_splitter_impl() {} + + void burst_sdcch_subslot_splitter_impl::process_burst(pmt::pmt_t msg) + { + pmt::pmt_t header_plus_burst = pmt::cdr(msg); + gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(header_plus_burst); + + uint32_t frame_nr = be32toh(header->frame_number); + uint32_t fn_mod102 = frame_nr % 102; + + int8_t subslot; + + if (d_mode == SPLITTER_SDCCH8) + { + subslot = d_subslots_sdcch8[fn_mod102]; + } + else if (d_mode == SPLITTER_SDCCH4) + { + subslot = d_subslots_sdcch4[fn_mod102]; + } + + if ((subslot == -1) || (d_mode == SPLITTER_SDCCH4 && subslot > 3)) + { + return; + } + + std::string port("out"); + + switch (subslot) + { + case 0: + port.append("0"); + break; + case 1: + port.append("1"); + break; + case 2: + port.append("2"); + break; + case 3: + port.append("3"); + break; + case 4: + port.append("4"); + break; + case 5: + port.append("5"); + break; + case 6: + port.append("6"); + break; + case 7: + port.append("7"); + break; + default: + port.append("0"); + break; + } + + message_port_pub(pmt::mp(port), msg); + } + } /* namespace gsm */ +} /* namespace gr */ diff --git a/lib/flow_control/burst_sdcch_subslot_splitter_impl.h b/lib/flow_control/burst_sdcch_subslot_splitter_impl.h new file mode 100644 index 0000000..58aff96 --- /dev/null +++ b/lib/flow_control/burst_sdcch_subslot_splitter_impl.h @@ -0,0 +1,54 @@ +/* -*- c++ -*- */ +/* @file + * @author Roman Khassraf + * @section LICENSE + * + * Gr-gsm 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. + * + * Gr-gsm 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 gr-gsm; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef INCLUDED_GSM_BURST_SDCCH_SUBSLOT_SPLITTER_IMPL_H +#define INCLUDED_GSM_BURST_SDCCH_SUBSLOT_SPLITTER_IMPL_H + +#include + +namespace gr { + namespace gsm { + + class burst_sdcch_subslot_splitter_impl : public burst_sdcch_subslot_splitter + { + private: + // hardcoded subslots of the channels, both SDCCH and the associated SACCH + // -1 means that the particular position in the frame is not SDCCH + const int8_t d_subslots_sdcch4[102] = { + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0, 0, 1, 1, 1, 1,-1,-1, 2, 2, 2, 2, 3, 3, 3, 3,-1,-1, 0, 0, 0, 0, 1, 1, 1, 1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0, 0, 1, 1, 1, 1,-1,-1, 2, 2, 2, 2, 3, 3, 3, 3,-1,-1, 2, 2, 2, 2, 3, 3, 3, 3,-1 + }; + const int8_t d_subslots_sdcch8[102] = { + 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,-1,-1,-1, + 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,-1,-1,-1 + }; + splitter_mode d_mode; + public: + burst_sdcch_subslot_splitter_impl(splitter_mode mode); + ~burst_sdcch_subslot_splitter_impl(); + void process_burst(pmt::pmt_t msg); + }; + + } // namespace gsm +} // namespace gr + +#endif /* INCLUDED_GSM_BURST_SDCCH_SUBSLOT_SPLITTER_IMPL_H */ diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 8ff87e0..da69ffd 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -48,5 +48,6 @@ set(GR_TEST_TARGET_DEPS gr-gsm) set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/swig) GR_ADD_TEST(qa_decryption ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_decryption.py) GR_ADD_TEST(qa_burst_timeslot_splitter ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_burst_timeslot_splitter.py) +GR_ADD_TEST(qa_burst_sdcch_subslot_splitter ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_burst_sdcch_subslot_splitter.py) GR_ADD_TEST(qa_burst_fnr_filter ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_burst_fnr_filter.py) GR_ADD_TEST(qa_dummy_burst_filter ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_dummy_burst_filter.py) diff --git a/python/qa_burst_sdcch_subslot_splitter.py b/python/qa_burst_sdcch_subslot_splitter.py new file mode 100755 index 0000000..6a68ebe --- /dev/null +++ b/python/qa_burst_sdcch_subslot_splitter.py @@ -0,0 +1,401 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @file +# @author Roman Khassraf +# @section LICENSE +# +# Gr-gsm 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. +# +# Gr-gsm 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 gr-gsm; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# +# + +from gnuradio import gr, gr_unittest, blocks +import grgsm +import pmt + +class qa_burst_sdcch_subslot_splitter (gr_unittest.TestCase): + # 102 random bursts as test input + bursts_input = [ + '0000111100101011111011010010011001000100001001110110000110110001011011101111000100101111111000110000001111111111000111100100011111010100010011111000', + '0001111110000000110110101010001000101000001101111100101100110010001111011010001000111100001010011101000111010111000100000111001111110011000011011000', + '0001101110111011011011011010000001011011001011000100100110010101001111101100010100111110110011001100100011111010110111011001000111101011100001111000', + '0000001011100110100011110111010101111000011111001011010011110000110101110010000011010110010011111001000110001111111010111011011001101010001100110000', + '0001011001110011011101111111100110110111011101001110111110000101001111101100010100111110001111100000000110001000010000010111111011110101100000111000', + '0001110110011011010011100010101010000100011000001111110101111101001111101100010100111110100001001101000100000001011001010110011111100010001111001000', + '0001101100101101011110011001110110011100001100100100100110000010001111011010001000111101101101001100100001110001011001000001100000011111101000011000', + '0000101100001011101001010001111001000000010100000111100110101000110101110010000011010110110000110010100011001111101101101001110111101001000011111000', + '0000011011010111011111101100010100110110000001100011100001010001011011101111000100101110001110000011001100100101111000001010000101010000110101110000', + '0000111100110111001011010100010010110100101010000000010001110010011101011000001001110100001010011111111111001010111010111010001111111101111110101000', + '0000111101101110011111010100010100110001101110001001111100100101001111101100010100111111100010010001001100000000111010001000100011010000110111110000', + '0000011100010011111011011001110010011000001111111110101000100000110101110010000011010111101011000100101011000011011011110000010001100110011010001000', + '0000011011100100011101000010111010101101001111110000110001111010000111011101001000011101111110101010000011100100111101000111101110011011001001100000', + '0000110100110111001010100011100010101001001010011001001111001001001011100001000100101111001001100100001111100111000101110111100011101100110100010000', + '0000011101101000110111010010111001011110101000001011111000101010000111011101001000011100100100010110101110101010001000011001001110100001000101001000', + '0000101000110000011100111010101000001101000111111101100100110010011101011000001001110101001101110101011110010100101010001110100001100010101000001000', + '0000100010110110000111101001011000001010011110000100111101111010011101011000001001110101100010000111010100001000110001110001111101010100100101010000', + '0000010110111011011100011101010001001011001110100011100001000101001111101100010100111110100100110001110011001011110001100000000100100111000011111000', + '0001101110100101110101100101011101111100111010101011110001101010000111011101001000011100100010100111110110111001001000100111110111100100010010111000', + '0000111000101011011101110110001110101111100010100000110111110010000111011101001000011101111011000101010100011111001000010000110101101110000010101000', + '0001001010011001111011001110100001000110010111110011111001000010011101011000001001110100001101000101010010001101001010111100100101010101011100110000', + '0000100010001111101111100100010010100000010111001011101101001000110101110010000011010110110011100111001001100101011010100101110011100001110010001000', + '0000100100010010111100111000011000001100100001110101110011011001011011101111000100101111001011000000010111001011110011000000001101100001001000100000', + '0001010000110010100010110111101111100100000011111000000010111010011101011000001001110101111100000011101010001010100001101000011010110000001001111000', + '0001101101111011000010001000000010001110101111001111111111110001011011101111000100101110110001011010110110100111000000010010101110111001111011000000', + '0001101000100010100001101100100101011100111000001101001010100010011101011000001001110100011100101100000010110101011011100111111011111101100000011000', + '0001010110101101110000011111101100001000001001110101100000011010001111011010001000111100000100110001111110110111010101011011011100111000101111010000', + '0000010000111000010001010010111110000100011000000101110110001000110101110010000011010111001100010011100001111101000101011110100001100010010110001000', + '0000011110101100001001101000001010010100100111101101101000110101001111101100010100111111011001110000011000100001010011100000001100010110101001001000', + '0001110111101011100000001011111101100110110001001100101111110010000111011101001000011101110010001111000010011110001101101111101011100001001100100000', + '0001111110100011001100101111001001101000101110011100011000100001001011100001000100101110000110110010111111110101000110001011010110011010100011001000', + '0001011100010110000001011011001100000101010000011010001000111111011110001001011101111001101111000011111110011001000010000011000101100011111001010000', + '0001110111001111101101110111110000001110111011011100110110001001001011100001000100101110100101001001000110101110111110100110100100111111011001011000', + '0001011111010100110010101100011000100011000011111000111100010101001111101100010100111111100110001110010110001110000101110000100101010111100100111000', + '0001000100110100001010000101011001010000001111001110011010001001001011100001000100101111100011000100111100100010111001010010110100010000110000110000', + '0001001100101001010111000101000101000000111101011111000001011010001111011010001000111100110110011000000011010000100110111101110011110011000011010000', + '0001011010100110110011000101111111010011110001101000011100101000110101110010000011010110110100000111011101000001101010100001110111001011010101111000', + '0000101010001100010011010101011110010101101110011110100110001010001111011010001000111100000010011011100001010001001111111100011111000011001010011000', + '0000111001011100101100111001010101000101010111011110111101010001001011100001000100101111100010100101111011000101100000101111000101011110011111100000', + '0000010101101111011001100001011100100101001000110111010110001111011110001001011101111000011010010010101111010000110000011001101011100000111110000000', + '0001000001011000010001000100100111110011001101111100010011110010011101011000001001110100110100101101100011010111101110110010101101001110001101010000', + '0000101000011101110011111001010011111001001010010000101110010001011011101111000100101111011111110000000100000110011001000100110000111001100000011000', + '0000100101010011010110101001100100110001011010111110110100011101001111101100010100111110111000110110100011001010110011000111011111110011001011100000', + '0001000110100001111010110101011111001000011100001111010110001001011011101111000100101111100001011001100110011001110101100001000001011011111110100000', + '0001011010100110001000100000001110010000011000111001001110000001001011100001000100101110011011011001000111101010001010111001101100000100001101001000', + '0000001010000101101010000000110000010101111011100110101000110111011110001001011101111001100011100100100100100000010010001111101111110011000001011000', + '0000000111000111010110000000001001101110001001001101100110010001011011101111000100101111101011111100101001110100101000011100111001001101101011101000', + '0000100100010111010011100110101011011010001011011011011101110010001111011010001000111100000110010111001010011100000011111100111000100100101010110000', + '0000101111000000100110100001011000000011111111010101010011011010000111011101001000011101110010101101000100100000001100001000100111001010010000111000', + '0000001001001101110111111011010011000011100001100011110011010001001011100001000100101110011100000010010111101100101011011111101011000000001100101000', + '0001100111010111011000100111110000111010111001011100011111000000110101110010000011010111001000000010000010011010111001111001011011011111110101011000', + '0000100010110111011001100110110010101011011110101001010001000001011011101111000100101111010101100010101110101111111011101000010111001111000101001000', + '0001110000101111100101001101001111101011000000011011000101111000110101110010000011010111111100111011111000000001010111001100110100100011010000011000', + '0000011000101001110100000000110101011101011010001101110110111001011011101111000100101111110110101011110110100111000000000011110011101000011000001000', + '0000101001000100101010001110110111010000011011001011101010010111011110001001011101111001111010110101100100101001111000100000010001000110000000110000', + '0000000111100101111111000110011101000110010110001110100101110001011011101111000100101110100010010011100010010001110100010101101101100111100110101000', + '0001000011111010000000011010011001010010011111000011110111010010001111011010001000111101101110111000011010001010100111011000001000110000101000000000', + '0001101000110010011001001110101101111110000111001101100110011001001011100001000100101110000101000111011001110001100011011101101000101001001001101000', + '0001100111010000101101001110010001001001011000011000001011001010011101011000001001110101101110110101111101110010010010000001000100011111010100011000', + '0001001101011001110000101110011110100001001000001111000100001001001011100001000100101110100010110100111010110010011000100111000100111111011000101000', + '0001001101010000111101110111111011000100101011011001110001001010011101011000001001110101000000011110001101001010110001100011000110100010011010000000', + '0000100100011000011010111010110001000101111010001001010110100001011011101111000100101111100001000101011111111110000011111111100110100100110000111000', + '0001011101111100011001100110010001000101100001001001000010110001011011101111000100101110101100111111101111111001110110100101000011100110000001011000', + '0001101000100100101011000001001101111011100110101010001110100010000111011101001000011101101101011111110001110001010000001111100110111101101000100000', + '0000010101011110000000010011100010101011101111011001100111001010001111011010001000111100010001101011101000101100010110100100001101010110010111000000', + '0001100011011000111011100010111111000000011111101010000010110001011011101111000100101111010100100110010000001010100011100001111011110010001011001000', + '0001001011000011010010000001001110110110010101010011000101001000110101110010000011010111010010011000110011000110000101111000010100001000011111111000', + '0000010100100110100110001010001011011000110000101011000001110001001011100001000100101111101010000111110111011010101010001100101100010100001000010000', + '0001101100111011110100000010111000000110111101001110111110111010011101011000001001110101011110110010010011001011001110101001101010101001011000010000', + '0001100011110111001100101110010110000110101101101111101101111001011011101111000100101111110001100010010000011100010000011011100010100111101001110000', + '0001010011010010101001001000100111111010011101011001110110010001011011101111000100101111111010111010010001100100101100011000100110011001101101000000', + '0000111011001001001100100100100101011111011100110101011100010010011101011000001001110101010100111100111001000001100010100111100001010011111111111000', + '0001100101110101101110111111000100110000001111010000100001011101001111101100010100111110111111110111000010011100101001111011010100001010001010001000', + '0000001000011111101111110000000000001100011111011010111010000111011110001001011101111001001100000001010100111111011000000110010111101001110010011000', + '0000100000011100011111001001001000001000100010010111101011101010011101011000001001110100000000010010011001110100101111001110111111010000010001000000', + '0001000101001011001111111101010111110010010110111111110000010001011011101111000100101111000100010000111110011101000001111100001001100100011100011000', + '0001101101101010110000001001110111001001000001110110110000110001001011100001000100101111100001110001000000110101100001111111001001111001101101100000', + '0000110011100000100000000010100100011001001000110010110101111001001011100001000100101110000111001100111111110011011001000001001000001111001101001000', + '0001001111100001110110001010100011100011110011100001010100001001001011100001000100101111001000101100111101001010111000010111101000000001101100101000', + '0000101001000010000001100001000011001010100011110111101110111001001011100001000100101110001010100101111010111000000010111011000010011001101000001000', + '0001101000000100110100110001010111010111111001101110110101100111011110001001011101111001000110010011100100000100011101110110111010001001000111101000', + '0000100000100110011100101001110010011011100010101101111001110010001111011010001000111101100000111011110010010111001100100010000101111111011101110000', + '0000100111111010101000001110100011010010010010100001011010110000110101110010000011010110011000111000111111000100001010010000011011001000011100110000', + '0001110110111100101101010011111100101100100100110001110110111001001011100001000100101110010111011011100001001010010100010101110100011111010101001000', + '0000111001001000110010011110000010011101000001010111011011111010011101011000001001110101011101101100101110010111010001100100000011100100111101010000', + '0001000001010011101010101011111100010010101110100001000111110010011101011000001001110101100000100101011101111101101101111000001101101010001000101000', + '0001101000001011010011001010011010100110010100011010101101011010000111011101001000011101100010011011111111101011100110000011110110001111000101101000', + '0000001010101101011001000000001000001001110100000111000000101001001011100001000100101110111111011101110101010011001110111111101001011010110000101000', + '0001011110101111110100110010010110011100111010011001001110011111011110001001011101111000101010001111000111000101111000100011100010100010010100010000', + '0001000001011110010010100001100010111111000111001111010101011111011110001001011101111001010010100101110110111111001111110010111100111010110011110000', + '0001111100100010101100010111000000011011001111001101101001000010001111011010001000111101111000000101111001110101101001101010001110100111101011001000', + '0000000011001001101001100111101011001011000100101100101001100010001111011010001000111101100100101001010100111000010001011000100110010101010111000000', + '0001111000011111011100011010110000000010000000100000111000100010011101011000001001110100011101011101001001000111011101100001011010101000011011011000', + '0001011000010101011100101011111010110101011110011011001011010010001111011010001000111100110111000110100100001100110100000001100100100111101010011000', + '0001010101101101101001011100101001110000100101011110100011100010011101011000001001110100111100001000000111000001111100011011101000101100111100111000', + '0000010101001010001110001001101101011011000110011011110111111000110101110010000011010110000000110010100100111001010110110011011101011001110100100000', + '0001111111000101100000111010111010011010011110110010111000010101001111101100010100111110000110010011101101011111001000010001111111000111001111011000', + '0000100101100011001010101100011110000111001110010010010000100001011011101111000100101110001111010000001000001101011010110101010111011011001101101000', + '0000110000111101100001011100100011101011011000111100001000000111011110001001011101111000111000000111100100101000000101100011011001111100110011110000', + '0000011001111001100111110110110000001111110101011110100011010010011101011000001001110101001101110111111100001001000101101101100110001111101011010000', + '0000100001011010001010000101110000111100011110110010000010101000110101110010000011010111010001010101111111111101101100110101111010110100001110101000', + '0000000111101000111001101101110011001100100000101111001011001111011110001001011101111001010011110001010010000011001100100001011001111010101011011000' + ] + + # 102 sequential framenumbers + framenumbers_input = [879852, 879853, 879854, 879855, 879856, 879857, 879858, 879859, 879860, 879861, 879862, 879863, 879864, 879865, 879866, 879867, 879868, 879869, 879870, 879871, 879872, 879873, 879874, 879875, 879876, 879877, 879878, 879879, 879880, 879881, 879882, 879883, 879884, 879885, 879886, 879887, 879888, 879889, 879890, 879891, 879892, 879893, 879894, 879895, 879896, 879897, 879898, 879899, 879900, 879901, 879902, 879903, 879904, 879905, 879906, 879907, 879908, 879909, 879910, 879911, 879912, 879913, 879914, 879915, 879916, 879917, 879918, 879919, 879920, 879921, 879922, 879923, 879924, 879925, 879926, 879927, 879928, 879929, 879930, 879931, 879932, 879933, 879934, 879935, 879936, 879937, 879938, 879939, 879940, 879941, 879942, 879943, 879944, 879945, 879946, 879947, 879948, 879949, 879950, 879951, 879952, 879953] + + timeslots_input = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + + def test_001_sdcch8 (self): + + bursts_expected_0 = [ + '0000111100101011111011010010011001000100001001110110000110110001011011101111000100101111111000110000001111111111000111100100011111010100010011111000', + '0001111110000000110110101010001000101000001101111100101100110010001111011010001000111100001010011101000111010111000100000111001111110011000011011000', + '0001101110111011011011011010000001011011001011000100100110010101001111101100010100111110110011001100100011111010110111011001000111101011100001111000', + '0000001011100110100011110111010101111000011111001011010011110000110101110010000011010110010011111001000110001111111010111011011001101010001100110000', + '0001110111001111101101110111110000001110111011011100110110001001001011100001000100101110100101001001000110101110111110100110100100111111011001011000', + '0001011111010100110010101100011000100011000011111000111100010101001111101100010100111111100110001110010110001110000101110000100101010111100100111000', + '0001000100110100001010000101011001010000001111001110011010001001001011100001000100101111100011000100111100100010111001010010110100010000110000110000', + '0001001100101001010111000101000101000000111101011111000001011010001111011010001000111100110110011000000011010000100110111101110011110011000011010000', + '0000100010110111011001100110110010101011011110101001010001000001011011101111000100101111010101100010101110101111111011101000010111001111000101001000', + '0001110000101111100101001101001111101011000000011011000101111000110101110010000011010111111100111011111000000001010111001100110100100011010000011000', + '0000011000101001110100000000110101011101011010001101110110111001011011101111000100101111110110101011110110100111000000000011110011101000011000001000', + '0000101001000100101010001110110111010000011011001011101010010111011110001001011101111001111010110101100100101001111000100000010001000110000000110000', + ] + + bursts_expected_1 = [ + '0001011001110011011101111111100110110111011101001110111110000101001111101100010100111110001111100000000110001000010000010111111011110101100000111000', + '0001110110011011010011100010101010000100011000001111110101111101001111101100010100111110100001001101000100000001011001010110011111100010001111001000', + '0001101100101101011110011001110110011100001100100100100110000010001111011010001000111101101101001100100001110001011001000001100000011111101000011000', + '0000101100001011101001010001111001000000010100000111100110101000110101110010000011010110110000110010100011001111101101101001110111101001000011111000', + '0001011010100110110011000101111111010011110001101000011100101000110101110010000011010110110100000111011101000001101010100001110111001011010101111000', + '0000101010001100010011010101011110010101101110011110100110001010001111011010001000111100000010011011100001010001001111111100011111000011001010011000', + '0000111001011100101100111001010101000101010111011110111101010001001011100001000100101111100010100101111011000101100000101111000101011110011111100000', + '0000010101101111011001100001011100100101001000110111010110001111011110001001011101111000011010010010101111010000110000011001101011100000111110000000', + '0000000111100101111111000110011101000110010110001110100101110001011011101111000100101110100010010011100010010001110100010101101101100111100110101000', + '0001000011111010000000011010011001010010011111000011110111010010001111011010001000111101101110111000011010001010100111011000001000110000101000000000', + '0001101000110010011001001110101101111110000111001101100110011001001011100001000100101110000101000111011001110001100011011101101000101001001001101000', + '0001100111010000101101001110010001001001011000011000001011001010011101011000001001110101101110110101111101110010010010000001000100011111010100011000', + ] + + bursts_expected_2 = [ + '0000011011010111011111101100010100110110000001100011100001010001011011101111000100101110001110000011001100100101111000001010000101010000110101110000', + '0000111100110111001011010100010010110100101010000000010001110010011101011000001001110100001010011111111111001010111010111010001111111101111110101000', + '0000111101101110011111010100010100110001101110001001111100100101001111101100010100111111100010010001001100000000111010001000100011010000110111110000', + '0000011100010011111011011001110010011000001111111110101000100000110101110010000011010111101011000100101011000011011011110000010001100110011010001000', + '0001000001011000010001000100100111110011001101111100010011110010011101011000001001110100110100101101100011010111101110110010101101001110001101010000', + '0000101000011101110011111001010011111001001010010000101110010001011011101111000100101111011111110000000100000110011001000100110000111001100000011000', + '0000100101010011010110101001100100110001011010111110110100011101001111101100010100111110111000110110100011001010110011000111011111110011001011100000', + '0001000110100001111010110101011111001000011100001111010110001001011011101111000100101111100001011001100110011001110101100001000001011011111110100000', + '0001001101011001110000101110011110100001001000001111000100001001001011100001000100101110100010110100111010110010011000100111000100111111011000101000', + '0001001101010000111101110111111011000100101011011001110001001010011101011000001001110101000000011110001101001010110001100011000110100010011010000000', + '0000100100011000011010111010110001000101111010001001010110100001011011101111000100101111100001000101011111111110000011111111100110100100110000111000', + '0001011101111100011001100110010001000101100001001001000010110001011011101111000100101110101100111111101111111001110110100101000011100110000001011000', + + ] + + bursts_expected_3 = [ + '0000011011100100011101000010111010101101001111110000110001111010000111011101001000011101111110101010000011100100111101000111101110011011001001100000', + '0000110100110111001010100011100010101001001010011001001111001001001011100001000100101111001001100100001111100111000101110111100011101100110100010000', + '0000011101101000110111010010111001011110101000001011111000101010000111011101001000011100100100010110101110101010001000011001001110100001000101001000', + '0000101000110000011100111010101000001101000111111101100100110010011101011000001001110101001101110101011110010100101010001110100001100010101000001000', + '0001011010100110001000100000001110010000011000111001001110000001001011100001000100101110011011011001000111101010001010111001101100000100001101001000', + '0000001010000101101010000000110000010101111011100110101000110111011110001001011101111001100011100100100100100000010010001111101111110011000001011000', + '0000000111000111010110000000001001101110001001001101100110010001011011101111000100101111101011111100101001110100101000011100111001001101101011101000', + '0000100100010111010011100110101011011010001011011011011101110010001111011010001000111100000110010111001010011100000011111100111000100100101010110000', + '0001101000100100101011000001001101111011100110101010001110100010000111011101001000011101101101011111110001110001010000001111100110111101101000100000', + '0000010101011110000000010011100010101011101111011001100111001010001111011010001000111100010001101011101000101100010110100100001101010110010111000000', + '0001100011011000111011100010111111000000011111101010000010110001011011101111000100101111010100100110010000001010100011100001111011110010001011001000', + '0001001011000011010010000001001110110110010101010011000101001000110101110010000011010111010010011000110011000110000101111000010100001000011111111000', + ] + + bursts_expected_4 = [ + '0000100010110110000111101001011000001010011110000100111101111010011101011000001001110101100010000111010100001000110001110001111101010100100101010000', + '0000010110111011011100011101010001001011001110100011100001000101001111101100010100111110100100110001110011001011110001100000000100100111000011111000', + '0001101110100101110101100101011101111100111010101011110001101010000111011101001000011100100010100111110110111001001000100111110111100100010010111000', + '0000111000101011011101110110001110101111100010100000110111110010000111011101001000011101111011000101010100011111001000010000110101101110000010101000', + '0000010100100110100110001010001011011000110000101011000001110001001011100001000100101111101010000111110111011010101010001100101100010100001000010000', + '0001101100111011110100000010111000000110111101001110111110111010011101011000001001110101011110110010010011001011001110101001101010101001011000010000', + '0001100011110111001100101110010110000110101101101111101101111001011011101111000100101111110001100010010000011100010000011011100010100111101001110000', + '0001010011010010101001001000100111111010011101011001110110010001011011101111000100101111111010111010010001100100101100011000100110011001101101000000', + '0001110110111100101101010011111100101100100100110001110110111001001011100001000100101110010111011011100001001010010100010101110100011111010101001000', + '0000111001001000110010011110000010011101000001010111011011111010011101011000001001110101011101101100101110010111010001100100000011100100111101010000', + '0001000001010011101010101011111100010010101110100001000111110010011101011000001001110101100000100101011101111101101101111000001101101010001000101000', + '0001101000001011010011001010011010100110010100011010101101011010000111011101001000011101100010011011111111101011100110000011110110001111000101101000', + ] + + bursts_expected_5 = [ + '0001001010011001111011001110100001000110010111110011111001000010011101011000001001110100001101000101010010001101001010111100100101010101011100110000', + '0000100010001111101111100100010010100000010111001011101101001000110101110010000011010110110011100111001001100101011010100101110011100001110010001000', + '0000100100010010111100111000011000001100100001110101110011011001011011101111000100101111001011000000010111001011110011000000001101100001001000100000', + '0001010000110010100010110111101111100100000011111000000010111010011101011000001001110101111100000011101010001010100001101000011010110000001001111000', + '0000111011001001001100100100100101011111011100110101011100010010011101011000001001110101010100111100111001000001100010100111100001010011111111111000', + '0001100101110101101110111111000100110000001111010000100001011101001111101100010100111110111111110111000010011100101001111011010100001010001010001000', + '0000001000011111101111110000000000001100011111011010111010000111011110001001011101111001001100000001010100111111011000000110010111101001110010011000', + '0000100000011100011111001001001000001000100010010111101011101010011101011000001001110100000000010010011001110100101111001110111111010000010001000000', + '0000001010101101011001000000001000001001110100000111000000101001001011100001000100101110111111011101110101010011001110111111101001011010110000101000', + '0001011110101111110100110010010110011100111010011001001110011111011110001001011101111000101010001111000111000101111000100011100010100010010100010000', + '0001000001011110010010100001100010111111000111001111010101011111011110001001011101111001010010100101110110111111001111110010111100111010110011110000', + '0001111100100010101100010111000000011011001111001101101001000010001111011010001000111101111000000101111001110101101001101010001110100111101011001000', + ] + + bursts_expected_6 = [ + '0001101101111011000010001000000010001110101111001111111111110001011011101111000100101110110001011010110110100111000000010010101110111001111011000000', + '0001101000100010100001101100100101011100111000001101001010100010011101011000001001110100011100101100000010110101011011100111111011111101100000011000', + '0001010110101101110000011111101100001000001001110101100000011010001111011010001000111100000100110001111110110111010101011011011100111000101111010000', + '0000010000111000010001010010111110000100011000000101110110001000110101110010000011010111001100010011100001111101000101011110100001100010010110001000', + '0001000101001011001111111101010111110010010110111111110000010001011011101111000100101111000100010000111110011101000001111100001001100100011100011000', + '0001101101101010110000001001110111001001000001110110110000110001001011100001000100101111100001110001000000110101100001111111001001111001101101100000', + '0000110011100000100000000010100100011001001000110010110101111001001011100001000100101110000111001100111111110011011001000001001000001111001101001000', + '0001001111100001110110001010100011100011110011100001010100001001001011100001000100101111001000101100111101001010111000010111101000000001101100101000', + '0000000011001001101001100111101011001011000100101100101001100010001111011010001000111101100100101001010100111000010001011000100110010101010111000000', + '0001111000011111011100011010110000000010000000100000111000100010011101011000001001110100011101011101001001000111011101100001011010101000011011011000', + '0001011000010101011100101011111010110101011110011011001011010010001111011010001000111100110111000110100100001100110100000001100100100111101010011000', + '0001010101101101101001011100101001110000100101011110100011100010011101011000001001110100111100001000000111000001111100011011101000101100111100111000', + ] + + bursts_expected_7 = [ + '0000011110101100001001101000001010010100100111101101101000110101001111101100010100111111011001110000011000100001010011100000001100010110101001001000', + '0001110111101011100000001011111101100110110001001100101111110010000111011101001000011101110010001111000010011110001101101111101011100001001100100000', + '0001111110100011001100101111001001101000101110011100011000100001001011100001000100101110000110110010111111110101000110001011010110011010100011001000', + '0001011100010110000001011011001100000101010000011010001000111111011110001001011101111001101111000011111110011001000010000011000101100011111001010000', + '0000101001000010000001100001000011001010100011110111101110111001001011100001000100101110001010100101111010111000000010111011000010011001101000001000', + '0001101000000100110100110001010111010111111001101110110101100111011110001001011101111001000110010011100100000100011101110110111010001001000111101000', + '0000100000100110011100101001110010011011100010101101111001110010001111011010001000111101100000111011110010010111001100100010000101111111011101110000', + '0000100111111010101000001110100011010010010010100001011010110000110101110010000011010110011000111000111111000100001010010000011011001000011100110000', + '0000010101001010001110001001101101011011000110011011110111111000110101110010000011010110000000110010100100111001010110110011011101011001110100100000', + '0001111111000101100000111010111010011010011110110010111000010101001111101100010100111110000110010011101101011111001000010001111111000111001111011000', + '0000100101100011001010101100011110000111001110010010010000100001011011101111000100101110001111010000001000001101011010110101010111011011001101101000', + '0000110000111101100001011100100011101011011000111100001000000111011110001001011101111000111000000111100100101000000101100011011001111100110011110000', + ] + + src = grgsm.burst_source_qa(self.framenumbers_input, self.timeslots_input, self.bursts_input) + splitter = grgsm.burst_sdcch_subslot_splitter(grgsm.SPLITTER_SDCCH8) + sink_0 = grgsm.burst_sink_qa() + sink_1 = grgsm.burst_sink_qa() + sink_2 = grgsm.burst_sink_qa() + sink_3 = grgsm.burst_sink_qa() + sink_4 = grgsm.burst_sink_qa() + sink_5 = grgsm.burst_sink_qa() + sink_6 = grgsm.burst_sink_qa() + sink_7 = grgsm.burst_sink_qa() + + self.tb.msg_connect(src, "out", splitter, "in") + self.tb.msg_connect(splitter, "out0", sink_0, "in") + self.tb.msg_connect(splitter, "out1", sink_1, "in") + self.tb.msg_connect(splitter, "out2", sink_2, "in") + self.tb.msg_connect(splitter, "out3", sink_3, "in") + self.tb.msg_connect(splitter, "out4", sink_4, "in") + self.tb.msg_connect(splitter, "out5", sink_5, "in") + self.tb.msg_connect(splitter, "out6", sink_6, "in") + self.tb.msg_connect(splitter, "out7", sink_7, "in") + + self.tb.run () + + bursts_result_0 = list(sink_0.get_burst_data()) + bursts_result_1 = list(sink_1.get_burst_data()) + bursts_result_2 = list(sink_2.get_burst_data()) + bursts_result_3 = list(sink_3.get_burst_data()) + bursts_result_4 = list(sink_4.get_burst_data()) + bursts_result_5 = list(sink_5.get_burst_data()) + bursts_result_6 = list(sink_6.get_burst_data()) + bursts_result_7 = list(sink_7.get_burst_data()) + + self.assertEqual(bursts_expected_0, bursts_result_0) + self.assertEqual(bursts_expected_1, bursts_result_1) + self.assertEqual(bursts_expected_2, bursts_result_2) + self.assertEqual(bursts_expected_3, bursts_result_3) + self.assertEqual(bursts_expected_4, bursts_result_4) + self.assertEqual(bursts_expected_5, bursts_result_5) + self.assertEqual(bursts_expected_6, bursts_result_6) + self.assertEqual(bursts_expected_7, bursts_result_7) + + + def test_002_sdcch4 (self): + + bursts_expected_0 = [ + '0000100100010010111100111000011000001100100001110101110011011001011011101111000100101111001011000000010111001011110011000000001101100001001000100000', + '0001010000110010100010110111101111100100000011111000000010111010011101011000001001110101111100000011101010001010100001101000011010110000001001111000', + '0001101101111011000010001000000010001110101111001111111111110001011011101111000100101110110001011010110110100111000000010010101110111001111011000000', + '0001101000100010100001101100100101011100111000001101001010100010011101011000001001110100011100101100000010110101011011100111111011111101100000011000', + '0000100101010011010110101001100100110001011010111110110100011101001111101100010100111110111000110110100011001010110011000111011111110011001011100000', + '0001000110100001111010110101011111001000011100001111010110001001011011101111000100101111100001011001100110011001110101100001000001011011111110100000', + '0001011010100110001000100000001110010000011000111001001110000001001011100001000100101110011011011001000111101010001010111001101100000100001101001000', + '0000001010000101101010000000110000010101111011100110101000110111011110001001011101111001100011100100100100100000010010001111101111110011000001011000', + '0000001000011111101111110000000000001100011111011010111010000111011110001001011101111001001100000001010100111111011000000110010111101001110010011000', + '0000100000011100011111001001001000001000100010010111101011101010011101011000001001110100000000010010011001110100101111001110111111010000010001000000', + '0001000101001011001111111101010111110010010110111111110000010001011011101111000100101111000100010000111110011101000001111100001001100100011100011000', + '0001101101101010110000001001110111001001000001110110110000110001001011100001000100101111100001110001000000110101100001111111001001111001101101100000', + ] + + bursts_expected_1 = [ + '0001010110101101110000011111101100001000001001110101100000011010001111011010001000111100000100110001111110110111010101011011011100111000101111010000', + '0000010000111000010001010010111110000100011000000101110110001000110101110010000011010111001100010011100001111101000101011110100001100010010110001000', + '0000011110101100001001101000001010010100100111101101101000110101001111101100010100111111011001110000011000100001010011100000001100010110101001001000', + '0001110111101011100000001011111101100110110001001100101111110010000111011101001000011101110010001111000010011110001101101111101011100001001100100000', + '0000000111000111010110000000001001101110001001001101100110010001011011101111000100101111101011111100101001110100101000011100111001001101101011101000', + '0000100100010111010011100110101011011010001011011011011101110010001111011010001000111100000110010111001010011100000011111100111000100100101010110000', + '0000101111000000100110100001011000000011111111010101010011011010000111011101001000011101110010101101000100100000001100001000100111001010010000111000', + '0000001001001101110111111011010011000011100001100011110011010001001011100001000100101110011100000010010111101100101011011111101011000000001100101000', + '0000110011100000100000000010100100011001001000110010110101111001001011100001000100101110000111001100111111110011011001000001001000001111001101001000', + '0001001111100001110110001010100011100011110011100001010100001001001011100001000100101111001000101100111101001010111000010111101000000001101100101000', + '0000101001000010000001100001000011001010100011110111101110111001001011100001000100101110001010100101111010111000000010111011000010011001101000001000', + '0001101000000100110100110001010111010111111001101110110101100111011110001001011101111001000110010011100100000100011101110110111010001001000111101000', + ] + + bursts_expected_2 = [ + '0001110111001111101101110111110000001110111011011100110110001001001011100001000100101110100101001001000110101110111110100110100100111111011001011000', + '0001011111010100110010101100011000100011000011111000111100010101001111101100010100111111100110001110010110001110000101110000100101010111100100111000', + '0001000100110100001010000101011001010000001111001110011010001001001011100001000100101111100011000100111100100010111001010010110100010000110000110000', + '0001001100101001010111000101000101000000111101011111000001011010001111011010001000111100110110011000000011010000100110111101110011110011000011010000', + '0001110110111100101101010011111100101100100100110001110110111001001011100001000100101110010111011011100001001010010100010101110100011111010101001000', + '0000111001001000110010011110000010011101000001010111011011111010011101011000001001110101011101101100101110010111010001100100000011100100111101010000', + '0001000001010011101010101011111100010010101110100001000111110010011101011000001001110101100000100101011101111101101101111000001101101010001000101000', + '0001101000001011010011001010011010100110010100011010101101011010000111011101001000011101100010011011111111101011100110000011110110001111000101101000', + '0001011000010101011100101011111010110101011110011011001011010010001111011010001000111100110111000110100100001100110100000001100100100111101010011000', + '0001010101101101101001011100101001110000100101011110100011100010011101011000001001110100111100001000000111000001111100011011101000101100111100111000', + '0000010101001010001110001001101101011011000110011011110111111000110101110010000011010110000000110010100100111001010110110011011101011001110100100000', + '0001111111000101100000111010111010011010011110110010111000010101001111101100010100111110000110010011101101011111001000010001111111000111001111011000', + ] + + bursts_expected_3 = [ + '0001011010100110110011000101111111010011110001101000011100101000110101110010000011010110110100000111011101000001101010100001110111001011010101111000', + '0000101010001100010011010101011110010101101110011110100110001010001111011010001000111100000010011011100001010001001111111100011111000011001010011000', + '0000111001011100101100111001010101000101010111011110111101010001001011100001000100101111100010100101111011000101100000101111000101011110011111100000', + '0000010101101111011001100001011100100101001000110111010110001111011110001001011101111000011010010010101111010000110000011001101011100000111110000000', + '0000001010101101011001000000001000001001110100000111000000101001001011100001000100101110111111011101110101010011001110111111101001011010110000101000', + '0001011110101111110100110010010110011100111010011001001110011111011110001001011101111000101010001111000111000101111000100011100010100010010100010000', + '0001000001011110010010100001100010111111000111001111010101011111011110001001011101111001010010100101110110111111001111110010111100111010110011110000', + '0001111100100010101100010111000000011011001111001101101001000010001111011010001000111101111000000101111001110101101001101010001110100111101011001000', + '0000100101100011001010101100011110000111001110010010010000100001011011101111000100101110001111010000001000001101011010110101010111011011001101101000', + '0000110000111101100001011100100011101011011000111100001000000111011110001001011101111000111000000111100100101000000101100011011001111100110011110000', + '0000011001111001100111110110110000001111110101011110100011010010011101011000001001110101001101110111111100001001000101101101100110001111101011010000', + '0000100001011010001010000101110000111100011110110010000010101000110101110010000011010111010001010101111111111101101100110101111010110100001110101000', + ] + + src = grgsm.burst_source_qa(self.framenumbers_input, self.timeslots_input, self.bursts_input) + splitter = grgsm.burst_sdcch_subslot_splitter(grgsm.SPLITTER_SDCCH4) + sink_0 = grgsm.burst_sink_qa() + sink_1 = grgsm.burst_sink_qa() + sink_2 = grgsm.burst_sink_qa() + sink_3 = grgsm.burst_sink_qa() + + self.tb.msg_connect(src, "out", splitter, "in") + self.tb.msg_connect(splitter, "out0", sink_0, "in") + self.tb.msg_connect(splitter, "out1", sink_1, "in") + self.tb.msg_connect(splitter, "out2", sink_2, "in") + self.tb.msg_connect(splitter, "out3", sink_3, "in") + + self.tb.run () + + bursts_result_0 = list(sink_0.get_burst_data()) + bursts_result_1 = list(sink_1.get_burst_data()) + bursts_result_2 = list(sink_2.get_burst_data()) + bursts_result_3 = list(sink_3.get_burst_data()) + + self.assertEqual(bursts_expected_0, bursts_result_0) + self.assertEqual(bursts_expected_1, bursts_result_1) + self.assertEqual(bursts_expected_2, bursts_result_2) + self.assertEqual(bursts_expected_3, bursts_result_3) + + +if __name__ == '__main__': + gr_unittest.run(qa_burst_sdcch_subslot_splitter, "qa_burst_sdcch_subslot_splitter.xml") diff --git a/swig/grgsm_swig.i b/swig/grgsm_swig.i index ba53b78..b9dad13 100644 --- a/swig/grgsm_swig.i +++ b/swig/grgsm_swig.i @@ -17,6 +17,7 @@ #include "grgsm/demapping/universal_ctrl_chans_demapper.h" #include "grgsm/demapping/tch_f_chans_demapper.h" #include "grgsm/flow_control/burst_timeslot_splitter.h" +#include "grgsm/flow_control/burst_sdcch_subslot_splitter.h" #include "grgsm/flow_control/burst_fnr_filter.h" #include "grgsm/flow_control/dummy_burst_filter.h" #include "grgsm/misc_utils/bursts_printer.h" @@ -54,6 +55,8 @@ GR_SWIG_BLOCK_MAGIC2(gsm, tch_f_chans_demapper); %include "grgsm/flow_control/burst_timeslot_splitter.h" GR_SWIG_BLOCK_MAGIC2(gsm, burst_timeslot_splitter); +%include "grgsm/flow_control/burst_sdcch_subslot_splitter.h" +GR_SWIG_BLOCK_MAGIC2(gsm, burst_sdcch_subslot_splitter); %include "grgsm/flow_control/burst_fnr_filter.h" GR_SWIG_BLOCK_MAGIC2(gsm, burst_fnr_filter); %include "grgsm/flow_control/dummy_burst_filter.h"