Merge refactoring of the receiver done in branch 'fixeria/receiver' of https://github.com/axilirator/gr-gsm into axilirator-fixeria/receiver
diff --git a/apps/grgsm_decode b/apps/grgsm_decode
index 18536c3..2198bc4 100755
--- a/apps/grgsm_decode
+++ b/apps/grgsm_decode
@@ -319,7 +319,7 @@
                                 "Valid options are " + ", ".join(tch_codecs.keys()))
     tch_options.add_option("-o", "--output-tch", dest="speech_output_file", default="/tmp/speech.au.gsm",
                            help="TCH/F speech output file [default=%default].")
-    tch_options.add_option("--voice-boundary", dest="enable_voice_boundary_detection", action="store_true",
+    tch_options.add_option("--voice-boundary", dest="enable_voice_boundary_detection", action="store_true", default=False,
                            help="Enable voice boundary detection for traffic channels. This can help reduce noice in the output.")
     parser.add_option_group(tch_options)
 
diff --git a/apps/grgsm_livemon b/apps/grgsm_livemon
index 765ebae..cb63bdc 100755
--- a/apps/grgsm_livemon
+++ b/apps/grgsm_livemon
@@ -5,7 +5,7 @@
 # Title: Gr-gsm Livemon
 # Author: Piotr Krysik
 # Description: Interactive monitor of a single C0 channel with analysis performed by Wireshark (command to run wireshark: sudo wireshark -k -f udp -Y gsmtap -i lo)
-# Generated: Mon Jan 23 21:28:25 2017
+# Generated: Sun Jul 23 19:07:48 2017
 ##################################################
 
 if __name__ == '__main__':
@@ -38,7 +38,7 @@
 
 class grgsm_livemon(gr.top_block, Qt.QWidget):
 
-    def __init__(self, args="", fc=939.4e6, gain=30, ppm=0, samp_rate=2000000.052982, shiftoff=400e3, osr=4):
+    def __init__(self, args="", gain=30, osr=4, ppm=0, samp_rate=2000000.052982, shiftoff=400e3, fc=941.8e6):
         gr.top_block.__init__(self, "Gr-gsm Livemon")
         Qt.QWidget.__init__(self)
         self.setWindowTitle("Gr-gsm Livemon")
@@ -65,12 +65,12 @@
         # Parameters
         ##################################################
         self.args = args
-        self.fc = fc
         self.gain = gain
+        self.osr = osr
         self.ppm = ppm
         self.samp_rate = samp_rate
         self.shiftoff = shiftoff
-        self.osr = osr
+        self.fc = fc
 
         ##################################################
         # Variables
@@ -161,7 +161,7 @@
         self.gsm_control_channels_decoder_0_0 = grgsm.control_channels_decoder()
         self.gsm_control_channels_decoder_0 = grgsm.control_channels_decoder()
         self.gsm_clock_offset_control_0 = grgsm.clock_offset_control(fc-shiftoff, samp_rate, osr)
-        self.gsm_bcch_ccch_demapper_0 = grgsm.gsm_bcch_ccch_demapper(
+        self.gsm_bcch_ccch_sdcch4_demapper_0 = grgsm.gsm_bcch_ccch_sdcch4_demapper(
             timeslot_nr=0,
         )
         self.blocks_socket_pdu_0_0 = blocks.socket_pdu("UDP_SERVER", "127.0.0.1", "4729", 10000, False)
@@ -171,14 +171,14 @@
         ##################################################
         # Connections
         ##################################################
-        self.msg_connect((self.gsm_bcch_ccch_demapper_0, 'bursts'), (self.gsm_control_channels_decoder_0, 'bursts'))    
+        self.msg_connect((self.gsm_bcch_ccch_sdcch4_demapper_0, 'bursts'), (self.gsm_control_channels_decoder_0, 'bursts'))    
         self.msg_connect((self.gsm_clock_offset_control_0, 'ctrl'), (self.gsm_input_0, 'ctrl_in'))    
         self.msg_connect((self.gsm_control_channels_decoder_0, 'msgs'), (self.blocks_socket_pdu_0, 'pdus'))    
         self.msg_connect((self.gsm_control_channels_decoder_0, 'msgs'), (self.gsm_message_printer_1, 'msgs'))    
         self.msg_connect((self.gsm_control_channels_decoder_0_0, 'msgs'), (self.blocks_socket_pdu_0, 'pdus'))    
         self.msg_connect((self.gsm_control_channels_decoder_0_0, 'msgs'), (self.gsm_message_printer_1, 'msgs'))    
         self.msg_connect((self.gsm_decryption_0, 'bursts'), (self.gsm_control_channels_decoder_0_0, 'bursts'))    
-        self.msg_connect((self.gsm_receiver_0, 'C0'), (self.gsm_bcch_ccch_demapper_0, 'bursts'))    
+        self.msg_connect((self.gsm_receiver_0, 'C0'), (self.gsm_bcch_ccch_sdcch4_demapper_0, 'bursts'))    
         self.msg_connect((self.gsm_receiver_0, 'measurements'), (self.gsm_clock_offset_control_0, 'measurements'))    
         self.msg_connect((self.gsm_receiver_0, 'C0'), (self.gsm_sdcch8_demapper_0, 'bursts'))    
         self.msg_connect((self.gsm_sdcch8_demapper_0, 'bursts'), (self.gsm_decryption_0, 'bursts'))    
@@ -199,14 +199,6 @@
     def set_args(self, args):
         self.args = args
 
-    def get_fc(self):
-        return self.fc
-
-    def set_fc(self, fc):
-        self.fc = fc
-        self.set_fc_slider(self.fc)
-        self.gsm_input_0.set_fc(self.fc)
-
     def get_gain(self):
         return self.gain
 
@@ -214,6 +206,12 @@
         self.gain = gain
         self.set_g_slider(self.gain)
 
+    def get_osr(self):
+        return self.osr
+
+    def set_osr(self, osr):
+        self.osr = osr
+
     def get_ppm(self):
         return self.ppm
 
@@ -227,25 +225,27 @@
 
     def set_samp_rate(self, samp_rate):
         self.samp_rate = samp_rate
+        self.blocks_rotator_cc_0.set_phase_inc(-2*pi*self.shiftoff/self.samp_rate)
         self.gsm_input_0.set_samp_rate_in(self.samp_rate)
         self.qtgui_freq_sink_x_0.set_frequency_range(self.fc_slider, self.samp_rate)
         self.rtlsdr_source_0.set_sample_rate(self.samp_rate)
-        self.blocks_rotator_cc_0.set_phase_inc(-2*pi*self.shiftoff/self.samp_rate)
 
     def get_shiftoff(self):
         return self.shiftoff
 
     def set_shiftoff(self, shiftoff):
         self.shiftoff = shiftoff
+        self.blocks_rotator_cc_0.set_phase_inc(-2*pi*self.shiftoff/self.samp_rate)
         self.rtlsdr_source_0.set_center_freq(self.fc_slider-self.shiftoff, 0)
         self.rtlsdr_source_0.set_bandwidth(250e3+abs(self.shiftoff), 0)
-        self.blocks_rotator_cc_0.set_phase_inc(-2*pi*self.shiftoff/self.samp_rate)
 
-    def get_osr(self):
-        return self.osr
+    def get_fc(self):
+        return self.fc
 
-    def set_osr(self, osr):
-        self.osr = osr
+    def set_fc(self, fc):
+        self.fc = fc
+        self.set_fc_slider(self.fc)
+        self.gsm_input_0.set_fc(self.fc)
 
     def get_ppm_slider(self):
         return self.ppm_slider
@@ -276,12 +276,12 @@
         "", "--args", dest="args", type="string", default="",
         help="Set Device Arguments [default=%default]")
     parser.add_option(
-        "-f", "--fc", dest="fc", type="eng_float", default=eng_notation.num_to_str(939.4e6),
-        help="Set fc [default=%default]")
-    parser.add_option(
         "-g", "--gain", dest="gain", type="eng_float", default=eng_notation.num_to_str(30),
         help="Set gain [default=%default]")
     parser.add_option(
+        "", "--osr", dest="osr", type="intx", default=4,
+        help="Set OverSampling Ratio [default=%default]")
+    parser.add_option(
         "-p", "--ppm", dest="ppm", type="eng_float", default=eng_notation.num_to_str(0),
         help="Set ppm [default=%default]")
     parser.add_option(
@@ -289,10 +289,10 @@
         help="Set samp_rate [default=%default]")
     parser.add_option(
         "-o", "--shiftoff", dest="shiftoff", type="eng_float", default=eng_notation.num_to_str(400e3),
-        help="Set shiftoff [default=%default]")
+        help="Set Frequency Shiftoff [default=%default]")
     parser.add_option(
-        "", "--osr", dest="osr", type="intx", default=4,
-        help="Set OSR [default=%default]")
+        "-f", "--fc", dest="fc", type="eng_float", default=eng_notation.num_to_str(941.8e6),
+        help="Set GSM channel's central frequency [default=%default]")
     return parser
 
 
