Merged origin/msg-file-sink-source-101 into dev, fixed conflicts. Issue #101
diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt
index caf2660..2b94539 100644
--- a/grc/CMakeLists.txt
+++ b/grc/CMakeLists.txt
@@ -21,8 +21,8 @@
add_subdirectory(decryption)
add_subdirectory(demapping)
add_subdirectory(receiver)
+add_subdirectory(flow_control)
add_subdirectory(misc_utils)
install(FILES
- gsm_block_tree.xml
- DESTINATION share/gnuradio/grc/blocks
+ gsm_block_tree.xml DESTINATION share/gnuradio/grc/blocks
)
diff --git a/grc/flow_control/CMakeLists.txt b/grc/flow_control/CMakeLists.txt
new file mode 100644
index 0000000..107fac7
--- /dev/null
+++ b/grc/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(FILES
+ gsm_burst_timeslot_splitter.xml
+ gsm_burst_fnr_filter.xml
+ gsm_dummy_burst_filter.xml
+ gsm_burst_sdcch_subslot_splitter.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 @@
+<?xml version="1.0"?>
+<block>
+ <name>Burst framenumber filter</name>
+ <key>gsm_burst_fnr_filter</key>
+ <import>import grgsm</import>
+ <make>grgsm.burst_fnr_filter($mode, $fnr)</make>
+
+ <param>
+ <name>Mode</name>
+ <key>mode</key>
+ <type>enum</type>
+ <option>
+ <name>Less or equal</name>
+ <key>grgsm.FILTER_LESS_OR_EQUAL</key>
+ </option>
+ <option>
+ <name>Greater or equal</name>
+ <key>grgsm.FILTER_GREATER_OR_EQUAL</key>
+ </option>
+ </param>
+ <param>
+ <name>Framenumber</name>
+ <key>fnr</key>
+ <value>1500123</value>
+ <type>int</type>
+ </param>
+
+ <sink>
+ <name>in</name>
+ <type>message</type>
+ </sink>
+
+ <source>
+ <name>out</name>
+ <type>message</type>
+ <optional>1</optional>
+ </source>
+
+ <doc>
+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.
+ </doc>
+</block>
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 @@
+<?xml version="1.0"?>
+<block>
+ <name>Burst SDCCH subslot splitter</name>
+ <key>gsm_burst_sdcch_subslot_splitter</key>
+ <import>import grgsm</import>
+ <make>grgsm.burst_sdcch_subslot_splitter(
+#if int($ports())==4 #
+grgsm.SPLITTER_SDCCH4
+#else
+grgsm.SPLITTER_SDCCH8
+#end if
+ )</make>
+
+ <param>
+ <name>Mode</name>
+ <key>ports</key>
+ <type>enum</type>
+ <option>
+ <name>SDCCH/8</name>
+ <key>8</key>
+ </option>
+ <option>
+ <name>SDCCH/4</name>
+ <key>4</key>
+ </option>
+ </param>
+
+ <sink>
+ <name>in</name>
+ <type>message</type>
+ </sink>
+
+ <source>
+ <name>out</name>
+ <type>message</type>
+ <nports>$ports</nports>
+ <optional>1</optional>
+ </source>
+
+ <doc>
+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.
+ </doc>
+</block>
\ No newline at end of file
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 @@
+<?xml version="1.0"?>
+<block>
+ <name>Burst timeslot splitter</name>
+ <key>gsm_burst_timeslot_splitter</key>
+ <import>import grgsm</import>
+ <make>grgsm.burst_timeslot_splitter()</make>
+
+ <sink>
+ <name>in</name>
+ <type>message</type>
+ </sink>
+
+ <source>
+ <name>out</name>
+ <type>message</type>
+ <nports>8</nports>
+ <optional>1</optional>
+ </source>
+
+ <doc>
+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.
+ </doc>
+</block>
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 @@
+<?xml version="1.0"?>
+<block>
+ <name>Dummy burst filter</name>
+ <key>gsm_dummy_burst_filter</key>
+ <import>import grgsm</import>
+ <make>grgsm.dummy_burst_filter()</make>
+
+ <sink>
+ <name>in</name>
+ <type>message</type>
+ </sink>
+
+ <source>
+ <name>out</name>
+ <type>message</type>
+ <optional>1</optional>
+ </source>
+
+ <doc>
+This block filters dummy bursts.
+
+For more information on dummy bursts, see GSM 05.02.
+ </doc>
+</block>
diff --git a/grc/gsm_block_tree.xml b/grc/gsm_block_tree.xml
index 6496fd3..26f607f 100644
--- a/grc/gsm_block_tree.xml
+++ b/grc/gsm_block_tree.xml
@@ -38,14 +38,19 @@
<block>gsm_tch_f_decoder</block>
</cat>
<cat>
+ <name>Flow control</name>
+ <block>gsm_burst_timeslot_splitter</block>
+ <block>gsm_burst_sdcch_subslot_splitter</block>
+ <block>gsm_burst_fnr_filter</block>
+ <block>gsm_dummy_burst_filter</block>
+ </cat>
+ <cat>
<name>Utilities</name>
<block>gsm_bursts_printer</block>
- <block>gsm_burst_sink</block>
- <block>gsm_burst_source</block>
+ <block>gsm_burst_file_sink</block>
+ <block>gsm_burst_file_source</block>
<block>gsm_message_file_sink</block>
<block>gsm_message_file_source</block>
- <block>gsm_burst_sink_qa</block>
- <block>gsm_burst_source_qa</block>
<block>gsm_extract_system_info</block>
<block>gsm_extract_immediate_assignment</block>
<block>gsm_controlled_rotator_cc</block>
diff --git a/grc/misc_utils/CMakeLists.txt b/grc/misc_utils/CMakeLists.txt
index 0ace0d8..99985a1 100644
--- a/grc/misc_utils/CMakeLists.txt
+++ b/grc/misc_utils/CMakeLists.txt
@@ -26,10 +26,8 @@
gsm_bursts_printer.xml
gsm_clock_offset_corrector.xml
gsm_tmsi_dumper.xml
+ gsm_burst_file_sink.xml
+ gsm_burst_file_source.xml
gsm_message_file_sink.xml
- gsm_message_file_source.xml
- gsm_burst_sink.xml
- gsm_burst_source.xml
- gsm_burst_source_qa.xml
- gsm_burst_sink_qa.xml DESTINATION share/gnuradio/grc/blocks
+ gsm_message_file_source.xml DESTINATION share/gnuradio/grc/blocks
)
diff --git a/grc/misc_utils/gsm_burst_sink.xml b/grc/misc_utils/gsm_burst_file_sink.xml
similarity index 70%
rename from grc/misc_utils/gsm_burst_sink.xml
rename to grc/misc_utils/gsm_burst_file_sink.xml
index a0e7532..e468e5f 100644
--- a/grc/misc_utils/gsm_burst_sink.xml
+++ b/grc/misc_utils/gsm_burst_file_sink.xml
@@ -1,9 +1,9 @@
<?xml version="1.0"?>
<block>
- <name>Burst sink</name>
- <key>gsm_burst_sink</key>
+ <name>Burst file sink</name>
+ <key>gsm_burst_file_sink</key>
<import>import grgsm</import>
- <make>grgsm.burst_sink($filename)</make>
+ <make>grgsm.burst_file_sink($filename)</make>
<param>
<name>Destination file</name>
diff --git a/grc/misc_utils/gsm_burst_source.xml b/grc/misc_utils/gsm_burst_file_source.xml
similarity index 69%
rename from grc/misc_utils/gsm_burst_source.xml
rename to grc/misc_utils/gsm_burst_file_source.xml
index 9e78069..e32a708 100644
--- a/grc/misc_utils/gsm_burst_source.xml
+++ b/grc/misc_utils/gsm_burst_file_source.xml
@@ -1,9 +1,9 @@
<?xml version="1.0"?>
<block>
- <name>Burst source</name>
- <key>gsm_burst_source</key>
+ <name>Burst file source</name>
+ <key>gsm_burst_file_source</key>
<import>import grgsm</import>
- <make>grgsm.burst_source($filename)</make>
+ <make>grgsm.burst_file_source($filename)</make>
<param>
<name>Source file</name>
diff --git a/grc/misc_utils/gsm_burst_sink_qa.xml b/grc/misc_utils/gsm_burst_sink_qa.xml
deleted file mode 100644
index c028da3..0000000
--- a/grc/misc_utils/gsm_burst_sink_qa.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0"?>
-<block>
- <name>QA Burst sink</name>
- <key>gsm_burst_sink_qa</key>
- <import>import grgsm</import>
- <make>grgsm.burst_sink_qa()</make>
-
- <sink>
- <name>in</name>
- <type>message</type>
- </sink>
-</block>
diff --git a/grc/misc_utils/gsm_bursts_printer.xml b/grc/misc_utils/gsm_bursts_printer.xml
index abdb532..821e6bb 100644
--- a/grc/misc_utils/gsm_bursts_printer.xml
+++ b/grc/misc_utils/gsm_bursts_printer.xml
@@ -4,7 +4,8 @@
<key>gsm_bursts_printer</key>
<import>import grgsm</import>
<import>import pmt</import>
- <make>grgsm.bursts_printer(pmt.intern($prepend_string), $prepend_fnr, $prepend_frame_count, $print_payload_only)</make>
+ <make>grgsm.bursts_printer(pmt.intern($prepend_string), $prepend_fnr,
+ $prepend_frame_count, $print_payload_only, $ignore_dummy_bursts)</make>
<param>
<name>Prepend String</name>
@@ -55,6 +56,20 @@
<key>True</key>
</option>
</param>
+ <param>
+ <name>Ignore dummy bursts</name>
+ <key>ignore_dummy_bursts</key>
+ <value>False</value>
+ <type>bool</type>
+ <option>
+ <name>False</name>
+ <key>False</key>
+ </option>
+ <option>
+ <name>True</name>
+ <key>True</key>
+ </option>
+ </param>
<sink>
<name>bursts</name>
@@ -70,6 +85,8 @@
If "Print payload only" is enabled, then only the two data blocks of a burst are printed, tail bits, stealing bits and training sequence are omitted.
-Enabling all three options results in an output that is similar to the output of airprobe, i.e. the format is "frame_nr frame_count: databits"
+If "Ignore dummy bursts" is enabled, then the burst printer will not print dummy bursts (see GSM 05.02)
+
+Enabling first three options (or all four options) results in an output that is similar to the output of airprobe, i.e. the format is "frame_nr frame_count: databits"
</doc>
</block>
diff --git a/grc/misc_utils/gsm_message_printer.xml b/grc/misc_utils/gsm_message_printer.xml
index 8b44b22..7e390ed 100644
--- a/grc/misc_utils/gsm_message_printer.xml
+++ b/grc/misc_utils/gsm_message_printer.xml
@@ -4,7 +4,7 @@
<key>gsm_message_printer</key>
<import>import grgsm</import>
<import>import pmt</import>
- <make>grgsm.message_printer(pmt.intern($prepend_string))</make>
+ <make>grgsm.message_printer(pmt.intern($prepend_string), $print_gsmtap_header)</make>
<param>
<name>Prepend String</name>
@@ -13,6 +13,20 @@
<type>string</type>
<hide>part</hide>
</param>
+ <param>
+ <name>Print GSMTap header</name>
+ <key>print_gsmtap_header</key>
+ <value>False</value>
+ <type>bool</type>
+ <option>
+ <name>False</name>
+ <key>False</key>
+ </option>
+ <option>
+ <name>True</name>
+ <key>True</key>
+ </option>
+ </param>
<sink>
<name>msgs</name>
diff --git a/grc/qa_utils/CMakeLists.txt b/grc/qa_utils/CMakeLists.txt
new file mode 100644
index 0000000..1f57aa1
--- /dev/null
+++ b/grc/qa_utils/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(FILES
+ gsm_burst_source.xml
+ gsm_burst_sink.xml
+ gsm_message_source.xml
+ gsm_message_sink.xml DESTINATION share/gnuradio/grc/blocks
+)
diff --git a/grc/qa_utils/gsm_burst_sink.xml b/grc/qa_utils/gsm_burst_sink.xml
new file mode 100644
index 0000000..740960f
--- /dev/null
+++ b/grc/qa_utils/gsm_burst_sink.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<block>
+ <name>Burst sink</name>
+ <key>gsm_burst_sink</key>
+ <import>import grgsm</import>
+ <make>grgsm.burst_sink()</make>
+
+ <sink>
+ <name>in</name>
+ <type>message</type>
+ </sink>
+</block>
diff --git a/grc/misc_utils/gsm_burst_source_qa.xml b/grc/qa_utils/gsm_burst_source.xml
similarity index 79%
rename from grc/misc_utils/gsm_burst_source_qa.xml
rename to grc/qa_utils/gsm_burst_source.xml
index bb04cca..9f55ac5 100644
--- a/grc/misc_utils/gsm_burst_source_qa.xml
+++ b/grc/qa_utils/gsm_burst_source.xml
@@ -1,9 +1,9 @@
<?xml version="1.0"?>
<block>
- <name>QA Burst source</name>
- <key>gsm_burst_source_qa</key>
+ <name>Burst source</name>
+ <key>gsm_burst_source</key>
<import>import grgsm</import>
- <make>grgsm.burst_source_qa($framenumbers, $timeslots, $bursts)</make>
+ <make>grgsm.burst_source($framenumbers, $timeslots, $bursts)</make>
<param>
<name>Frame numbers</name>
diff --git a/grc/qa_utils/gsm_message_sink.xml b/grc/qa_utils/gsm_message_sink.xml
new file mode 100644
index 0000000..e0d6ac0
--- /dev/null
+++ b/grc/qa_utils/gsm_message_sink.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<block>
+ <name>Message Sink</name>
+ <key>gsm_message_sink</key>
+ <import>import grgsm</import>
+ <make>grgsm.message_sink()</make>
+
+ <sink>
+ <name>in</name>
+ <type>message</type>
+ </sink>
+
+ <doc>
+This block is a message sink for testing purposes.
+
+The data can be retrieved using function get_messages()
+
+ </doc>
+</block>
diff --git a/grc/qa_utils/gsm_message_source.xml b/grc/qa_utils/gsm_message_source.xml
new file mode 100644
index 0000000..ab06f65
--- /dev/null
+++ b/grc/qa_utils/gsm_message_source.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<block>
+ <name>Message Source</name>
+ <key>gsm_message_source</key>
+ <import>import grgsm</import>
+ <make>grgsm.message_source($messages)</make>
+
+ <param>
+ <name>Messages</name>
+ <key>messages</key>
+ <value>["02 04 01 00 00 00 c9 00 00 1d 3c e5 02 00 01 00 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b",
+"02 04 01 00 00 00 ca 00 00 1d 3c e9 02 00 02 00 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b",
+"02 04 01 00 00 00 cb 00 00 1d 3d 0e 01 00 00 00 59 06 1a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff e5 04 00",
+"02 04 01 00 00 00 cb 00 00 1d 3d 12 02 00 00 00 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b"]</value>
+ <type>raw</type>
+ <hide>true</hide>
+ </param>
+
+ <source>
+ <name>msgs</name>
+ <type>message</type>
+ </source>
+
+ <doc>
+This block is a basic message source for testing purposes.
+
+It takes a list of strings as input, where each string
+is a whitespace-separated list of hexadecimal values representing the data bytes of a message including the gsmtap header.
+
+Such strings can be obtained using the message printer with option "Print GSMTap header"
+ </doc>
+</block>
diff --git a/include/grgsm/CMakeLists.txt b/include/grgsm/CMakeLists.txt
index fd44c54..e9f6cc2 100644
--- a/include/grgsm/CMakeLists.txt
+++ b/include/grgsm/CMakeLists.txt
@@ -32,4 +32,5 @@
add_subdirectory(demapping)
add_subdirectory(receiver)
add_subdirectory(misc_utils)
-
+add_subdirectory(qa_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..0a1a95a
--- /dev/null
+++ b/include/grgsm/flow_control/CMakeLists.txt
@@ -0,0 +1,28 @@
+# 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
+ burst_sdcch_subslot_splitter.h
+ burst_fnr_filter.h
+ dummy_burst_filter.h DESTINATION include/grgsm/flow_control
+)
diff --git a/include/grgsm/misc_utils/burst_sink.h b/include/grgsm/flow_control/burst_fnr_filter.h
similarity index 63%
copy from include/grgsm/misc_utils/burst_sink.h
copy to include/grgsm/flow_control/burst_fnr_filter.h
index 6903df9..9451d58 100644
--- a/include/grgsm/misc_utils/burst_sink.h
+++ b/include/grgsm/flow_control/burst_fnr_filter.h
@@ -1,5 +1,6 @@
/* -*- c++ -*- */
-/* @file
+/*
+ * @file
* @author Roman Khassraf <rkhassraf@gmail.com>
* @section LICENSE
*
@@ -17,11 +18,11 @@
* 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_SINK_H
-#define INCLUDED_GSM_BURST_SINK_H
+
+#ifndef INCLUDED_GSM_BURST_FNR_FILTER_H
+#define INCLUDED_GSM_BURST_FNR_FILTER_H
#include <grgsm/api.h>
#include <gnuradio/block.h>
@@ -29,28 +30,35 @@
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_sink : virtual public gr::block
+ class GSM_API burst_fnr_filter : virtual public gr::block
{
public:
- typedef boost::shared_ptr<burst_sink> sptr;
+ typedef boost::shared_ptr<burst_fnr_filter> sptr;
/*!
- * \brief Return a shared_ptr to a new instance of grgsm::burst_sink.
+ * \brief Return a shared_ptr to a new instance of gsm::burst_fnr_filter.
*
- * To avoid accidental use of raw pointers, grgsm::burst_sink's
+ * To avoid accidental use of raw pointers, gsm::burst_fnr_filter's
* constructor is in a private implementation
- * class. grgsm::burst_sink::make is the public interface for
+ * class. gsm::burst_fnr_filter::make is the public interface for
* creating new instances.
*/
- static sptr make(const std::string &filename);
+ static sptr make(filter_mode mode, unsigned int fnr);
+
};
+
} // namespace gsm
} // namespace gr
-#endif /* INCLUDED_GSM_BURST_SINK_H */
-
+#endif /* INCLUDED_GSM_BURST_FNR_FILTER_H */
diff --git a/include/grgsm/misc_utils/burst_sink.h b/include/grgsm/flow_control/burst_sdcch_subslot_splitter.h
similarity index 68%
copy from include/grgsm/misc_utils/burst_sink.h
copy to include/grgsm/flow_control/burst_sdcch_subslot_splitter.h
index 6903df9..aee2a24 100644
--- a/include/grgsm/misc_utils/burst_sink.h
+++ b/include/grgsm/flow_control/burst_sdcch_subslot_splitter.h
@@ -20,37 +20,42 @@
*
*/
-#ifndef INCLUDED_GSM_BURST_SINK_H
-#define INCLUDED_GSM_BURST_SINK_H
+#ifndef INCLUDED_GSM_BURST_SDCCH_SUBSLOT_SPLITTER_H
+#define INCLUDED_GSM_BURST_SDCCH_SUBSLOT_SPLITTER_H
#include <grgsm/api.h>
#include <gnuradio/block.h>
namespace gr {
namespace gsm {
+
+ enum splitter_mode
+ {
+ SPLITTER_SDCCH8,
+ SPLITTER_SDCCH4
+ };
/*!
* \brief <+description of block+>
* \ingroup gsm
*
*/
- class GSM_API burst_sink : virtual public gr::block
+ class GSM_API burst_sdcch_subslot_splitter : virtual public gr::block
{
public:
- typedef boost::shared_ptr<burst_sink> sptr;
+ typedef boost::shared_ptr<burst_sdcch_subslot_splitter> sptr;
/*!
- * \brief Return a shared_ptr to a new instance of grgsm::burst_sink.
+ * \brief Return a shared_ptr to a new instance of grgsm::burst_sdcch_subslot_splitter.
*
- * To avoid accidental use of raw pointers, grgsm::burst_sink's
+ * To avoid accidental use of raw pointers, grgsm::burst_sdcch_subslot_splitter's
* constructor is in a private implementation
- * class. grgsm::burst_sink::make is the public interface for
+ * class. grgsm::burst_sdcch_subslot_splitter::make is the public interface for
* creating new instances.
*/
- static sptr make(const std::string &filename);
+ static sptr make(splitter_mode mode);
};
} // namespace gsm
} // namespace gr
-#endif /* INCLUDED_GSM_BURST_SINK_H */
-
+#endif /* INCLUDED_GSM_BURST_SDCCH_SUBSLOT_SPLITTER_H */
diff --git a/include/grgsm/misc_utils/burst_sink.h b/include/grgsm/flow_control/burst_timeslot_splitter.h
similarity index 70%
copy from include/grgsm/misc_utils/burst_sink.h
copy to include/grgsm/flow_control/burst_timeslot_splitter.h
index 6903df9..ee6298e 100644
--- a/include/grgsm/misc_utils/burst_sink.h
+++ b/include/grgsm/flow_control/burst_timeslot_splitter.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef INCLUDED_GSM_BURST_SINK_H
-#define INCLUDED_GSM_BURST_SINK_H
+#ifndef INCLUDED_GSM_BURST_TIMESLOT_SPLITTER_H
+#define INCLUDED_GSM_BURST_TIMESLOT_SPLITTER_H
#include <grgsm/api.h>
#include <gnuradio/block.h>
@@ -34,23 +34,22 @@
* \ingroup gsm
*
*/
- class GSM_API burst_sink : virtual public gr::block
+ class GSM_API burst_timeslot_splitter : virtual public gr::block
{
public:
- typedef boost::shared_ptr<burst_sink> sptr;
+ typedef boost::shared_ptr<burst_timeslot_splitter> sptr;
/*!
- * \brief Return a shared_ptr to a new instance of grgsm::burst_sink.
+ * \brief Return a shared_ptr to a new instance of grgsm::burst_timeslot_splitter.
*
- * To avoid accidental use of raw pointers, grgsm::burst_sink's
+ * To avoid accidental use of raw pointers, grgsm::burst_timeslot_splitter's
* constructor is in a private implementation
- * class. grgsm::burst_sink::make is the public interface for
+ * class. grgsm::burst_timeslot_splitter::make is the public interface for
* creating new instances.
*/
- static sptr make(const std::string &filename);
+ static sptr make();
};
} // namespace gsm
} // namespace gr
-#endif /* INCLUDED_GSM_BURST_SINK_H */
-
+#endif /* INCLUDED_GSM_BURST_TIMESLOT_SPLITTER_H */
diff --git a/include/grgsm/misc_utils/burst_sink.h b/include/grgsm/flow_control/dummy_burst_filter.h
similarity index 72%
copy from include/grgsm/misc_utils/burst_sink.h
copy to include/grgsm/flow_control/dummy_burst_filter.h
index 6903df9..0922433 100644
--- a/include/grgsm/misc_utils/burst_sink.h
+++ b/include/grgsm/flow_control/dummy_burst_filter.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef INCLUDED_GSM_BURST_SINK_H
-#define INCLUDED_GSM_BURST_SINK_H
+#ifndef INCLUDED_GSM_DUMMY_BURST_FILTER_H
+#define INCLUDED_GSM_DUMMY_BURST_FILTER_H
#include <grgsm/api.h>
#include <gnuradio/block.h>
@@ -34,23 +34,22 @@
* \ingroup gsm
*
*/
- class GSM_API burst_sink : virtual public gr::block
+ class GSM_API dummy_burst_filter : virtual public gr::block
{
public:
- typedef boost::shared_ptr<burst_sink> sptr;
+ typedef boost::shared_ptr<dummy_burst_filter> sptr;
/*!
- * \brief Return a shared_ptr to a new instance of grgsm::burst_sink.
+ * \brief Return a shared_ptr to a new instance of grgsm::dummy_burst_filter.
*
- * To avoid accidental use of raw pointers, grgsm::burst_sink's
+ * To avoid accidental use of raw pointers, grgsm::dummy_burst_filter's
* constructor is in a private implementation
- * class. grgsm::burst_sink::make is the public interface for
+ * class. grgsm::dummy_burst_filter::make is the public interface for
* creating new instances.
*/
- static sptr make(const std::string &filename);
+ static sptr make();
};
} // namespace gsm
} // namespace gr
-#endif /* INCLUDED_GSM_BURST_SINK_H */
-
+#endif /* INCLUDED_GSM_DUMMY_BURST_FILTER_H */
diff --git a/include/grgsm/misc_utils/CMakeLists.txt b/include/grgsm/misc_utils/CMakeLists.txt
index a7b9d67..d85ac21 100644
--- a/include/grgsm/misc_utils/CMakeLists.txt
+++ b/include/grgsm/misc_utils/CMakeLists.txt
@@ -22,16 +22,14 @@
########################################################################
install(FILES
bursts_printer.h
- burst_sink.h
- burst_source.h
+ burst_file_source.h
+ burst_file_sink.h
message_file_sink.h
message_file_source.h
- burst_sink_qa.h
- burst_source_qa.h
extract_system_info.h
extract_immediate_assignment.h
controlled_rotator_cc.h
controlled_const_source_f.h
- message_printer.h
+ message_printer.h
tmsi_dumper.h DESTINATION include/grgsm/misc_utils
)
diff --git a/include/grgsm/misc_utils/burst_sink.h b/include/grgsm/misc_utils/burst_file_sink.h
similarity index 75%
copy from include/grgsm/misc_utils/burst_sink.h
copy to include/grgsm/misc_utils/burst_file_sink.h
index 6903df9..7263baa 100644
--- a/include/grgsm/misc_utils/burst_sink.h
+++ b/include/grgsm/misc_utils/burst_file_sink.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef INCLUDED_GSM_BURST_SINK_H
-#define INCLUDED_GSM_BURST_SINK_H
+#ifndef INCLUDED_GSM_BURST_FILE_SINK_H
+#define INCLUDED_GSM_BURST_FILE_SINK_H
#include <grgsm/api.h>
#include <gnuradio/block.h>
@@ -34,17 +34,17 @@
* \ingroup gsm
*
*/
- class GSM_API burst_sink : virtual public gr::block
+ class GSM_API burst_file_sink : virtual public gr::block
{
public:
- typedef boost::shared_ptr<burst_sink> sptr;
+ typedef boost::shared_ptr<burst_file_sink> sptr;
/*!
- * \brief Return a shared_ptr to a new instance of grgsm::burst_sink.
+ * \brief Return a shared_ptr to a new instance of grgsm::burst_file_sink.
*
- * To avoid accidental use of raw pointers, grgsm::burst_sink's
+ * To avoid accidental use of raw pointers, grgsm::burst_file_sink's
* constructor is in a private implementation
- * class. grgsm::burst_sink::make is the public interface for
+ * class. grgsm::burst_file_sink::make is the public interface for
* creating new instances.
*/
static sptr make(const std::string &filename);
@@ -52,5 +52,5 @@
} // namespace gsm
} // namespace gr
-#endif /* INCLUDED_GSM_BURST_SINK_H */
+#endif /* INCLUDED_GSM_BURST_FILE_SINK_H */
diff --git a/include/grgsm/misc_utils/burst_source.h b/include/grgsm/misc_utils/burst_file_source.h
similarity index 75%
rename from include/grgsm/misc_utils/burst_source.h
rename to include/grgsm/misc_utils/burst_file_source.h
index bd8644f..e18ef44 100644
--- a/include/grgsm/misc_utils/burst_source.h
+++ b/include/grgsm/misc_utils/burst_file_source.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef INCLUDED_GSM_BURST_SOURCE_H
-#define INCLUDED_GSM_BURST_SOURCE_H
+#ifndef INCLUDED_GSM_BURST_FILE_SOURCE_H
+#define INCLUDED_GSM_BURST_FILE_SOURCE_H
#include <grgsm/api.h>
#include <gnuradio/block.h>
@@ -34,17 +34,17 @@
* \ingroup gsm
*
*/
- class GSM_API burst_source : virtual public gr::block
+ class GSM_API burst_file_source : virtual public gr::block
{
public:
- typedef boost::shared_ptr<burst_source> sptr;
+ typedef boost::shared_ptr<burst_file_source> sptr;
/*!
- * \brief Return a shared_ptr to a new instance of grgsm::burst_source.
+ * \brief Return a shared_ptr to a new instance of grgsm::burst_file_source.
*
- * To avoid accidental use of raw pointers, grgsm::burst_source's
+ * To avoid accidental use of raw pointers, grgsm::burst_file_source's
* constructor is in a private implementation
- * class. grgsm::burst_source::make is the public interface for
+ * class. grgsm::burst_file_source::make is the public interface for
* creating new instances.
*/
static sptr make(const std::string &filename);
@@ -53,5 +53,5 @@
} // namespace gsm
} // namespace gr
-#endif /* INCLUDED_GSM_BURST_SOURCE_H */
+#endif /* INCLUDED_GSM_BURST_FILE_SOURCE_H */
diff --git a/include/grgsm/misc_utils/burst_sink_qa.h b/include/grgsm/misc_utils/burst_sink_qa.h
deleted file mode 100644
index 3b5cac2..0000000
--- a/include/grgsm/misc_utils/burst_sink_qa.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- c++ -*- */
-/* @file
- * @author Roman Khassraf <rkhassraf@gmail.com>
- * @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_SINK_QA_H
-#define INCLUDED_GSM_BURST_SINK_QA_H
-
-#include <grgsm/api.h>
-#include <gnuradio/block.h>
-
-namespace gr {
- namespace gsm {
-
- /*!
- * \brief <+description of block+>
- * \ingroup gsm
- *
- */
- class GSM_API burst_sink_qa : virtual public gr::block
- {
- public:
- typedef boost::shared_ptr<burst_sink_qa> sptr;
-
- /*!
- * \brief Return a shared_ptr to a new instance of grgsm::burst_sink_qa.
- *
- * To avoid accidental use of raw pointers, grgsm::burst_sink_qa's
- * constructor is in a private implementation
- * class. grgsm::burst_sink_qa::make is the public interface for
- * creating new instances.
- */
- static sptr make();
-
- virtual std::vector<int> get_framenumbers() = 0;
- virtual std::vector<int> get_timeslots() = 0;
- virtual std::vector<std::string> get_burst_data() = 0;
- };
- } // namespace gsm
-} // namespace gr
-
-#endif /* INCLUDED_GSM_BURST_SINK_QA_H */
-
diff --git a/include/grgsm/misc_utils/bursts_printer.h b/include/grgsm/misc_utils/bursts_printer.h
index 099bf08..eb006c5 100644
--- a/include/grgsm/misc_utils/bursts_printer.h
+++ b/include/grgsm/misc_utils/bursts_printer.h
@@ -51,7 +51,8 @@
* creating new instances.
*/
static sptr make(pmt::pmt_t prepend_string, bool prepend_fnr=false,
- bool prepend_frame_count=false, bool print_payload_only=false);
+ bool prepend_frame_count=false, bool print_payload_only=false,
+ bool ignore_dummy_bursts=false);
};
} // namespace gsm
diff --git a/include/grgsm/misc_utils/message_printer.h b/include/grgsm/misc_utils/message_printer.h
index 3914707..d40352f 100644
--- a/include/grgsm/misc_utils/message_printer.h
+++ b/include/grgsm/misc_utils/message_printer.h
@@ -48,7 +48,7 @@
* class. gsm::message_printer::make is the public interface for
* creating new instances.
*/
- static sptr make(pmt::pmt_t prepend_string);
+ static sptr make(pmt::pmt_t prepend_string, bool print_gsmtap_header=false);
};
} // namespace gsm
diff --git a/include/grgsm/qa_utils/CMakeLists.txt b/include/grgsm/qa_utils/CMakeLists.txt
new file mode 100644
index 0000000..44bbbfb
--- /dev/null
+++ b/include/grgsm/qa_utils/CMakeLists.txt
@@ -0,0 +1,28 @@
+# 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_sink.h
+ burst_source.h
+ message_source.h
+ message_sink.h DESTINATION include/grgsm/qa_utils
+)
diff --git a/include/grgsm/misc_utils/burst_sink.h b/include/grgsm/qa_utils/burst_sink.h
similarity index 88%
rename from include/grgsm/misc_utils/burst_sink.h
rename to include/grgsm/qa_utils/burst_sink.h
index 6903df9..266cbc8 100644
--- a/include/grgsm/misc_utils/burst_sink.h
+++ b/include/grgsm/qa_utils/burst_sink.h
@@ -47,7 +47,11 @@
* class. grgsm::burst_sink::make is the public interface for
* creating new instances.
*/
- static sptr make(const std::string &filename);
+ static sptr make();
+
+ virtual std::vector<int> get_framenumbers() = 0;
+ virtual std::vector<int> get_timeslots() = 0;
+ virtual std::vector<std::string> get_burst_data() = 0;
};
} // namespace gsm
} // namespace gr
diff --git a/include/grgsm/misc_utils/burst_source_qa.h b/include/grgsm/qa_utils/burst_source.h
similarity index 82%
rename from include/grgsm/misc_utils/burst_source_qa.h
rename to include/grgsm/qa_utils/burst_source.h
index c3c5713..bfed70f 100644
--- a/include/grgsm/misc_utils/burst_source_qa.h
+++ b/include/grgsm/qa_utils/burst_source.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef INCLUDED_GSM_BURST_SOURCE_QA_H
-#define INCLUDED_GSM_BURST_SOURCE_QA_H
+#ifndef INCLUDED_GSM_BURST_SOURCE_H
+#define INCLUDED_GSM_BURST_SOURCE_H
#include <grgsm/api.h>
#include <gnuradio/block.h>
@@ -34,17 +34,17 @@
* \ingroup gsm
*
*/
- class GSM_API burst_source_qa : virtual public gr::block
+ class GSM_API burst_source : virtual public gr::block
{
public:
- typedef boost::shared_ptr<burst_source_qa> sptr;
+ typedef boost::shared_ptr<burst_source> sptr;
/*!
- * \brief Return a shared_ptr to a new instance of grgsm::burst_source_qa.
+ * \brief Return a shared_ptr to a new instance of grgsm::burst_source.
*
- * To avoid accidental use of raw pointers, grgsm::burst_source_qa's
+ * To avoid accidental use of raw pointers, grgsm::burst_source's
* constructor is in a private implementation
- * class. grgsm::burst_source_qa::make is the public interface for
+ * class. grgsm::burst_source::make is the public interface for
* creating new instances.
*/
static sptr make(const std::vector<int> &framenumbers,
@@ -59,6 +59,6 @@
} // namespace gsm
} // namespace gr
-#endif /* INCLUDED_GSM_BURST_SOURCE_QA_H */
+#endif /* INCLUDED_GSM_BURST_SOURCE_H */
diff --git a/include/grgsm/misc_utils/burst_source.h b/include/grgsm/qa_utils/message_sink.h
similarity index 71%
copy from include/grgsm/misc_utils/burst_source.h
copy to include/grgsm/qa_utils/message_sink.h
index bd8644f..5cfe2f7 100644
--- a/include/grgsm/misc_utils/burst_source.h
+++ b/include/grgsm/qa_utils/message_sink.h
@@ -2,26 +2,27 @@
/* @file
* @author Roman Khassraf <rkhassraf@gmail.com>
* @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_SOURCE_H
-#define INCLUDED_GSM_BURST_SOURCE_H
+
+#ifndef INCLUDED_GSM_MESSAGE_SINK_H
+#define INCLUDED_GSM_MESSAGE_SINK_H
#include <grgsm/api.h>
#include <gnuradio/block.h>
@@ -34,24 +35,26 @@
* \ingroup gsm
*
*/
- class GSM_API burst_source : virtual public gr::block
+ class GSM_API message_sink : virtual public gr::block
{
public:
- typedef boost::shared_ptr<burst_source> sptr;
+ typedef boost::shared_ptr<message_sink> sptr;
/*!
- * \brief Return a shared_ptr to a new instance of grgsm::burst_source.
+ * \brief Return a shared_ptr to a new instance of grgsm::message_sink.
*
- * To avoid accidental use of raw pointers, grgsm::burst_source's
+ * To avoid accidental use of raw pointers, grgsm::message_sink's
* constructor is in a private implementation
- * class. grgsm::burst_source::make is the public interface for
+ * class. grgsm::message_sink::make is the public interface for
* creating new instances.
*/
- static sptr make(const std::string &filename);
+ static sptr make();
+
+ virtual std::vector<std::string> get_messages() = 0;
};
} // namespace gsm
} // namespace gr
-#endif /* INCLUDED_GSM_BURST_SOURCE_H */
+#endif /* INCLUDED_GSM_MESSAGE_SINK_H */
diff --git a/include/grgsm/misc_utils/burst_source.h b/include/grgsm/qa_utils/message_source.h
similarity index 69%
copy from include/grgsm/misc_utils/burst_source.h
copy to include/grgsm/qa_utils/message_source.h
index bd8644f..5c3e8a1 100644
--- a/include/grgsm/misc_utils/burst_source.h
+++ b/include/grgsm/qa_utils/message_source.h
@@ -20,8 +20,9 @@
*
*/
-#ifndef INCLUDED_GSM_BURST_SOURCE_H
-#define INCLUDED_GSM_BURST_SOURCE_H
+
+#ifndef INCLUDED_GSM_MESSAGE_SOURCE_H
+#define INCLUDED_GSM_MESSAGE_SOURCE_H
#include <grgsm/api.h>
#include <gnuradio/block.h>
@@ -34,24 +35,26 @@
* \ingroup gsm
*
*/
- class GSM_API burst_source : virtual public gr::block
+ class GSM_API message_source : virtual public gr::block
{
public:
- typedef boost::shared_ptr<burst_source> sptr;
+ typedef boost::shared_ptr<message_source> sptr;
/*!
- * \brief Return a shared_ptr to a new instance of grgsm::burst_source.
+ * \brief Return a shared_ptr to a new instance of grgsm::message_source.
*
- * To avoid accidental use of raw pointers, grgsm::burst_source's
+ * To avoid accidental use of raw pointers, grgsm::message_source's
* constructor is in a private implementation
- * class. grgsm::burst_source::make is the public interface for
+ * class. grgsm::message_source::make is the public interface for
* creating new instances.
*/
- static sptr make(const std::string &filename);
+ static sptr make(const std::vector<std::string> &msg_data);
+
+ virtual void set_msg_data(const std::vector<std::string> &msg_data) = 0;
};
} // namespace gsm
} // namespace gr
-#endif /* INCLUDED_GSM_BURST_SOURCE_H */
+#endif /* INCLUDED_GSM_MESSAGE_SOURCE_H */
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 1ddab6d..2278809 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -46,17 +46,25 @@
decoding/GSM660Tables.cpp
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
misc_utils/controlled_const_source_f_impl.cc
misc_utils/message_printer_impl.cc
misc_utils/tmsi_dumper_impl.cc
- misc_utils/burst_sink_impl.cc
- misc_utils/burst_source_impl.cc
- misc_utils/burst_sink_qa_impl.cc
- misc_utils/burst_source_qa_impl.cc
+ misc_utils/burst_file_sink_impl.cc
+ misc_utils/burst_file_source_impl.cc
misc_utils/message_file_sink_impl.cc
- misc_utils/message_file_source_impl.cc
- decryption/decryption_impl.cc )
+ misc_utils/message_file_source_impl.cc
+ qa_utils/burst_sink_impl.cc
+ qa_utils/burst_source_impl.cc
+ qa_utils/message_source_impl.cc
+ qa_utils/message_sink_impl.cc
+ decryption/decryption_impl.cc
+)
+
add_library(gnuradio-grgsm SHARED ${grgsm_sources})
target_link_libraries(gnuradio-grgsm ${Boost_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES} ${VOLK_LIBRARIES} ${LIBOSMOCORE_LIBRARIES}
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 <rkhassraf@gmail.com>
+ * @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 <gnuradio/io_signature.h>
+#include "burst_fnr_filter_impl.h"
+#include <stdio.h>
+#include <grgsm/endian.h>
+#include <grgsm/gsmtap.h>
+
+
+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/misc_utils/burst_sink_impl.h b/lib/flow_control/burst_fnr_filter_impl.h
similarity index 70%
copy from lib/misc_utils/burst_sink_impl.h
copy to lib/flow_control/burst_fnr_filter_impl.h
index f981826..5d9850d 100644
--- a/lib/misc_utils/burst_sink_impl.h
+++ b/lib/flow_control/burst_fnr_filter_impl.h
@@ -20,27 +20,27 @@
*
*/
-#ifndef INCLUDED_GSM_BURST_SINK_IMPL_H
-#define INCLUDED_GSM_BURST_SINK_IMPL_H
+#ifndef INCLUDED_GSM_BURST_FNR_FILTER_IMPL_H
+#define INCLUDED_GSM_BURST_FNR_FILTER_IMPL_H
-#include <grgsm/misc_utils/burst_sink.h>
-#include <fstream>
+#include <grgsm/flow_control/burst_fnr_filter.h>
namespace gr {
namespace gsm {
- class burst_sink_impl : public burst_sink
+ class burst_fnr_filter_impl : public burst_fnr_filter
{
private:
- std::ofstream d_output_file;
+ unsigned int d_framenr;
+ filter_mode d_mode;
public:
- burst_sink_impl(const std::string &filename);
- ~burst_sink_impl();
+ 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_SINK_IMPL_H */
+#endif /* INCLUDED_GSM_BURST_FNR_FILTER_IMPL_H */
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 <rkhassraf@gmail.com>
+ * @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 <gnuradio/io_signature.h>
+#include "burst_sdcch_subslot_splitter_impl.h"
+#include <stdio.h>
+#include <grgsm/endian.h>
+#include <grgsm/gsmtap.h>
+
+
+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 <rkhassraf@gmail.com>
+ * @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 <grgsm/flow_control/burst_sdcch_subslot_splitter.h>
+
+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/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 <rkhassraf@gmail.com>
+ * @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 <gnuradio/io_signature.h>
+#include "burst_timeslot_splitter_impl.h"
+#include <stdio.h>
+#include <grgsm/endian.h>
+#include <grgsm/gsmtap.h>
+
+
+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/misc_utils/burst_sink_impl.h b/lib/flow_control/burst_timeslot_splitter_impl.h
similarity index 71%
copy from lib/misc_utils/burst_sink_impl.h
copy to lib/flow_control/burst_timeslot_splitter_impl.h
index f981826..47a9115 100644
--- a/lib/misc_utils/burst_sink_impl.h
+++ b/lib/flow_control/burst_timeslot_splitter_impl.h
@@ -20,27 +20,24 @@
*
*/
-#ifndef INCLUDED_GSM_BURST_SINK_IMPL_H
-#define INCLUDED_GSM_BURST_SINK_IMPL_H
+#ifndef INCLUDED_GSM_BURST_TIMESLOT_SPLITTER_IMPL_H
+#define INCLUDED_GSM_BURST_TIMESLOT_SPLITTER_IMPL_H
-#include <grgsm/misc_utils/burst_sink.h>
-#include <fstream>
+#include <grgsm/flow_control/burst_timeslot_splitter.h>
namespace gr {
namespace gsm {
- class burst_sink_impl : public burst_sink
+ class burst_timeslot_splitter_impl : public burst_timeslot_splitter
{
- private:
- std::ofstream d_output_file;
public:
- burst_sink_impl(const std::string &filename);
- ~burst_sink_impl();
+ burst_timeslot_splitter_impl();
+ ~burst_timeslot_splitter_impl();
void process_burst(pmt::pmt_t msg);
};
} // namespace gsm
} // namespace gr
-#endif /* INCLUDED_GSM_BURST_SINK_IMPL_H */
+#endif /* INCLUDED_GSM_BURST_TIMESLOT_SPLITTER_IMPL_H */
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 <rkhassraf@gmail.com>
+ * @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 <gnuradio/io_signature.h>
+#include "dummy_burst_filter_impl.h"
+#include <stdio.h>
+#include <grgsm/endian.h>
+#include <grgsm/gsmtap.h>
+
+
+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<DUMMY_BURST_LEN; i++)
+ {
+ if (burst[i] != d_dummy_burst[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ } /* namespace gsm */
+} /* namespace gr */
diff --git a/lib/misc_utils/burst_sink_impl.h b/lib/flow_control/dummy_burst_filter_impl.h
similarity index 67%
copy from lib/misc_utils/burst_sink_impl.h
copy to lib/flow_control/dummy_burst_filter_impl.h
index f981826..ce9c741 100644
--- a/lib/misc_utils/burst_sink_impl.h
+++ b/lib/flow_control/dummy_burst_filter_impl.h
@@ -20,27 +20,29 @@
*
*/
-#ifndef INCLUDED_GSM_BURST_SINK_IMPL_H
-#define INCLUDED_GSM_BURST_SINK_IMPL_H
+#ifndef INCLUDED_GSM_DUMMY_BURST_FILTER_IMPL_H
+#define INCLUDED_GSM_DUMMY_BURST_FILTER_IMPL_H
-#include <grgsm/misc_utils/burst_sink.h>
-#include <fstream>
+#define DUMMY_BURST_LEN 148
+
+#include <grgsm/flow_control/dummy_burst_filter.h>
namespace gr {
namespace gsm {
- class burst_sink_impl : public burst_sink
+ class dummy_burst_filter_impl : public dummy_burst_filter
{
private:
- std::ofstream d_output_file;
+ bool is_dummy_burst(int8_t *burst, size_t burst_len);
+ static const int8_t d_dummy_burst[];
public:
- burst_sink_impl(const std::string &filename);
- ~burst_sink_impl();
+ dummy_burst_filter_impl();
+ ~dummy_burst_filter_impl();
void process_burst(pmt::pmt_t msg);
};
} // namespace gsm
} // namespace gr
-#endif /* INCLUDED_GSM_BURST_SINK_IMPL_H */
+#endif /* INCLUDED_GSM_DUMMY_BURST_FILTER_IMPL_H */
diff --git a/lib/misc_utils/burst_sink_impl.cc b/lib/misc_utils/burst_file_sink_impl.cc
similarity index 76%
rename from lib/misc_utils/burst_sink_impl.cc
rename to lib/misc_utils/burst_file_sink_impl.cc
index fdb7d98..25a262e 100644
--- a/lib/misc_utils/burst_sink_impl.cc
+++ b/lib/misc_utils/burst_file_sink_impl.cc
@@ -25,36 +25,36 @@
#endif
#include <gnuradio/io_signature.h>
-#include "burst_sink_impl.h"
+#include "burst_file_sink_impl.h"
#include "stdio.h"
namespace gr {
namespace gsm {
- burst_sink::sptr
- burst_sink::make(const std::string &filename)
+ burst_file_sink::sptr
+ burst_file_sink::make(const std::string &filename)
{
return gnuradio::get_initial_sptr
- (new burst_sink_impl(filename));
+ (new burst_file_sink_impl(filename));
}
/*
* The private constructor
*/
- burst_sink_impl::burst_sink_impl(const std::string &filename)
- : gr::block("burst_sink",
+ burst_file_sink_impl::burst_file_sink_impl(const std::string &filename)
+ : gr::block("burst_file_sink",
gr::io_signature::make(0, 0, 0),
gr::io_signature::make(0, 0, 0)),
d_output_file(filename.c_str(), std::ofstream::binary)
{
message_port_register_in(pmt::mp("in"));
- set_msg_handler(pmt::mp("in"), boost::bind(&burst_sink_impl::process_burst, this, _1));
+ set_msg_handler(pmt::mp("in"), boost::bind(&burst_file_sink_impl::process_burst, this, _1));
}
/*
* Our virtual destructor.
*/
- burst_sink_impl::~burst_sink_impl()
+ burst_file_sink_impl::~burst_file_sink_impl()
{
if (d_output_file.is_open())
{
@@ -62,7 +62,7 @@
}
}
- void burst_sink_impl::process_burst(pmt::pmt_t msg)
+ void burst_file_sink_impl::process_burst(pmt::pmt_t msg)
{
std::string s = pmt::serialize_str(msg);
const char *serialized = s.data();
diff --git a/lib/misc_utils/burst_sink_impl.h b/lib/misc_utils/burst_file_sink_impl.h
similarity index 75%
rename from lib/misc_utils/burst_sink_impl.h
rename to lib/misc_utils/burst_file_sink_impl.h
index f981826..898c609 100644
--- a/lib/misc_utils/burst_sink_impl.h
+++ b/lib/misc_utils/burst_file_sink_impl.h
@@ -20,27 +20,27 @@
*
*/
-#ifndef INCLUDED_GSM_BURST_SINK_IMPL_H
-#define INCLUDED_GSM_BURST_SINK_IMPL_H
+#ifndef INCLUDED_GSM_BURST_FILE_SINK_IMPL_H
+#define INCLUDED_GSM_BURST_FILE_SINK_IMPL_H
-#include <grgsm/misc_utils/burst_sink.h>
+#include <grgsm/misc_utils/burst_file_sink.h>
#include <fstream>
namespace gr {
namespace gsm {
- class burst_sink_impl : public burst_sink
+ class burst_file_sink_impl : public burst_file_sink
{
private:
std::ofstream d_output_file;
public:
- burst_sink_impl(const std::string &filename);
- ~burst_sink_impl();
+ burst_file_sink_impl(const std::string &filename);
+ ~burst_file_sink_impl();
void process_burst(pmt::pmt_t msg);
};
} // namespace gsm
} // namespace gr
-#endif /* INCLUDED_GSM_BURST_SINK_IMPL_H */
+#endif /* INCLUDED_GSM_BURST_FILE_SINK_IMPL_H */
diff --git a/lib/misc_utils/burst_source_impl.cc b/lib/misc_utils/burst_file_source_impl.cc
similarity index 79%
rename from lib/misc_utils/burst_source_impl.cc
rename to lib/misc_utils/burst_file_source_impl.cc
index 76d1eaa..4661dfb 100644
--- a/lib/misc_utils/burst_source_impl.cc
+++ b/lib/misc_utils/burst_file_source_impl.cc
@@ -25,7 +25,7 @@
#endif
#include <gnuradio/io_signature.h>
-#include "burst_source_impl.h"
+#include "burst_file_source_impl.h"
#include "stdio.h"
#define PMT_SIZE 174
@@ -33,18 +33,18 @@
namespace gr {
namespace gsm {
- burst_source::sptr
- burst_source::make(const std::string &filename)
+ burst_file_source::sptr
+ burst_file_source::make(const std::string &filename)
{
return gnuradio::get_initial_sptr
- (new burst_source_impl(filename));
+ (new burst_file_source_impl(filename));
}
/*
* The private constructor
*/
- burst_source_impl::burst_source_impl(const std::string &filename)
- : gr::block("burst_source",
+ burst_file_source_impl::burst_file_source_impl(const std::string &filename)
+ : gr::block("burst_file_source",
gr::io_signature::make(0, 0, 0),
gr::io_signature::make(0, 0, 0)),
d_input_file(filename.c_str(), std::ifstream::binary),
@@ -56,22 +56,22 @@
/*
* Our virtual destructor.
*/
- burst_source_impl::~burst_source_impl()
+ burst_file_source_impl::~burst_file_source_impl()
{
if (d_finished == false){
d_finished = true;
}
}
- bool burst_source_impl::start()
+ bool burst_file_source_impl::start()
{
d_finished = false;
d_thread = boost::shared_ptr<gr::thread::thread>
- (new gr::thread::thread(boost::bind(&burst_source_impl::run, this)));
+ (new gr::thread::thread(boost::bind(&burst_file_source_impl::run, this)));
return block::start();
}
- bool burst_source_impl::stop()
+ bool burst_file_source_impl::stop()
{
d_finished = true;
d_thread->interrupt();
@@ -79,12 +79,12 @@
return block::stop();
}
- bool burst_source_impl::finished()
+ bool burst_file_source_impl::finished()
{
return d_finished;
}
- void burst_source_impl::run()
+ void burst_file_source_impl::run()
{
char *unserialized = (char*)malloc(sizeof(char) * PMT_SIZE);
while (d_input_file.read(unserialized, PMT_SIZE) && !d_finished)
diff --git a/lib/misc_utils/burst_source_impl.h b/lib/misc_utils/burst_file_source_impl.h
similarity index 76%
rename from lib/misc_utils/burst_source_impl.h
rename to lib/misc_utils/burst_file_source_impl.h
index 85217b0..383dc90 100644
--- a/lib/misc_utils/burst_source_impl.h
+++ b/lib/misc_utils/burst_file_source_impl.h
@@ -20,16 +20,16 @@
*
*/
-#ifndef INCLUDED_GSM_BURST_SOURCE_IMPL_H
-#define INCLUDED_GSM_BURST_SOURCE_IMPL_H
+#ifndef INCLUDED_GSM_BURST_FILE_SOURCE_IMPL_H
+#define INCLUDED_GSM_BURST_FILE_SOURCE_IMPL_H
-#include <grgsm/misc_utils/burst_source.h>
+#include <grgsm/misc_utils/burst_file_source.h>
#include <fstream>
namespace gr {
namespace gsm {
- class burst_source_impl : public burst_source
+ class burst_file_source_impl : public burst_file_source
{
private:
boost::shared_ptr<gr::thread::thread> d_thread;
@@ -37,8 +37,8 @@
bool d_finished;
void run();
public:
- burst_source_impl(const std::string &filename);
- ~burst_source_impl();
+ burst_file_source_impl(const std::string &filename);
+ ~burst_file_source_impl();
bool start();
bool stop();
bool finished();
@@ -46,5 +46,5 @@
} // namespace gsm
} // namespace gr
-#endif /* INCLUDED_GSM_BURST_SOURCE_IMPL_H */
+#endif /* INCLUDED_GSM_BURST_FILE_SOURCE_IMPL_H */
diff --git a/lib/misc_utils/bursts_printer_impl.cc b/lib/misc_utils/bursts_printer_impl.cc
index 3b4f026..fd93d79 100644
--- a/lib/misc_utils/bursts_printer_impl.cc
+++ b/lib/misc_utils/bursts_printer_impl.cc
@@ -37,6 +37,19 @@
namespace gr {
namespace gsm {
boost::mutex printer_mutex;
+ // dummy burst defined in gsm 05.02, section 5.2.6
+ const int8_t bursts_printer_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 };
+
void bursts_printer_impl::bursts_print(pmt::pmt_t msg)
{
pmt::pmt_t header_plus_burst = pmt::cdr(msg);
@@ -46,6 +59,11 @@
size_t burst_len=pmt::blob_length(header_plus_burst)-sizeof(gsmtap_hdr);
uint32_t frame_nr = be32toh(header->frame_number);
+ if (d_ignore_dummy_bursts && is_dummy_burst(burst, burst_len))
+ {
+ return;
+ }
+
std::cout << d_prepend_string;
if (d_prepend_fnr)
{
@@ -94,19 +112,38 @@
std::cout << std::endl;
}
+ bool bursts_printer_impl::is_dummy_burst(int8_t *burst, size_t burst_len)
+ {
+ if (burst_len != DUMMY_BURST_LEN)
+ {
+ return false;
+ }
+ for (int i=0; i<DUMMY_BURST_LEN; i++)
+ {
+ if (burst[i] != d_dummy_burst[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
bursts_printer::sptr
bursts_printer::make(pmt::pmt_t prepend_string, bool prepend_fnr,
- bool prepend_frame_count, bool print_payload_only)
+ bool prepend_frame_count, bool print_payload_only,
+ bool ignore_dummy_bursts)
{
return gnuradio::get_initial_sptr
- (new bursts_printer_impl(prepend_string, prepend_fnr, prepend_frame_count, print_payload_only));
+ (new bursts_printer_impl(prepend_string, prepend_fnr, prepend_frame_count,
+ print_payload_only, ignore_dummy_bursts));
}
/*
* The private constructor
*/
bursts_printer_impl::bursts_printer_impl(pmt::pmt_t prepend_string, bool prepend_fnr,
- bool prepend_frame_count, bool print_payload_only)
+ bool prepend_frame_count, bool print_payload_only,
+ bool ignore_dummy_bursts)
: gr::block("bursts_printer",
gr::io_signature::make(0, 0, 0),
gr::io_signature::make(0, 0, 0))
@@ -115,6 +152,8 @@
d_prepend_fnr = prepend_fnr;
d_prepend_frame_count = prepend_frame_count;
d_print_payload_only = print_payload_only;
+ d_ignore_dummy_bursts = ignore_dummy_bursts;
+
message_port_register_in(pmt::mp("bursts"));
set_msg_handler(pmt::mp("bursts"), boost::bind(&bursts_printer_impl::bursts_print, this, _1));
}
diff --git a/lib/misc_utils/bursts_printer_impl.h b/lib/misc_utils/bursts_printer_impl.h
index 5a8a7ed..e438c37 100644
--- a/lib/misc_utils/bursts_printer_impl.h
+++ b/lib/misc_utils/bursts_printer_impl.h
@@ -23,6 +23,8 @@
#ifndef INCLUDED_GSM_BURSTS_PRINTER_IMPL_H
#define INCLUDED_GSM_BURSTS_PRINTER_IMPL_H
+#define DUMMY_BURST_LEN 148
+
#include <grgsm/misc_utils/bursts_printer.h>
#include <set>
@@ -37,9 +39,13 @@
bool d_prepend_fnr;
bool d_prepend_frame_count;
bool d_print_payload_only;
+ bool d_ignore_dummy_bursts;
+ bool is_dummy_burst(int8_t *burst, size_t burst_len);
+ static const int8_t d_dummy_burst[];
public:
bursts_printer_impl(pmt::pmt_t prepend_string, bool prepend_fnr=false,
- bool prepend_frame_count=false, bool print_payload_only=false);
+ bool prepend_frame_count=false, bool print_payload_only=false,
+ bool ignore_dummy_bursts=false);
~bursts_printer_impl();
};
diff --git a/lib/misc_utils/message_printer_impl.cc b/lib/misc_utils/message_printer_impl.cc
index d02e2fe..2599f65 100644
--- a/lib/misc_utils/message_printer_impl.cc
+++ b/lib/misc_utils/message_printer_impl.cc
@@ -41,7 +41,15 @@
gsmtap_hdr * header = (gsmtap_hdr *)message_plus_header;
std::cout << d_prepend_string;
- for(int ii=sizeof(gsmtap_hdr); ii<message_plus_header_len; ii++)
+
+ int start_index = sizeof(gsmtap_hdr);
+
+ if (d_print_gsmtap_header)
+ {
+ start_index = 0;
+ }
+
+ for(int ii=start_index; ii<message_plus_header_len; ii++)
{
printf(" %02x", message_plus_header[ii]);
}
@@ -49,24 +57,24 @@
}
message_printer::sptr
- message_printer::make(pmt::pmt_t prepend_string)
+ message_printer::make(pmt::pmt_t prepend_string, bool print_gsmtap_header)
{
return gnuradio::get_initial_sptr
- (new message_printer_impl(prepend_string));
+ (new message_printer_impl(prepend_string, print_gsmtap_header));
}
/*
* The private constructor
*/
- message_printer_impl::message_printer_impl(pmt::pmt_t prepend_string)
+ message_printer_impl::message_printer_impl(pmt::pmt_t prepend_string, bool print_gsmtap_header)
: gr::block("message_printer",
gr::io_signature::make(0, 0, 0),
gr::io_signature::make(0, 0, 0))
{
d_prepend_string = prepend_string;
+ d_print_gsmtap_header = print_gsmtap_header;
message_port_register_in(pmt::mp("msgs"));
set_msg_handler(pmt::mp("msgs"), boost::bind(&message_printer_impl::message_print, this, _1));
-
}
/*
diff --git a/lib/misc_utils/message_printer_impl.h b/lib/misc_utils/message_printer_impl.h
index e82485e..e44288b 100644
--- a/lib/misc_utils/message_printer_impl.h
+++ b/lib/misc_utils/message_printer_impl.h
@@ -33,8 +33,9 @@
private:
void message_print(pmt::pmt_t msg);
pmt::pmt_t d_prepend_string;
+ bool d_print_gsmtap_header;
public:
- message_printer_impl(pmt::pmt_t prepend_string);
+ message_printer_impl(pmt::pmt_t prepend_string, bool print_gsmtap_header=false);
~message_printer_impl();
};
diff --git a/lib/misc_utils/burst_sink_qa_impl.cc b/lib/qa_utils/burst_sink_impl.cc
similarity index 80%
rename from lib/misc_utils/burst_sink_qa_impl.cc
rename to lib/qa_utils/burst_sink_impl.cc
index aa9df9d..de26d39 100644
--- a/lib/misc_utils/burst_sink_qa_impl.cc
+++ b/lib/qa_utils/burst_sink_impl.cc
@@ -25,7 +25,7 @@
#endif
#include <gnuradio/io_signature.h>
-#include "burst_sink_qa_impl.h"
+#include "burst_sink_impl.h"
#include <stdio.h>
#include <sstream>
#include <grgsm/gsmtap.h>
@@ -33,29 +33,29 @@
namespace gr {
namespace gsm {
- burst_sink_qa::sptr
- burst_sink_qa::make()
+ burst_sink::sptr
+ burst_sink::make()
{
return gnuradio::get_initial_sptr
- (new burst_sink_qa_impl());
+ (new burst_sink_impl());
}
/*
* The private constructor
*/
- burst_sink_qa_impl::burst_sink_qa_impl()
- : gr::block("burst_sink_qa",
+ burst_sink_impl::burst_sink_impl()
+ : gr::block("burst_sink",
gr::io_signature::make(0, 0, 0),
gr::io_signature::make(0, 0, 0))
{
message_port_register_in(pmt::mp("in"));
- set_msg_handler(pmt::mp("in"), boost::bind(&burst_sink_qa_impl::process_burst, this, _1));
+ set_msg_handler(pmt::mp("in"), boost::bind(&burst_sink_impl::process_burst, this, _1));
}
/*
* Our virtual destructor.
*/
- burst_sink_qa_impl::~burst_sink_qa_impl()
+ burst_sink_impl::~burst_sink_impl()
{
// for (int i=0; i<d_burst_data.size(); i++)
// {
@@ -63,7 +63,7 @@
// }
}
- void burst_sink_qa_impl::process_burst(pmt::pmt_t msg)
+ void burst_sink_impl::process_burst(pmt::pmt_t msg)
{
pmt::pmt_t header_plus_burst = pmt::cdr(msg);
@@ -90,17 +90,17 @@
d_burst_data.push_back(burst_str.str());
}
- std::vector<int> burst_sink_qa_impl::get_framenumbers()
+ std::vector<int> burst_sink_impl::get_framenumbers()
{
return d_framenumbers;
}
- std::vector<int> burst_sink_qa_impl::get_timeslots()
+ std::vector<int> burst_sink_impl::get_timeslots()
{
return d_timeslots;
}
- std::vector<std::string> burst_sink_qa_impl::get_burst_data()
+ std::vector<std::string> burst_sink_impl::get_burst_data()
{
return d_burst_data;
}
diff --git a/lib/misc_utils/burst_sink_qa_impl.h b/lib/qa_utils/burst_sink_impl.h
similarity index 81%
rename from lib/misc_utils/burst_sink_qa_impl.h
rename to lib/qa_utils/burst_sink_impl.h
index 412a0a1..42e1e4a 100644
--- a/lib/misc_utils/burst_sink_qa_impl.h
+++ b/lib/qa_utils/burst_sink_impl.h
@@ -20,24 +20,24 @@
*
*/
-#ifndef INCLUDED_GSM_BURST_SINK_QA_IMPL_H
-#define INCLUDED_GSM_BURST_SINK_QA_IMPL_H
+#ifndef INCLUDED_GSM_BURST_SINK_IMPL_H
+#define INCLUDED_GSM_BURST_SINK_IMPL_H
-#include <grgsm/misc_utils/burst_sink_qa.h>
+#include <grgsm/qa_utils/burst_sink.h>
#include <fstream>
namespace gr {
namespace gsm {
- class burst_sink_qa_impl : public burst_sink_qa
+ class burst_sink_impl : public burst_sink
{
private:
std::vector<int> d_framenumbers;
std::vector<int> d_timeslots;
std::vector<std::string> d_burst_data;
public:
- burst_sink_qa_impl();
- ~burst_sink_qa_impl();
+ burst_sink_impl();
+ ~burst_sink_impl();
void process_burst(pmt::pmt_t msg);
virtual std::vector<int> get_framenumbers();
virtual std::vector<int> get_timeslots();
@@ -47,5 +47,5 @@
} // namespace gsm
} // namespace gr
-#endif /* INCLUDED_GSM_BURST_SINK_QA_IMPL_H */
+#endif /* INCLUDED_GSM_BURST_SINK_IMPL_H */
diff --git a/lib/misc_utils/burst_source_qa_impl.cc b/lib/qa_utils/burst_source_impl.cc
similarity index 82%
rename from lib/misc_utils/burst_source_qa_impl.cc
rename to lib/qa_utils/burst_source_impl.cc
index 7b2d412..7391872 100644
--- a/lib/misc_utils/burst_source_qa_impl.cc
+++ b/lib/qa_utils/burst_source_impl.cc
@@ -25,7 +25,7 @@
#endif
#include <gnuradio/io_signature.h>
-#include "burst_source_qa_impl.h"
+#include "burst_source_impl.h"
#include "stdio.h"
#include <boost/scoped_ptr.hpp>
#include <grgsm/gsmtap.h>
@@ -36,22 +36,22 @@
namespace gr {
namespace gsm {
- burst_source_qa::sptr
- burst_source_qa::make(const std::vector<int> &framenumbers,
+ burst_source::sptr
+ burst_source::make(const std::vector<int> &framenumbers,
const std::vector<int> ×lots,
const std::vector<std::string> &burst_data)
{
return gnuradio::get_initial_sptr
- (new burst_source_qa_impl(framenumbers, timeslots, burst_data));
+ (new burst_source_impl(framenumbers, timeslots, burst_data));
}
/*
* The private constructor
*/
- burst_source_qa_impl::burst_source_qa_impl(const std::vector<int> &framenumbers,
+ burst_source_impl::burst_source_impl(const std::vector<int> &framenumbers,
const std::vector<int> ×lots,
const std::vector<std::string> &burst_data)
- : gr::block("burst_source_qa",
+ : gr::block("burst_source",
gr::io_signature::make(0, 0, 0),
gr::io_signature::make(0, 0, 0)),
d_finished(false)
@@ -65,37 +65,37 @@
/*
* Our virtual destructor.
*/
- burst_source_qa_impl::~burst_source_qa_impl()
+ burst_source_impl::~burst_source_impl()
{
if (d_finished == false){
d_finished = true;
}
}
- void burst_source_qa_impl::set_framenumbers(const std::vector<int> &framenumbers)
+ void burst_source_impl::set_framenumbers(const std::vector<int> &framenumbers)
{
d_framenumbers = framenumbers;
}
- void burst_source_qa_impl::set_timeslots(const std::vector<int> ×lots)
+ void burst_source_impl::set_timeslots(const std::vector<int> ×lots)
{
d_timeslots = timeslots;
}
- void burst_source_qa_impl::set_burst_data(const std::vector<std::string> &burst_data)
+ void burst_source_impl::set_burst_data(const std::vector<std::string> &burst_data)
{
d_burst_data = burst_data;
}
- bool burst_source_qa_impl::start()
+ bool burst_source_impl::start()
{
d_finished = false;
d_thread = boost::shared_ptr<gr::thread::thread>
- (new gr::thread::thread(boost::bind(&burst_source_qa_impl::run, this)));
+ (new gr::thread::thread(boost::bind(&burst_source_impl::run, this)));
return block::start();
}
- bool burst_source_qa_impl::stop()
+ bool burst_source_impl::stop()
{
d_finished = true;
d_thread->interrupt();
@@ -103,12 +103,12 @@
return block::stop();
}
- bool burst_source_qa_impl::finished()
+ bool burst_source_impl::finished()
{
return d_finished;
}
- void burst_source_qa_impl::run()
+ void burst_source_impl::run()
{
char *unserialized = (char*)malloc(sizeof(char) * PMT_SIZE);
diff --git a/lib/misc_utils/burst_source_qa_impl.h b/lib/qa_utils/burst_source_impl.h
similarity index 81%
rename from lib/misc_utils/burst_source_qa_impl.h
rename to lib/qa_utils/burst_source_impl.h
index cb62571..969faf9 100644
--- a/lib/misc_utils/burst_source_qa_impl.h
+++ b/lib/qa_utils/burst_source_impl.h
@@ -20,19 +20,19 @@
*
*/
-#ifndef INCLUDED_GSM_BURST_SOURCE_QA_IMPL_H
-#define INCLUDED_GSM_BURST_SOURCE_QA_IMPL_H
+#ifndef INCLUDED_GSM_BURST_SOURCE_IMPL_H
+#define INCLUDED_GSM_BURST_SOURCE_IMPL_H
#define BURST_SIZE 148
-#include <grgsm/misc_utils/burst_source_qa.h>
+#include <grgsm/qa_utils/burst_source.h>
#include <fstream>
namespace gr {
namespace gsm {
- class burst_source_qa_impl : public burst_source_qa
+ class burst_source_impl : public burst_source
{
private:
boost::shared_ptr<gr::thread::thread> d_thread;
@@ -42,10 +42,10 @@
bool d_finished;
void run();
public:
- burst_source_qa_impl(const std::vector<int> &framenumbers,
+ burst_source_impl(const std::vector<int> &framenumbers,
const std::vector<int> ×lots,
const std::vector<std::string> &burst_data);
- ~burst_source_qa_impl();
+ ~burst_source_impl();
virtual void set_framenumbers(const std::vector<int> &framenumbers);
virtual void set_timeslots(const std::vector<int> ×lots);
virtual void set_burst_data(const std::vector<std::string> &burst_data);
@@ -56,6 +56,6 @@
} // namespace gsm
} // namespace gr
-#endif /* INCLUDED_GSM_BURST_SOURCE_QA_IMPL_H */
+#endif /* INCLUDED_GSM_BURST_SOURCE_IMPL_H */
diff --git a/lib/qa_utils/message_sink_impl.cc b/lib/qa_utils/message_sink_impl.cc
new file mode 100644
index 0000000..269cada
--- /dev/null
+++ b/lib/qa_utils/message_sink_impl.cc
@@ -0,0 +1,90 @@
+/* -*- c++ -*- */
+/* @file
+ * @author Roman Khassraf <rkhassraf@gmail.com>
+ * @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 <gnuradio/io_signature.h>
+#include "message_sink_impl.h"
+#include <stdio.h>
+#include <sstream>
+
+namespace gr {
+ namespace gsm {
+
+ message_sink::sptr
+ message_sink::make()
+ {
+ return gnuradio::get_initial_sptr
+ (new message_sink_impl());
+ }
+
+ /*
+ * The private constructor
+ */
+ message_sink_impl::message_sink_impl()
+ : gr::block("message_sink",
+ gr::io_signature::make(0, 0, 0),
+ gr::io_signature::make(0, 0, 0))
+ {
+ message_port_register_in(pmt::mp("in"));
+ set_msg_handler(pmt::mp("in"), boost::bind(&message_sink_impl::process_message, this, _1));
+ }
+
+ /*
+ * Our virtual destructor.
+ */
+ message_sink_impl::~message_sink_impl()
+ {
+ for (int i=0; i<d_messages.size(); i++)
+ {
+ std::cout << d_messages[i].c_str() << std::endl;
+ }
+ }
+
+ void message_sink_impl::process_message(pmt::pmt_t msg)
+ {
+ pmt::pmt_t message_plus_header_blob = pmt::cdr(msg);
+ uint8_t * message_plus_header = (uint8_t *)pmt::blob_data(message_plus_header_blob);
+ size_t message_plus_header_len = pmt::blob_length(message_plus_header_blob);
+
+ std::stringstream s_msg_stream;
+ for (int i=0; i<message_plus_header_len; i++)
+ {
+ if (i>0)
+ {
+ s_msg_stream << (" ");
+ }
+ s_msg_stream << std::hex << std::setw(2) << std::setfill('0') << (unsigned)message_plus_header[i];
+ }
+ d_messages.push_back(s_msg_stream.str());
+ }
+
+ std::vector<std::string> message_sink_impl::get_messages()
+ {
+ return d_messages;
+ }
+
+ } /* namespace gsm */
+} /* namespace gr */
+
diff --git a/lib/misc_utils/burst_sink_impl.h b/lib/qa_utils/message_sink_impl.h
similarity index 68%
copy from lib/misc_utils/burst_sink_impl.h
copy to lib/qa_utils/message_sink_impl.h
index f981826..dd11819 100644
--- a/lib/misc_utils/burst_sink_impl.h
+++ b/lib/qa_utils/message_sink_impl.h
@@ -20,27 +20,28 @@
*
*/
-#ifndef INCLUDED_GSM_BURST_SINK_IMPL_H
-#define INCLUDED_GSM_BURST_SINK_IMPL_H
+#ifndef INCLUDED_GSM_MESSAGE_SINK_IMPL_H
+#define INCLUDED_GSM_MESSAGE_SINK_IMPL_H
-#include <grgsm/misc_utils/burst_sink.h>
-#include <fstream>
+#include <grgsm/qa_utils/message_sink.h>
namespace gr {
namespace gsm {
- class burst_sink_impl : public burst_sink
+ class message_sink_impl : public message_sink
{
private:
- std::ofstream d_output_file;
+ std::vector<std::string> d_messages;
+
public:
- burst_sink_impl(const std::string &filename);
- ~burst_sink_impl();
- void process_burst(pmt::pmt_t msg);
+ message_sink_impl();
+ ~message_sink_impl();
+ void process_message(pmt::pmt_t msg);
+ virtual std::vector<std::string> get_messages();
};
} // namespace gsm
} // namespace gr
-#endif /* INCLUDED_GSM_BURST_SINK_IMPL_H */
+#endif /* INCLUDED_GSM_MESSAGE_SINK_IMPL_H */
diff --git a/lib/qa_utils/message_source_impl.cc b/lib/qa_utils/message_source_impl.cc
new file mode 100644
index 0000000..2e71ba4
--- /dev/null
+++ b/lib/qa_utils/message_source_impl.cc
@@ -0,0 +1,131 @@
+/* -*- c++ -*- */
+/* @file
+ * @author Roman Khassraf <rkhassraf@gmail.com>
+ * @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 <gnuradio/io_signature.h>
+#include "message_source_impl.h"
+#include <stdio.h>
+#include <grgsm/gsmtap.h>
+#include <grgsm/endian.h>
+#include <algorithm>
+#include <boost/scoped_ptr.hpp>
+#include <iostream>
+#include <string>
+#include <sstream>
+
+#define MSG_BYTE_LEN 39
+
+
+namespace gr {
+ namespace gsm {
+
+ message_source::sptr
+ message_source::make(const std::vector<std::string> &msg_data)
+ {
+ return gnuradio::get_initial_sptr
+ (new message_source_impl(msg_data));
+ }
+
+ /*
+ * The private constructor
+ */
+ message_source_impl::message_source_impl(const std::vector<std::string> &msg_data)
+ : gr::block("message_source",
+ gr::io_signature::make(0, 0, 0),
+ gr::io_signature::make(0, 0, 0)),
+ d_finished(false)
+ {
+ message_port_register_out(pmt::mp("msgs"));
+ set_msg_data(msg_data);
+ }
+
+ /*
+ * Our virtual destructor.
+ */
+ message_source_impl::~message_source_impl()
+ {
+ if (d_finished == false){
+ d_finished = true;
+ }
+ }
+
+ void message_source_impl::set_msg_data(const std::vector<std::string> &msg_data)
+ {
+ for (int i=0; i<msg_data.size(); i++)
+ {
+ std::istringstream iss(msg_data[i]);
+ std::vector<uint8_t> bytes;
+ unsigned int c;
+
+ while (iss >> std::hex >> c)
+ {
+ if (c < 256)
+ {
+ bytes.push_back(c);
+ }
+ }
+
+ if (bytes.size() == MSG_BYTE_LEN)
+ {
+ d_msgs.push_back(bytes);
+ }
+ }
+ }
+
+ bool message_source_impl::start()
+ {
+ d_finished = false;
+ d_thread = boost::shared_ptr<gr::thread::thread>
+ (new gr::thread::thread(boost::bind(&message_source_impl::run, this)));
+ return block::start();
+ }
+
+ bool message_source_impl::stop()
+ {
+ d_finished = true;
+ d_thread->interrupt();
+ d_thread->join();
+ return block::stop();
+ }
+
+ bool message_source_impl::finished()
+ {
+ return d_finished;
+ }
+
+ void message_source_impl::run()
+ {
+ for (int i=0; i<d_msgs.size(); i++)
+ {
+ std::vector<uint8_t> current = d_msgs[i];
+ pmt::pmt_t blob_header_plus_burst = pmt::make_blob(¤t[0], current.size());
+ pmt::pmt_t msg = pmt::cons(pmt::PMT_NIL, blob_header_plus_burst);
+ message_port_pub(pmt::mp("msgs"), msg);
+ }
+ post(pmt::mp("system"), pmt::cons(pmt::mp("done"), pmt::from_long(1)));
+ }
+ } /* namespace gsm */
+} /* namespace gr */
+
diff --git a/lib/misc_utils/burst_source_impl.h b/lib/qa_utils/message_source_impl.h
similarity index 64%
copy from lib/misc_utils/burst_source_impl.h
copy to lib/qa_utils/message_source_impl.h
index 85217b0..9856f78 100644
--- a/lib/misc_utils/burst_source_impl.h
+++ b/lib/qa_utils/message_source_impl.h
@@ -20,31 +20,32 @@
*
*/
-#ifndef INCLUDED_GSM_BURST_SOURCE_IMPL_H
-#define INCLUDED_GSM_BURST_SOURCE_IMPL_H
+#ifndef INCLUDED_GSM_MESSAGE_SOURCE_IMPL_H
+#define INCLUDED_GSM_MESSAGE_SOURCE_IMPL_H
-#include <grgsm/misc_utils/burst_source.h>
-#include <fstream>
+#include <grgsm/qa_utils/message_source.h>
namespace gr {
namespace gsm {
- class burst_source_impl : public burst_source
+ class message_source_impl : public message_source
{
private:
boost::shared_ptr<gr::thread::thread> d_thread;
- std::ifstream d_input_file;
+ std::vector<std::vector<uint8_t> > d_msgs;
bool d_finished;
void run();
public:
- burst_source_impl(const std::string &filename);
- ~burst_source_impl();
- bool start();
- bool stop();
- bool finished();
+ message_source_impl(const std::vector<std::string> &msg_data);
+ ~message_source_impl();
+ virtual void set_msg_data(const std::vector<std::string> &msg_data);
+ bool start();
+ bool stop();
+ bool finished();
};
- } // namespace gsm
+
+ } // namespace grgsm
} // namespace gr
-#endif /* INCLUDED_GSM_BURST_SOURCE_IMPL_H */
+#endif /* INCLUDED_GSM_MESSAGE_SOURCE_IMPL_H */
diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt
index cb4b2b2..811a3ec 100644
--- a/python/CMakeLists.txt
+++ b/python/CMakeLists.txt
@@ -47,5 +47,9 @@
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_printer ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_burst_printer.py)
+GR_ADD_TEST(qa_message_printer ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_message_printer.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_fnr_filter.py b/python/qa_burst_fnr_filter.py
new file mode 100755
index 0000000..cdd3ff4
--- /dev/null
+++ b/python/qa_burst_fnr_filter.py
@@ -0,0 +1,168 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# @file
+# @author Roman Khassraf <rkhassraf@gmail.com>
+# @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(framenumbers_input, timeslots_input, bursts_input)
+ sink = grgsm.burst_sink()
+
+ 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(framenumbers_input, timeslots_input, bursts_input)
+ sink = grgsm.burst_sink()
+
+ 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/python/qa_burst_printer.py b/python/qa_burst_printer.py
new file mode 100755
index 0000000..97fbe71
--- /dev/null
+++ b/python/qa_burst_printer.py
@@ -0,0 +1,297 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# @file
+# @author Roman Khassraf <rkhassraf@gmail.com>
+# @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 os
+import pmt
+import sys
+import tempfile
+
+class qa_burst_printer (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block()
+ self.tmpfile = tempfile.NamedTemporaryFile()
+ self.prevfd = os.dup(sys.stdout.fileno())
+ os.dup2(self.tmpfile.fileno(), sys.stdout.fileno())
+ self.prev = sys.stdout
+ sys.stdout = os.fdopen(self.prevfd, "w")
+
+ def tearDown (self):
+ self.tb = None
+ os.dup2(self.prevfd, self.prev.fileno())
+ sys.stdout = self.prev
+ self.tmpfile.close()
+
+ def getOutput(self):
+ self.tmpfile.seek(0)
+ return self.tmpfile.read()
+
+ def getOutputExpected(self, expected_lines):
+ out = ""
+ for l in expected_lines:
+ out = out + l + "\n"
+ return out
+
+ def test_001_complete_bursts_prefix (self):
+ """
+ Complete bursts, without any prefix
+ """
+ framenumbers_input = [2569043, 2569044, 2569045, 2569046]
+ timeslots_input = [2, 2, 2, 2]
+ bursts_input = [
+ "0001100000010010011110111110011111000000001010001111000000001000110101110010000011010111100101101010000001111010100010110111101011101011100000101000",
+ "0001000101111101111110000010100001011011111010111110101011101000110101110010000011010111110110111101101111110000011011010111011111001011101000011000",
+ "0000001000011110111110101011001000110000000000110110101100011000110101110010000011010111001010100101011111001000111100000100000111111000000101110000",
+ "0001101010111110010001010110101100000011101100011111110100101000110101110010000011010111111000000001010010111001111111011001000000001001000011101000"
+ ]
+
+ expected_lines = [
+ "0001100000010010011110111110011111000000001010001111000000001000110101110010000011010111100101101010000001111010100010110111101011101011100000101000",
+ "0001000101111101111110000010100001011011111010111110101011101000110101110010000011010111110110111101101111110000011011010111011111001011101000011000",
+ "0000001000011110111110101011001000110000000000110110101100011000110101110010000011010111001010100101011111001000111100000100000111111000000101110000",
+ "0001101010111110010001010110101100000011101100011111110100101000110101110010000011010111111000000001010010111001111111011001000000001001000011101000"
+ ]
+
+ src = grgsm.burst_source(framenumbers_input, timeslots_input, bursts_input)
+ printer = grgsm.bursts_printer(pmt.intern(""), False, False, False, False)
+ self.tb.msg_connect(src, "out", printer, "bursts")
+ self.tb.run()
+
+ self.assertEqual(self.getOutput(), self.getOutputExpected(expected_lines))
+
+ def test_002_complete_bursts_prefix (self):
+ """
+ Complete bursts, with a string prefix
+ """
+ framenumbers_input = [2569043, 2569044, 2569045, 2569046]
+ timeslots_input = [2, 2, 2, 2]
+ bursts_input = [
+ "0001100000010010011110111110011111000000001010001111000000001000110101110010000011010111100101101010000001111010100010110111101011101011100000101000",
+ "0001000101111101111110000010100001011011111010111110101011101000110101110010000011010111110110111101101111110000011011010111011111001011101000011000",
+ "0000001000011110111110101011001000110000000000110110101100011000110101110010000011010111001010100101011111001000111100000100000111111000000101110000",
+ "0001101010111110010001010110101100000011101100011111110100101000110101110010000011010111111000000001010010111001111111011001000000001001000011101000"
+ ]
+
+ expected_lines = [
+ "Test 0001100000010010011110111110011111000000001010001111000000001000110101110010000011010111100101101010000001111010100010110111101011101011100000101000",
+ "Test 0001000101111101111110000010100001011011111010111110101011101000110101110010000011010111110110111101101111110000011011010111011111001011101000011000",
+ "Test 0000001000011110111110101011001000110000000000110110101100011000110101110010000011010111001010100101011111001000111100000100000111111000000101110000",
+ "Test 0001101010111110010001010110101100000011101100011111110100101000110101110010000011010111111000000001010010111001111111011001000000001001000011101000"
+ ]
+
+ src = grgsm.burst_source(framenumbers_input, timeslots_input, bursts_input)
+ printer = grgsm.bursts_printer(pmt.intern("Test "), False, False, False, False)
+ self.tb.msg_connect(src, "out", printer, "bursts")
+ self.tb.run()
+
+ self.assertEqual(self.getOutput(), self.getOutputExpected(expected_lines))
+
+ def test_003_complete_bursts_fnr (self):
+ """
+ Complete bursts, no prefix, with frame number
+ """
+ framenumbers_input = [2569043, 2569044, 2569045, 2569046]
+ timeslots_input = [2, 2, 2, 2]
+ bursts_input = [
+ "0001100000010010011110111110011111000000001010001111000000001000110101110010000011010111100101101010000001111010100010110111101011101011100000101000",
+ "0001000101111101111110000010100001011011111010111110101011101000110101110010000011010111110110111101101111110000011011010111011111001011101000011000",
+ "0000001000011110111110101011001000110000000000110110101100011000110101110010000011010111001010100101011111001000111100000100000111111000000101110000",
+ "0001101010111110010001010110101100000011101100011111110100101000110101110010000011010111111000000001010010111001111111011001000000001001000011101000"
+ ]
+
+ expected_lines = [
+ "2569043: 0001100000010010011110111110011111000000001010001111000000001000110101110010000011010111100101101010000001111010100010110111101011101011100000101000",
+ "2569044: 0001000101111101111110000010100001011011111010111110101011101000110101110010000011010111110110111101101111110000011011010111011111001011101000011000",
+ "2569045: 0000001000011110111110101011001000110000000000110110101100011000110101110010000011010111001010100101011111001000111100000100000111111000000101110000",
+ "2569046: 0001101010111110010001010110101100000011101100011111110100101000110101110010000011010111111000000001010010111001111111011001000000001001000011101000"
+ ]
+
+ src = grgsm.burst_source(framenumbers_input, timeslots_input, bursts_input)
+ printer = grgsm.bursts_printer(pmt.intern(""), True, False, False, False)
+ self.tb.msg_connect(src, "out", printer, "bursts")
+ self.tb.run()
+
+ self.assertEqual(self.getOutput(), self.getOutputExpected(expected_lines))
+
+ def test_004_complete_bursts_fcount (self):
+ """
+ Complete bursts, no prefix, with frame count
+ """
+ framenumbers_input = [2569043, 2569044, 2569045, 2569046]
+ timeslots_input = [2, 2, 2, 2]
+ bursts_input = [
+ "0001100000010010011110111110011111000000001010001111000000001000110101110010000011010111100101101010000001111010100010110111101011101011100000101000",
+ "0001000101111101111110000010100001011011111010111110101011101000110101110010000011010111110110111101101111110000011011010111011111001011101000011000",
+ "0000001000011110111110101011001000110000000000110110101100011000110101110010000011010111001010100101011111001000111100000100000111111000000101110000",
+ "0001101010111110010001010110101100000011101100011111110100101000110101110010000011010111111000000001010010111001111111011001000000001001000011101000"
+ ]
+
+ expected_lines = [
+ "3967625: 0001100000010010011110111110011111000000001010001111000000001000110101110010000011010111100101101010000001111010100010110111101011101011100000101000",
+ "3967658: 0001000101111101111110000010100001011011111010111110101011101000110101110010000011010111110110111101101111110000011011010111011111001011101000011000",
+ "3967691: 0000001000011110111110101011001000110000000000110110101100011000110101110010000011010111001010100101011111001000111100000100000111111000000101110000",
+ "3967724: 0001101010111110010001010110101100000011101100011111110100101000110101110010000011010111111000000001010010111001111111011001000000001001000011101000"
+ ]
+
+ src = grgsm.burst_source(framenumbers_input, timeslots_input, bursts_input)
+ printer = grgsm.bursts_printer(pmt.intern(""), False, True, False, False)
+ self.tb.msg_connect(src, "out", printer, "bursts")
+ self.tb.run()
+
+ self.assertEqual(self.getOutput(), self.getOutputExpected(expected_lines))
+
+ def test_005_complete_bursts_fnr_fcount (self):
+ """
+ Complete bursts, no prefix, with frame number and frame count
+ """
+ framenumbers_input = [2569043, 2569044, 2569045, 2569046]
+ timeslots_input = [2, 2, 2, 2]
+ bursts_input = [
+ "0001100000010010011110111110011111000000001010001111000000001000110101110010000011010111100101101010000001111010100010110111101011101011100000101000",
+ "0001000101111101111110000010100001011011111010111110101011101000110101110010000011010111110110111101101111110000011011010111011111001011101000011000",
+ "0000001000011110111110101011001000110000000000110110101100011000110101110010000011010111001010100101011111001000111100000100000111111000000101110000",
+ "0001101010111110010001010110101100000011101100011111110100101000110101110010000011010111111000000001010010111001111111011001000000001001000011101000"
+ ]
+
+ expected_lines = [
+ "2569043 3967625: 0001100000010010011110111110011111000000001010001111000000001000110101110010000011010111100101101010000001111010100010110111101011101011100000101000",
+ "2569044 3967658: 0001000101111101111110000010100001011011111010111110101011101000110101110010000011010111110110111101101111110000011011010111011111001011101000011000",
+ "2569045 3967691: 0000001000011110111110101011001000110000000000110110101100011000110101110010000011010111001010100101011111001000111100000100000111111000000101110000",
+ "2569046 3967724: 0001101010111110010001010110101100000011101100011111110100101000110101110010000011010111111000000001010010111001111111011001000000001001000011101000"
+ ]
+
+ src = grgsm.burst_source(framenumbers_input, timeslots_input, bursts_input)
+ printer = grgsm.bursts_printer(pmt.intern(""), True, True, False, False)
+ self.tb.msg_connect(src, "out", printer, "bursts")
+ self.tb.run()
+
+ self.assertEqual(self.getOutput(), self.getOutputExpected(expected_lines))
+
+ def test_006_payload_prefix_fnr_fcount (self):
+ """
+ Payload only, no prefix, with frame number and frame count
+ Bursts 4-7 are dummy bursts
+ """
+ framenumbers_input = [2569043, 2569044, 2569045, 2569046, 1099602, 1099603, 1099604, 1099605]
+ timeslots_input = [2, 2, 2, 2, 4, 4, 4, 4]
+ bursts_input = [
+ "0001100000010010011110111110011111000000001010001111000000001000110101110010000011010111100101101010000001111010100010110111101011101011100000101000",
+ "0001000101111101111110000010100001011011111010111110101011101000110101110010000011010111110110111101101111110000011011010111011111001011101000011000",
+ "0000001000011110111110101011001000110000000000110110101100011000110101110010000011010111001010100101011111001000111100000100000111111000000101110000",
+ "0001101010111110010001010110101100000011101100011111110100101000110101110010000011010111111000000001010010111001111111011001000000001001000011101000",
+ "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000",
+ "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000",
+ "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000",
+ "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000"
+
+ ]
+
+ expected_lines = [
+ "test_006: 2569043 3967625: 110000001001001111011111001111100000000101000111100000000100101101010000001111010100010110111101011101011100000101",
+ "test_006: 2569044 3967658: 100010111110111111000001010000101101111101011111010101110110110111101101111110000011011010111011111001011101000011",
+ "test_006: 2569045 3967691: 000100001111011111010101100100011000000000011011010110001001010100101011111001000111100000100000111111000000101110",
+ "test_006: 2569046 3967724: 110101011111001000101011010110000001110110001111111010010111000000001010010111001111111011001000000001001000011101",
+ "test_006: 1099602 1699146: 111110110111011000001010010011100000100100010000000111110111010010100011001100111001111010011111000100101111101010",
+ "test_006: 1099603 1699179: 111110110111011000001010010011100000100100010000000111110111010010100011001100111001111010011111000100101111101010",
+ "test_006: 1099604 1699212: 111110110111011000001010010011100000100100010000000111110111010010100011001100111001111010011111000100101111101010",
+ "test_006: 1099605 1699245: 111110110111011000001010010011100000100100010000000111110111010010100011001100111001111010011111000100101111101010"
+ ]
+
+ src = grgsm.burst_source(framenumbers_input, timeslots_input, bursts_input)
+ printer = grgsm.bursts_printer(pmt.intern("test_006: "), True, True, True, False)
+ self.tb.msg_connect(src, "out", printer, "bursts")
+ self.tb.run()
+
+ self.assertEqual(self.getOutput(), self.getOutputExpected(expected_lines))
+
+ def test_007_payload_prefix_fnr_fcount (self):
+ """
+ Payload only, no prefix, with frame number, frame count, and ignoring dummy bursts
+ Bursts 4-7 are dummy bursts
+ """
+ framenumbers_input = [2569043, 2569044, 2569045, 2569046, 1099602, 1099603, 1099604, 1099605]
+ timeslots_input = [2, 2, 2, 2, 4, 4, 4, 4]
+ bursts_input = [
+ "0001100000010010011110111110011111000000001010001111000000001000110101110010000011010111100101101010000001111010100010110111101011101011100000101000",
+ "0001000101111101111110000010100001011011111010111110101011101000110101110010000011010111110110111101101111110000011011010111011111001011101000011000",
+ "0000001000011110111110101011001000110000000000110110101100011000110101110010000011010111001010100101011111001000111100000100000111111000000101110000",
+ "0001101010111110010001010110101100000011101100011111110100101000110101110010000011010111111000000001010010111001111111011001000000001001000011101000",
+ "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000",
+ "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000",
+ "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000",
+ "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000"
+
+ ]
+
+ expected_lines = [
+ "test_007: 2569043 3967625: 110000001001001111011111001111100000000101000111100000000100101101010000001111010100010110111101011101011100000101",
+ "test_007: 2569044 3967658: 100010111110111111000001010000101101111101011111010101110110110111101101111110000011011010111011111001011101000011",
+ "test_007: 2569045 3967691: 000100001111011111010101100100011000000000011011010110001001010100101011111001000111100000100000111111000000101110",
+ "test_007: 2569046 3967724: 110101011111001000101011010110000001110110001111111010010111000000001010010111001111111011001000000001001000011101"
+ ]
+
+ src = grgsm.burst_source(framenumbers_input, timeslots_input, bursts_input)
+ printer = grgsm.bursts_printer(pmt.intern("test_007: "), True, True, True, True)
+ self.tb.msg_connect(src, "out", printer, "bursts")
+ self.tb.run()
+
+ self.assertEqual(self.getOutput(), self.getOutputExpected(expected_lines))
+
+ def test_008_complete_prefix_fnr_fcount (self):
+ """
+ Complete bursts, no prefix, with frame number, frame count, and ignoring dummy bursts
+ Bursts 4-7 are dummy bursts
+ """
+ framenumbers_input = [2569043, 2569044, 2569045, 2569046, 1099602, 1099603, 1099604, 1099605]
+ timeslots_input = [2, 2, 2, 2, 4, 4, 4, 4]
+ bursts_input = [
+ "0001100000010010011110111110011111000000001010001111000000001000110101110010000011010111100101101010000001111010100010110111101011101011100000101000",
+ "0001000101111101111110000010100001011011111010111110101011101000110101110010000011010111110110111101101111110000011011010111011111001011101000011000",
+ "0000001000011110111110101011001000110000000000110110101100011000110101110010000011010111001010100101011111001000111100000100000111111000000101110000",
+ "0001101010111110010001010110101100000011101100011111110100101000110101110010000011010111111000000001010010111001111111011001000000001001000011101000",
+ "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000",
+ "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000",
+ "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000",
+ "0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000"
+
+ ]
+
+ expected_lines = [
+ "test_008: 2569043 3967625: 0001100000010010011110111110011111000000001010001111000000001000110101110010000011010111100101101010000001111010100010110111101011101011100000101000",
+ "test_008: 2569044 3967658: 0001000101111101111110000010100001011011111010111110101011101000110101110010000011010111110110111101101111110000011011010111011111001011101000011000",
+ "test_008: 2569045 3967691: 0000001000011110111110101011001000110000000000110110101100011000110101110010000011010111001010100101011111001000111100000100000111111000000101110000",
+ "test_008: 2569046 3967724: 0001101010111110010001010110101100000011101100011111110100101000110101110010000011010111111000000001010010111001111111011001000000001001000011101000"
+ ]
+
+ src = grgsm.burst_source(framenumbers_input, timeslots_input, bursts_input)
+ printer = grgsm.bursts_printer(pmt.intern("test_008: "), True, True, False, True)
+ self.tb.msg_connect(src, "out", printer, "bursts")
+ self.tb.run()
+
+ self.assertEqual(self.getOutput(), self.getOutputExpected(expected_lines))
+
+
+if __name__ == '__main__':
+ gr_unittest.run(qa_burst_printer, "qa_burst_printer.xml")
diff --git a/python/qa_burst_sdcch_subslot_splitter.py b/python/qa_burst_sdcch_subslot_splitter.py
new file mode 100755
index 0000000..ff30c2b
--- /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 <rkhassraf@gmail.com>
+# @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(self.framenumbers_input, self.timeslots_input, self.bursts_input)
+ splitter = grgsm.burst_sdcch_subslot_splitter(grgsm.SPLITTER_SDCCH8)
+ sink_0 = grgsm.burst_sink()
+ sink_1 = grgsm.burst_sink()
+ sink_2 = grgsm.burst_sink()
+ sink_3 = grgsm.burst_sink()
+ sink_4 = grgsm.burst_sink()
+ sink_5 = grgsm.burst_sink()
+ sink_6 = grgsm.burst_sink()
+ sink_7 = grgsm.burst_sink()
+
+ 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(self.framenumbers_input, self.timeslots_input, self.bursts_input)
+ splitter = grgsm.burst_sdcch_subslot_splitter(grgsm.SPLITTER_SDCCH4)
+ sink_0 = grgsm.burst_sink()
+ sink_1 = grgsm.burst_sink()
+ sink_2 = grgsm.burst_sink()
+ sink_3 = grgsm.burst_sink()
+
+ 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/python/qa_burst_timeslot_splitter.py b/python/qa_burst_timeslot_splitter.py
new file mode 100755
index 0000000..b162a2e
--- /dev/null
+++ b/python/qa_burst_timeslot_splitter.py
@@ -0,0 +1,161 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# @file
+# @author Roman Khassraf <rkhassraf@gmail.com>
+# @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(framenumbers_input, timeslots_input, bursts_input)
+ splitter = grgsm.burst_timeslot_splitter()
+ sink_0 = grgsm.burst_sink()
+ sink_1 = grgsm.burst_sink()
+ sink_2 = grgsm.burst_sink()
+ sink_3 = grgsm.burst_sink()
+ sink_4 = grgsm.burst_sink()
+ sink_5 = grgsm.burst_sink()
+ sink_6 = grgsm.burst_sink()
+ sink_7 = grgsm.burst_sink()
+
+ 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/python/qa_decryption.py b/python/qa_decryption.py
index cf228ae..08f0915 100755
--- a/python/qa_decryption.py
+++ b/python/qa_decryption.py
@@ -56,9 +56,9 @@
key = [0x32,0xE5,0x45,0x53,0x20,0x8C,0xE0,0x00]
a5_version = 1
- src = grgsm.burst_source_qa(framenumbers_input, timeslots_input, bursts_input)
+ src = grgsm.burst_source(framenumbers_input, timeslots_input, bursts_input)
decryption = grgsm.decryption((key), a5_version)
- dst = grgsm.burst_sink_qa()
+ dst = grgsm.burst_sink()
self.tb.msg_connect(src, "out", decryption, "bursts")
self.tb.msg_connect(decryption, "bursts", dst, "in")
@@ -97,9 +97,9 @@
key = [0xAD,0x6A,0x3E,0xC2,0xB4,0x42,0xE4,0x00]
a5_version = 1
- src = grgsm.burst_source_qa(framenumbers_input, timeslots_input, bursts_input)
+ src = grgsm.burst_source(framenumbers_input, timeslots_input, bursts_input)
decryption = grgsm.decryption((key), a5_version)
- dst = grgsm.burst_sink_qa()
+ dst = grgsm.burst_sink()
self.tb.msg_connect(src, "out", decryption, "bursts")
self.tb.msg_connect(decryption, "bursts", dst, "in")
@@ -138,9 +138,9 @@
key = [0x41,0xBC,0x19,0x30,0xB6,0x31,0x8A,0xC8]
a5_version = 3
- src = grgsm.burst_source_qa(framenumbers_input, timeslots_input, bursts_input)
+ src = grgsm.burst_source(framenumbers_input, timeslots_input, bursts_input)
decryption = grgsm.decryption((key), a5_version)
- dst = grgsm.burst_sink_qa()
+ dst = grgsm.burst_sink()
self.tb.msg_connect(src, "out", decryption, "bursts")
self.tb.msg_connect(decryption, "bursts", dst, "in")
@@ -179,9 +179,9 @@
key = [0xAD,0x2C,0xB3,0x83,0x2F,0x4A,0x6C,0xF1]
a5_version = 3
- src = grgsm.burst_source_qa(framenumbers_input, timeslots_input, bursts_input)
+ src = grgsm.burst_source(framenumbers_input, timeslots_input, bursts_input)
decryption = grgsm.decryption((key), a5_version)
- dst = grgsm.burst_sink_qa()
+ dst = grgsm.burst_sink()
self.tb.msg_connect(src, "out", decryption, "bursts")
self.tb.msg_connect(decryption, "bursts", dst, "in")
diff --git a/python/qa_dummy_burst_filter.py b/python/qa_dummy_burst_filter.py
new file mode 100755
index 0000000..5a78890
--- /dev/null
+++ b/python/qa_dummy_burst_filter.py
@@ -0,0 +1,102 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# @file
+# @author Roman Khassraf <rkhassraf@gmail.com>
+# @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(framenumbers_input, timeslots_input, bursts_input)
+ sink = grgsm.burst_sink()
+
+ 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/python/qa_message_printer.py b/python/qa_message_printer.py
new file mode 100755
index 0000000..4efaaef
--- /dev/null
+++ b/python/qa_message_printer.py
@@ -0,0 +1,166 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# @file
+# @author Roman Khassraf <rkhassraf@gmail.com>
+# @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 os
+import pmt
+import sys
+import tempfile
+
+class qa_message_printer (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block()
+ self.tmpfile = tempfile.NamedTemporaryFile()
+ self.prevfd = os.dup(sys.stdout.fileno())
+ os.dup2(self.tmpfile.fileno(), sys.stdout.fileno())
+ self.prev = sys.stdout
+ sys.stdout = os.fdopen(self.prevfd, "w")
+
+ def tearDown (self):
+ self.tb = None
+ os.dup2(self.prevfd, self.prev.fileno())
+ sys.stdout = self.prev
+ self.tmpfile.close()
+
+ def getOutput(self):
+ self.tmpfile.seek(0)
+ return self.tmpfile.read()
+
+ def getOutputExpected(self, expected_lines):
+ out = ""
+ for l in expected_lines:
+ out = out + l + "\n"
+ return out
+
+ def test_001_no_prefix_no_header (self):
+ """
+ Four messages, without any prefix, no gsmtap header
+ """
+ msgs_input = [
+ "02 04 01 00 00 00 c9 00 00 1d 3c e5 02 00 01 00 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b",
+ "02 04 01 00 00 00 ca 00 00 1d 3c e9 02 00 02 00 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b",
+ "02 04 01 00 00 00 cb 00 00 1d 3d 0e 01 00 00 00 59 06 1a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff e5 04 00",
+ "02 04 01 00 00 00 cb 00 00 1d 3d 12 02 00 00 00 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b"
+ ]
+
+ # there is a whitespace at the beginning of message_printer output
+ msgs_expected = [
+ " 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b",
+ " 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b",
+ " 59 06 1a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff e5 04 00",
+ " 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b"
+ ]
+
+ src = grgsm.message_source(msgs_input)
+ printer = grgsm.message_printer(pmt.intern(""), False)
+ self.tb.msg_connect(src, "msgs", printer, "msgs")
+ self.tb.run()
+
+ self.assertEqual(self.getOutput(), self.getOutputExpected(msgs_expected))
+
+
+ def test_002_prefix_no_header (self):
+ """
+ Four messages, with prefix "test_002:", no gsmtap header
+ """
+ msgs_input = [
+ "02 04 01 00 00 00 c9 00 00 1d 3c e5 02 00 01 00 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b",
+ "02 04 01 00 00 00 ca 00 00 1d 3c e9 02 00 02 00 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b",
+ "02 04 01 00 00 00 cb 00 00 1d 3d 0e 01 00 00 00 59 06 1a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff e5 04 00",
+ "02 04 01 00 00 00 cb 00 00 1d 3d 12 02 00 00 00 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b"
+ ]
+
+ msgs_expected = [
+ "test_002: 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b",
+ "test_002: 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b",
+ "test_002: 59 06 1a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff e5 04 00",
+ "test_002: 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b"
+ ]
+
+ src = grgsm.message_source(msgs_input)
+ printer = grgsm.message_printer(pmt.intern("test_002:"), False)
+ self.tb.msg_connect(src, "msgs", printer, "msgs")
+ self.tb.run()
+
+ self.assertEqual(self.getOutput(), self.getOutputExpected(msgs_expected))
+
+
+ def test_003_no_prefix_header (self):
+ """
+ Four messages, without any prefix, with gsmtap header
+ """
+ msgs_input = [
+ "02 04 01 00 00 00 c9 00 00 1d 3c e5 02 00 01 00 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b",
+ "02 04 01 00 00 00 ca 00 00 1d 3c e9 02 00 02 00 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b",
+ "02 04 01 00 00 00 cb 00 00 1d 3d 0e 01 00 00 00 59 06 1a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff e5 04 00",
+ "02 04 01 00 00 00 cb 00 00 1d 3d 12 02 00 00 00 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b"
+ ]
+
+ # there is a whitespace at the beginning of message_printer output
+ msgs_expected = [
+ " 02 04 01 00 00 00 c9 00 00 1d 3c e5 02 00 01 00 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b",
+ " 02 04 01 00 00 00 ca 00 00 1d 3c e9 02 00 02 00 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b",
+ " 02 04 01 00 00 00 cb 00 00 1d 3d 0e 01 00 00 00 59 06 1a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff e5 04 00",
+ " 02 04 01 00 00 00 cb 00 00 1d 3d 12 02 00 00 00 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b"
+ ]
+
+ src = grgsm.message_source(msgs_input)
+ printer = grgsm.message_printer(pmt.intern(""), True)
+ self.tb.msg_connect(src, "msgs", printer, "msgs")
+ self.tb.run()
+
+ self.assertEqual(self.getOutput(), self.getOutputExpected(msgs_expected))
+
+
+ def test_004_prefix_header (self):
+ """
+ Four messages, with prefix "test_004:", with gsmtap header
+ """
+ msgs_input = [
+ "02 04 01 00 00 00 c9 00 00 1d 3c e5 02 00 01 00 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b",
+ "02 04 01 00 00 00 ca 00 00 1d 3c e9 02 00 02 00 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b",
+ "02 04 01 00 00 00 cb 00 00 1d 3d 0e 01 00 00 00 59 06 1a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff e5 04 00",
+ "02 04 01 00 00 00 cb 00 00 1d 3d 12 02 00 00 00 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b"
+ ]
+
+ # there is a whitespace at the beginning of message_printer output
+ msgs_expected = [
+ "test_004: 02 04 01 00 00 00 c9 00 00 1d 3c e5 02 00 01 00 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b",
+ "test_004: 02 04 01 00 00 00 ca 00 00 1d 3c e9 02 00 02 00 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b",
+ "test_004: 02 04 01 00 00 00 cb 00 00 1d 3d 0e 01 00 00 00 59 06 1a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff e5 04 00",
+ "test_004: 02 04 01 00 00 00 cb 00 00 1d 3d 12 02 00 00 00 15 06 21 00 01 f0 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b"
+ ]
+
+ src = grgsm.message_source(msgs_input)
+ printer = grgsm.message_printer(pmt.intern("test_004:"), True)
+ self.tb.msg_connect(src, "msgs", printer, "msgs")
+ self.tb.run()
+
+ self.assertEqual(self.getOutput(), self.getOutputExpected(msgs_expected))
+
+
+if __name__ == '__main__':
+ gr_unittest.run(qa_message_printer, "qa_message_printer.xml")
+
diff --git a/swig/grgsm_swig.i b/swig/grgsm_swig.i
index bf63f08..b6ae71c 100644
--- a/swig/grgsm_swig.i
+++ b/swig/grgsm_swig.i
@@ -16,6 +16,10 @@
#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/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"
#include "grgsm/misc_utils/controlled_const_source_f.h"
#include "grgsm/misc_utils/controlled_rotator_cc.h"
@@ -23,15 +27,16 @@
#include "grgsm/misc_utils/extract_immediate_assignment.h"
#include "grgsm/misc_utils/message_printer.h"
#include "grgsm/misc_utils/tmsi_dumper.h"
-#include "grgsm/misc_utils/burst_sink.h"
-#include "grgsm/misc_utils/burst_sink_qa.h"
-#include "grgsm/misc_utils/burst_source.h"
-#include "grgsm/misc_utils/burst_source_qa.h"
+#include "grgsm/misc_utils/burst_file_sink.h"
+#include "grgsm/misc_utils/burst_file_source.h"
+#include "grgsm/qa_utils/burst_sink.h"
+#include "grgsm/qa_utils/burst_source.h"
+#include "grgsm/qa_utils/message_source.h"
+#include "grgsm/qa_utils/message_sink.h"
#include "grgsm/misc_utils/message_file_sink.h"
#include "grgsm/misc_utils/message_file_source.h"
%}
-
%include "grgsm/receiver/receiver.h"
GR_SWIG_BLOCK_MAGIC2(gsm, receiver);
%include "grgsm/receiver/clock_offset_control.h"
@@ -52,16 +57,21 @@
%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/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"
+GR_SWIG_BLOCK_MAGIC2(gsm, dummy_burst_filter);
+
%include "grgsm/misc_utils/bursts_printer.h"
GR_SWIG_BLOCK_MAGIC2(gsm, bursts_printer);
-%include "grgsm/misc_utils/burst_sink.h"
-GR_SWIG_BLOCK_MAGIC2(gsm, burst_sink);
-%include "grgsm/misc_utils/burst_source.h"
-GR_SWIG_BLOCK_MAGIC2(gsm, burst_source);
-%include "grgsm/misc_utils/burst_sink_qa.h"
-GR_SWIG_BLOCK_MAGIC2(gsm, burst_sink_qa);
-%include "grgsm/misc_utils/burst_source_qa.h"
-GR_SWIG_BLOCK_MAGIC2(gsm, burst_source_qa);
+%include "grgsm/misc_utils/burst_file_sink.h"
+GR_SWIG_BLOCK_MAGIC2(gsm, burst_file_sink);
+%include "grgsm/misc_utils/burst_file_source.h"
+GR_SWIG_BLOCK_MAGIC2(gsm, burst_file_source);
%include "grgsm/misc_utils/extract_system_info.h"
GR_SWIG_BLOCK_MAGIC2(gsm, extract_system_info);
%include "grgsm/misc_utils/extract_immediate_assignment.h"
@@ -78,3 +88,12 @@
GR_SWIG_BLOCK_MAGIC2(gsm, message_file_sink);
%include "grgsm/misc_utils/message_file_source.h"
GR_SWIG_BLOCK_MAGIC2(gsm, message_file_source);
+
+%include "grgsm/qa_utils/burst_sink.h"
+GR_SWIG_BLOCK_MAGIC2(gsm, burst_sink);
+%include "grgsm/qa_utils/burst_source.h"
+GR_SWIG_BLOCK_MAGIC2(gsm, burst_source);
+%include "grgsm/qa_utils/message_source.h"
+GR_SWIG_BLOCK_MAGIC2(gsm, message_source);
+%include "grgsm/qa_utils/message_sink.h"
+GR_SWIG_BLOCK_MAGIC2(gsm, message_sink);