@@ -306,7 +306,7 @@
         Qt.QApplication.setGraphicsSystem(style)
     qapp = Qt.QApplication(sys.argv)
 
-    tb = top_block_cls(args=options.args, fc=options.fc, gain=options.gain, ppm=options.ppm, samp_rate=options.samp_rate, shiftoff=options.shiftoff, osr=options.osr)
+    tb = top_block_cls(args=options.args, gain=options.gain, osr=options.osr, ppm=options.ppm, samp_rate=options.samp_rate, shiftoff=options.shiftoff, fc=options.fc)
     tb.start()
     tb.show()
 
diff --git a/apps/grgsm_livemon.grc b/apps/grgsm_livemon.grc
index 77640c9..40bee70 100644
--- a/apps/grgsm_livemon.grc
+++ b/apps/grgsm_livemon.grc
@@ -502,7 +502,7 @@
     </param>
     <param>
       <key>label</key>
-      <value>fc</value>
+      <value>GSM channel's central frequency</value>
     </param>
     <param>
       <key>short_id</key>
@@ -514,7 +514,7 @@
     </param>
     <param>
       <key>value</key>
-      <value>939.4e6</value>
+      <value>941.8e6</value>
     </param>
   </block>
   <block>
@@ -561,7 +561,7 @@
     </param>
   </block>
   <block>
-    <key>gsm_bcch_ccch_demapper</key>
+    <key>gsm_bcch_ccch_sdcch4_demapper</key>
     <param>
       <key>alias</key>
       <value></value>
@@ -580,7 +580,7 @@
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(896, 284)</value>
+      <value>(920, 284)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -588,7 +588,7 @@
     </param>
     <param>
       <key>id</key>
-      <value>gsm_bcch_ccch_demapper_0</value>
+      <value>gsm_bcch_ccch_sdcch4_demapper_0</value>
     </param>
     <param>
       <key>maxoutbuf</key>
@@ -1038,7 +1038,7 @@
     </param>
     <param>
       <key>label</key>
-      <value>OSR</value>
+      <value>OverSampling Ratio</value>
     </param>
     <param>
       <key>short_id</key>
@@ -2861,7 +2861,7 @@
     </param>
     <param>
       <key>label</key>
-      <value>shiftoff</value>
+      <value>Frequency Shiftoff</value>
     </param>
     <param>
       <key>short_id</key>
@@ -2889,7 +2889,7 @@
     <sink_key>0</sink_key>
   </connection>
   <connection>
-    <source_block_id>gsm_bcch_ccch_demapper_0</source_block_id>
+    <source_block_id>gsm_bcch_ccch_sdcch4_demapper_0</source_block_id>
     <sink_block_id>gsm_control_channels_decoder_0</sink_block_id>
     <source_key>bursts</source_key>
     <sink_key>bursts</sink_key>
@@ -2938,7 +2938,7 @@
   </connection>
   <connection>
     <source_block_id>gsm_receiver_0</source_block_id>
-    <sink_block_id>gsm_bcch_ccch_demapper_0</sink_block_id>
+    <sink_block_id>gsm_bcch_ccch_sdcch4_demapper_0</sink_block_id>
     <source_key>C0</source_key>
     <sink_key>bursts</sink_key>
   </connection>
diff --git a/include/grgsm/flow_control/CMakeLists.txt b/include/grgsm/flow_control/CMakeLists.txt
index 9c20b59..322c8c8 100644
--- a/include/grgsm/flow_control/CMakeLists.txt
+++ b/include/grgsm/flow_control/CMakeLists.txt
@@ -21,6 +21,7 @@
 # Install public header files
 ########################################################################
 install(FILES
+    common.h
     burst_timeslot_splitter.h
     burst_sdcch_subslot_splitter.h
     burst_timeslot_filter.h
diff --git a/include/grgsm/flow_control/burst_fnr_filter.h b/include/grgsm/flow_control/burst_fnr_filter.h
index 919bc1c..0d94ff8 100644
--- a/include/grgsm/flow_control/burst_fnr_filter.h
+++ b/include/grgsm/flow_control/burst_fnr_filter.h
@@ -26,6 +26,7 @@
 
 #include <grgsm/api.h>
 #include <gnuradio/block.h>
+#include <grgsm/flow_control/common.h>
 
 namespace gr {
   namespace gsm {
@@ -56,6 +57,16 @@
        */
       static sptr make(filter_mode mode, unsigned int fnr);
 
+      /* External API */
+      virtual unsigned int get_fn(void) = 0;
+      virtual unsigned int set_fn(unsigned int fn) = 0;
+
+      virtual filter_mode get_mode(void) = 0;
+      virtual filter_mode set_mode(filter_mode mode) = 0;
+
+      /* Filtering policy */
+      virtual filter_policy get_policy(void) = 0;
+      virtual filter_policy set_policy(filter_policy policy) = 0;
     };
 
   } // namespace gsm
diff --git a/include/grgsm/flow_control/burst_sdcch_subslot_filter.h b/include/grgsm/flow_control/burst_sdcch_subslot_filter.h
index 150d76a..a68782f 100644
--- a/include/grgsm/flow_control/burst_sdcch_subslot_filter.h
+++ b/include/grgsm/flow_control/burst_sdcch_subslot_filter.h
@@ -25,6 +25,7 @@
 
 #include <grgsm/api.h>
 #include <gnuradio/block.h>
+#include <grgsm/flow_control/common.h>
 
 namespace gr {
   namespace gsm {
@@ -54,6 +55,17 @@
        * creating new instances.
        */
       static sptr make(subslot_filter_mode mode, unsigned int subslot);
+
+      /* External API */
+      virtual unsigned int get_ss(void) = 0;
+      virtual unsigned int set_ss(unsigned int ss) = 0;
+
+      virtual subslot_filter_mode get_mode(void) = 0;
+      virtual subslot_filter_mode set_mode(subslot_filter_mode mode) = 0;
+
+      /* Filtering policy */
+      virtual filter_policy get_policy(void) = 0;
+      virtual filter_policy set_policy(filter_policy policy) = 0;
     };
   } // namespace gsm
 } // namespace gr
diff --git a/include/grgsm/flow_control/burst_sdcch_subslot_splitter.h b/include/grgsm/flow_control/burst_sdcch_subslot_splitter.h
index 2b48c43..83f98ba 100644
--- a/include/grgsm/flow_control/burst_sdcch_subslot_splitter.h
+++ b/include/grgsm/flow_control/burst_sdcch_subslot_splitter.h
@@ -54,6 +54,10 @@
        * creating new instances.
        */
       static sptr make(splitter_mode mode);
+
+      /* External API */
+      virtual splitter_mode get_mode(void) = 0;
+      virtual splitter_mode set_mode(splitter_mode mode) = 0;
     };
   } // namespace gsm
 } // namespace gr
diff --git a/include/grgsm/flow_control/burst_timeslot_filter.h b/include/grgsm/flow_control/burst_timeslot_filter.h
index f23fcf7..79d677c 100644
--- a/include/grgsm/flow_control/burst_timeslot_filter.h
+++ b/include/grgsm/flow_control/burst_timeslot_filter.h
@@ -25,6 +25,7 @@
 
 #include <grgsm/api.h>
 #include <gnuradio/block.h>
+#include <grgsm/flow_control/common.h>
 
 namespace gr {
   namespace gsm {
@@ -48,6 +49,14 @@
        * creating new instances.
        */
       static sptr make(unsigned int timeslot);
+
+      /* External API */
+      virtual unsigned int get_tn(void) = 0;
+      virtual unsigned int set_tn(unsigned int tn) = 0;
+
+      /* Filtering policy */
+      virtual filter_policy get_policy(void) = 0;
+      virtual filter_policy set_policy(filter_policy policy) = 0;
     };
   } // namespace gsm
 } // namespace gr
diff --git a/include/grgsm/flow_control/common.h b/include/grgsm/flow_control/common.h
new file mode 100644
index 0000000..fa4725c
--- /dev/null
+++ b/include/grgsm/flow_control/common.h
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */
+/*
+ * @file
+ * @author Vadim Yanitskiy <axilirator@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_FLOW_CONTROL_COMMON_H
+#define INCLUDED_GSM_FLOW_CONTROL_COMMON_H
+
+namespace gr {
+  namespace gsm {
+
+    enum filter_policy {
+      FILTER_POLICY_DEFAULT,
+      FILTER_POLICY_PASS_ALL,
+      FILTER_POLICY_DROP_ALL,
+    };
+
+  } /* namespace gsm */
+} /* namespace gr */
+
+#endif
diff --git a/include/grgsm/flow_control/dummy_burst_filter.h b/include/grgsm/flow_control/dummy_burst_filter.h
index b969611..bf956bb 100644
--- a/include/grgsm/flow_control/dummy_burst_filter.h
+++ b/include/grgsm/flow_control/dummy_burst_filter.h
@@ -25,6 +25,7 @@
 
 #include <grgsm/api.h>
 #include <gnuradio/block.h>
+#include <grgsm/flow_control/common.h>
 
 namespace gr {
   namespace gsm {
@@ -48,6 +49,11 @@
        * creating new instances.
        */
       static sptr make();
+
+      /* External API */
+      /* Filtering policy */
+      virtual filter_policy get_policy(void) = 0;
+      virtual filter_policy set_policy(filter_policy policy) = 0;
     };
   } // namespace gsm
 } // namespace gr
diff --git a/lib/flow_control/burst_fnr_filter_impl.cc b/lib/flow_control/burst_fnr_filter_impl.cc
index e665acf..5d1ffbc 100644
--- a/lib/flow_control/burst_fnr_filter_impl.cc
+++ b/lib/flow_control/burst_fnr_filter_impl.cc
@@ -49,7 +49,8 @@
               gr::io_signature::make(0, 0, 0),
               gr::io_signature::make(0, 0, 0)),
       d_mode(mode),
-      d_framenr(fnr)
+      d_framenr(fnr),
+      d_filter_policy(FILTER_POLICY_DEFAULT)
     {
         message_port_register_in(pmt::mp("in"));       
         message_port_register_out(pmt::mp("out"));
@@ -64,6 +65,14 @@
 
     void burst_fnr_filter_impl::process_burst(pmt::pmt_t msg)
     {
+        if (d_filter_policy == FILTER_POLICY_DROP_ALL)
+          return;
+
+        if (d_filter_policy == FILTER_POLICY_PASS_ALL) {
+          message_port_pub(pmt::mp("out"), msg);
+          return;
+        }
+
         pmt::pmt_t header_plus_burst = pmt::cdr(msg);
         gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(header_plus_burst);
         
@@ -75,5 +84,50 @@
             message_port_pub(pmt::mp("out"), msg);
         }
     }
+
+    /* External API */
+    unsigned int
+    burst_fnr_filter_impl::get_fn(void)
+    {
+      return d_framenr;
+    }
+
+    unsigned int
+    burst_fnr_filter_impl::set_fn(unsigned int fn)
+    {
+      if (fn <= GSM_HYPERFRAME)
+        d_framenr = fn;
+
+      return d_framenr;
+    }
+
+
+    filter_mode
+    burst_fnr_filter_impl::get_mode(void)
+    {
+      return d_mode;
+    }
+
+    filter_mode
+    burst_fnr_filter_impl::set_mode(filter_mode mode)
+    {
+      d_mode = mode;
+      return d_mode;
+    }
+
+    /* Filtering policy */
+    filter_policy
+    burst_fnr_filter_impl::get_policy(void)
+    {
+      return d_filter_policy;
+    }
+
+    filter_policy
+    burst_fnr_filter_impl::set_policy(filter_policy policy)
+    {
+      d_filter_policy = policy;
+      return d_filter_policy;
+    }
+
   } /* namespace gsm */
 } /* namespace gr */
diff --git a/lib/flow_control/burst_fnr_filter_impl.h b/lib/flow_control/burst_fnr_filter_impl.h
index 5d9850d..9d13825 100644
--- a/lib/flow_control/burst_fnr_filter_impl.h
+++ b/lib/flow_control/burst_fnr_filter_impl.h
@@ -25,18 +25,33 @@
 
 #include <grgsm/flow_control/burst_fnr_filter.h>
 
+#define GSM_SUPERFRAME    (26 * 51)
+#define GSM_HYPERFRAME    (2048 * GSM_SUPERFRAME)
+
 namespace gr {
   namespace gsm {
 
     class burst_fnr_filter_impl : public burst_fnr_filter
     {
      private:
+      filter_policy d_filter_policy;
       unsigned int d_framenr;
       filter_mode d_mode;
      public:
       burst_fnr_filter_impl(filter_mode mode, unsigned int fnr);
       ~burst_fnr_filter_impl();
       void process_burst(pmt::pmt_t msg);
+
+      /* External API */
+      unsigned int get_fn(void);
+      unsigned int set_fn(unsigned int fn);
+
+      filter_mode get_mode(void);
+      filter_mode set_mode(filter_mode mode);
+
+      /* Filtering policy */
+      filter_policy get_policy(void);
+      filter_policy set_policy(filter_policy policy);
     };
 
   } // namespace gsm
diff --git a/lib/flow_control/burst_sdcch_subslot_filter_impl.cc b/lib/flow_control/burst_sdcch_subslot_filter_impl.cc
index 31e2989..80e7c89 100644
--- a/lib/flow_control/burst_sdcch_subslot_filter_impl.cc
+++ b/lib/flow_control/burst_sdcch_subslot_filter_impl.cc
@@ -48,7 +48,8 @@
               gr::io_signature::make(0, 0, 0),
               gr::io_signature::make(0, 0, 0)),
       d_mode(mode),
-      d_subslot(subslot)
+      d_subslot(subslot),
+      d_filter_policy(FILTER_POLICY_DEFAULT)
     {     
         message_port_register_in(pmt::mp("in"));
         message_port_register_out(pmt::mp("out"));
@@ -73,6 +74,14 @@
           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
         };
+
+        if (d_filter_policy == FILTER_POLICY_DROP_ALL)
+          return;
+
+        if (d_filter_policy == FILTER_POLICY_PASS_ALL) {
+          message_port_pub(pmt::mp("out"), msg);
+          return;
+        }
     
         pmt::pmt_t header_plus_burst = pmt::cdr(msg);
         gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(header_plus_burst);
@@ -101,5 +110,51 @@
             message_port_pub(pmt::mp("out"), msg);
         }
     }
+
+    /* External API */
+    unsigned int
+    burst_sdcch_subslot_filter_impl::get_ss(void)
+    {
+      return d_subslot;
+    }
+
+    unsigned int
+    burst_sdcch_subslot_filter_impl::set_ss(unsigned int ss)
+    {
+      if ((d_mode == SS_FILTER_SDCCH8 && ss < 8)
+      || (d_mode == SS_FILTER_SDCCH4 && ss < 4))
+        d_subslot = ss;
+
+      return d_subslot;
+    }
+
+
+    subslot_filter_mode
+    burst_sdcch_subslot_filter_impl::get_mode(void)
+    {
+      return d_mode;
+    }
+
+    subslot_filter_mode
+    burst_sdcch_subslot_filter_impl::set_mode(subslot_filter_mode mode)
+    {
+      d_mode = mode;
+      return d_mode;
+    }
+
+    /* Filtering policy */
+    filter_policy
+    burst_sdcch_subslot_filter_impl::get_policy(void)
+    {
+      return d_filter_policy;
+    }
+
+    filter_policy
+    burst_sdcch_subslot_filter_impl::set_policy(filter_policy policy)
+    {
+      d_filter_policy = policy;
+      return d_filter_policy;
+    }
+
   } /* namespace gsm */
 } /* namespace gr */
diff --git a/lib/flow_control/burst_sdcch_subslot_filter_impl.h b/lib/flow_control/burst_sdcch_subslot_filter_impl.h
index 40a603e..85a392f 100644
--- a/lib/flow_control/burst_sdcch_subslot_filter_impl.h
+++ b/lib/flow_control/burst_sdcch_subslot_filter_impl.h
@@ -31,12 +31,24 @@
     class burst_sdcch_subslot_filter_impl : public burst_sdcch_subslot_filter
     {
      private:
+      filter_policy d_filter_policy;
       subslot_filter_mode d_mode;
       unsigned int d_subslot;
      public:
       burst_sdcch_subslot_filter_impl(subslot_filter_mode mode, unsigned int subslot);
       ~burst_sdcch_subslot_filter_impl();
       void process_burst(pmt::pmt_t msg);
+
+      /* External API */
+      unsigned int get_ss(void);
+      unsigned int set_ss(unsigned int ss);
+
+      subslot_filter_mode get_mode(void);
+      subslot_filter_mode set_mode(subslot_filter_mode mode);
+
+      /* Filtering policy */
+      filter_policy get_policy(void);
+      filter_policy set_policy(filter_policy policy);
     };
 
   } // namespace gsm
diff --git a/lib/flow_control/burst_sdcch_subslot_splitter_impl.cc b/lib/flow_control/burst_sdcch_subslot_splitter_impl.cc
index 90237d9..46177c1 100644
--- a/lib/flow_control/burst_sdcch_subslot_splitter_impl.cc
+++ b/lib/flow_control/burst_sdcch_subslot_splitter_impl.cc
@@ -141,5 +141,20 @@
 
         message_port_pub(pmt::mp(port), msg);
     }
+
+    /* External API */
+    splitter_mode
+    burst_sdcch_subslot_splitter_impl::get_mode(void)
+    {
+      return d_mode;
+    }
+
+    splitter_mode
+    burst_sdcch_subslot_splitter_impl::set_mode(splitter_mode mode)
+    {
+      d_mode = mode;
+      return d_mode;
+    }
+
   } /* 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
index b8eaaea..50aa028 100644
--- a/lib/flow_control/burst_sdcch_subslot_splitter_impl.h
+++ b/lib/flow_control/burst_sdcch_subslot_splitter_impl.h
@@ -36,6 +36,10 @@
       burst_sdcch_subslot_splitter_impl(splitter_mode mode);
       ~burst_sdcch_subslot_splitter_impl();
       void process_burst(pmt::pmt_t msg);
+
+      /* External API */
+      splitter_mode get_mode(void);
+      splitter_mode set_mode(splitter_mode mode);
     };
 
   } // namespace gsm
diff --git a/lib/flow_control/burst_timeslot_filter_impl.cc b/lib/flow_control/burst_timeslot_filter_impl.cc
index ccf4d4c..c93bc60 100644
--- a/lib/flow_control/burst_timeslot_filter_impl.cc
+++ b/lib/flow_control/burst_timeslot_filter_impl.cc
@@ -48,7 +48,8 @@
       : gr::block("burst_timeslot_filter",
               gr::io_signature::make(0, 0, 0),
               gr::io_signature::make(0, 0, 0)),
-       d_timeslot(timeslot)
+       d_timeslot(timeslot),
+       d_filter_policy(FILTER_POLICY_DEFAULT)
     {
         message_port_register_in(pmt::mp("in"));        
         message_port_register_out(pmt::mp("out"));
@@ -63,6 +64,14 @@
 
     void burst_timeslot_filter_impl::process_burst(pmt::pmt_t msg)
     {
+        if (d_filter_policy == FILTER_POLICY_DROP_ALL)
+          return;
+
+        if (d_filter_policy == FILTER_POLICY_PASS_ALL) {
+          message_port_pub(pmt::mp("out"), msg);
+          return;
+        }
+
         pmt::pmt_t header_plus_burst = pmt::cdr(msg);
         gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(header_plus_burst);
         
@@ -73,5 +82,38 @@
             message_port_pub(pmt::mp("out"), msg);
         }
     }
+
+    /*
+     * External API
+     */
+    unsigned int
+    burst_timeslot_filter_impl::get_tn(void)
+    {
+      return d_timeslot;
+    }
+
+    unsigned int
+    burst_timeslot_filter_impl::set_tn(unsigned int tn)
+    {
+      if (tn < 8)
+        d_timeslot = tn;
+
+      return d_timeslot;
+    }
+
+    /* Filtering policy */
+    filter_policy
+    burst_timeslot_filter_impl::get_policy(void)
+    {
+      return d_filter_policy;
+    }
+
+    filter_policy
+    burst_timeslot_filter_impl::set_policy(filter_policy policy)
+    {
+      d_filter_policy = policy;
+      return d_filter_policy;
+    }
+
   } /* namespace gsm */
 } /* namespace gr */
diff --git a/lib/flow_control/burst_timeslot_filter_impl.h b/lib/flow_control/burst_timeslot_filter_impl.h
index f7b0b2d..fa54ef4 100644
--- a/lib/flow_control/burst_timeslot_filter_impl.h
+++ b/lib/flow_control/burst_timeslot_filter_impl.h
@@ -31,11 +31,20 @@
     class burst_timeslot_filter_impl : public burst_timeslot_filter
     {
      private:
+      filter_policy d_filter_policy;
       unsigned int d_timeslot;
      public:
       burst_timeslot_filter_impl(unsigned int timeslot);
       ~burst_timeslot_filter_impl();
       void process_burst(pmt::pmt_t msg);
+
+      /* External API */
+      unsigned int get_tn(void);
+      unsigned int set_tn(unsigned int tn);
+
+      /* Filtering policy */
+      filter_policy get_policy(void);
+      filter_policy set_policy(filter_policy policy);
     };
 
   } // namespace gsm
diff --git a/lib/flow_control/dummy_burst_filter_impl.cc b/lib/flow_control/dummy_burst_filter_impl.cc
index 33c24cb..4241111 100644
--- a/lib/flow_control/dummy_burst_filter_impl.cc
+++ b/lib/flow_control/dummy_burst_filter_impl.cc
@@ -60,7 +60,8 @@
     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))
+              gr::io_signature::make(0, 0, 0)),
+        d_filter_policy(FILTER_POLICY_DEFAULT)
     {
         message_port_register_in(pmt::mp("in"));        
         message_port_register_out(pmt::mp("out"));
@@ -75,6 +76,14 @@
 
     void dummy_burst_filter_impl::process_burst(pmt::pmt_t msg)
     {
+        if (d_filter_policy == FILTER_POLICY_DROP_ALL)
+          return;
+
+        if (d_filter_policy == FILTER_POLICY_PASS_ALL) {
+          message_port_pub(pmt::mp("out"), msg);
+          return;
+        }
+
         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);
@@ -100,6 +109,20 @@
         }
         return true;
     }
+
+    /* Filtering policy */
+    filter_policy
+    dummy_burst_filter_impl::get_policy(void)
+    {
+      return d_filter_policy;
+    }
+
+    filter_policy
+    dummy_burst_filter_impl::set_policy(filter_policy policy)
+    {
+      d_filter_policy = policy;
+      return d_filter_policy;
+    }
     
   } /* namespace gsm */
 } /* namespace gr */
diff --git a/lib/flow_control/dummy_burst_filter_impl.h b/lib/flow_control/dummy_burst_filter_impl.h
index ce9c741..953ae94 100644
--- a/lib/flow_control/dummy_burst_filter_impl.h
+++ b/lib/flow_control/dummy_burst_filter_impl.h
@@ -35,10 +35,16 @@
      private:
       bool is_dummy_burst(int8_t *burst, size_t burst_len);
       static const int8_t d_dummy_burst[];
+      filter_policy d_filter_policy;
      public:
       dummy_burst_filter_impl();
       ~dummy_burst_filter_impl();
       void process_burst(pmt::pmt_t msg);
+
+      /* External API */
+      /* Filtering policy */
+      filter_policy get_policy(void);
+      filter_policy set_policy(filter_policy policy);
     };
 
   } // namespace gsm
diff --git a/lib/receiver/receiver_config.cc b/lib/receiver/receiver_config.cc
index 0abf200..44e3b6c 100644
--- a/lib/receiver/receiver_config.cc
+++ b/lib/receiver/receiver_config.cc
@@ -53,8 +53,8 @@
   if (timeslot_nr < 0) {
     timeslot_nr = timeslot_nr + 8;
 
-    t2 = (d_t2 - 1) % 26;
-    t3 = (d_t3 - 1) % 51;
+    t2 = (d_t2+26 - 1) % 26;
+    t3 = (d_t3+51 - 1) % 51;
 
     if ((d_t2 == 0) && (d_t3 == 0)) {
       t1 = (d_t1 - 1) % (1 << 11);
diff --git a/swig/grgsm_swig.i b/swig/grgsm_swig.i
index 68911ae..eab179c 100644
--- a/swig/grgsm_swig.i
+++ b/swig/grgsm_swig.i
@@ -16,6 +16,7 @@
 #include "grgsm/decryption/decryption.h"
 #include "grgsm/demapping/universal_ctrl_chans_demapper.h"
 #include "grgsm/demapping/tch_f_chans_demapper.h"
+#include "grgsm/flow_control/common.h"
 #include "grgsm/flow_control/burst_timeslot_splitter.h"
 #include "grgsm/flow_control/burst_sdcch_subslot_splitter.h"
 #include "grgsm/flow_control/burst_timeslot_filter.h"
@@ -63,6 +64,7 @@
 %include "grgsm/demapping/tch_f_chans_demapper.h"
 GR_SWIG_BLOCK_MAGIC2(gsm, tch_f_chans_demapper);
 
+%include "grgsm/flow_control/common.h"
 %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"