Added typical signalization channels (CCCH, BCCH, SDCCH) decoder and demapper for BCCH.
The implementation is quite dirty at this moment.
diff --git a/examples/receiver_file.grc b/examples/receiver_file.grc
index e277cd8..883ea2e 100644
--- a/examples/receiver_file.grc
+++ b/examples/receiver_file.grc
@@ -1,6 +1,6 @@
 <?xml version='1.0' encoding='ASCII'?>
 <flow_graph>
-  <timestamp>Sat Feb  8 13:47:51 2014</timestamp>
+  <timestamp>Fri Jul 18 10:24:08 2014</timestamp>
   <block>
     <key>options</key>
     <param>
@@ -52,6 +52,10 @@
       <value></value>
     </param>
     <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
       <key>_coordinate</key>
       <value>(10, 10)</value>
     </param>
@@ -75,6 +79,10 @@
       <value>1625000/6*4</value>
     </param>
     <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
       <key>_coordinate</key>
       <value>(10, 170)</value>
     </param>
@@ -84,6 +92,80 @@
     </param>
   </block>
   <block>
+    <key>blocks_message_debug</key>
+    <param>
+      <key>id</key>
+      <value>blocks_message_debug_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(630, 183)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gsm_receiver_hier</key>
+    <param>
+      <key>id</key>
+      <value>gsm_receiver_hier_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>input_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>osr</key>
+      <value>4</value>
+    </param>
+    <param>
+      <key>arfcn</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>minoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>maxoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(352, 163)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
     <key>blocks_file_source</key>
     <param>
       <key>id</key>
@@ -110,45 +192,10 @@
       <value>1</value>
     </param>
     <param>
-      <key>affinity</key>
+      <key>alias</key>
       <value></value>
     </param>
     <param>
-      <key>minoutbuf</key>
-      <value>0</value>
-    </param>
-    <param>
-      <key>maxoutbuf</key>
-      <value>0</value>
-    </param>
-    <param>
-      <key>_coordinate</key>
-      <value>(267, 220)</value>
-    </param>
-    <param>
-      <key>_rotation</key>
-      <value>0</value>
-    </param>
-  </block>
-  <block>
-    <key>gsm_receiver_hier</key>
-    <param>
-      <key>id</key>
-      <value>gsm_receiver_hier_0</value>
-    </param>
-    <param>
-      <key>_enabled</key>
-      <value>True</value>
-    </param>
-    <param>
-      <key>input_rate</key>
-      <value>samp_rate</value>
-    </param>
-    <param>
-      <key>osr</key>
-      <value>4</value>
-    </param>
-    <param>
       <key>affinity</key>
       <value></value>
     </param>
@@ -162,30 +209,7 @@
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(539, 220)</value>
-    </param>
-    <param>
-      <key>_rotation</key>
-      <value>0</value>
-    </param>
-  </block>
-  <block>
-    <key>blocks_message_debug</key>
-    <param>
-      <key>id</key>
-      <value>blocks_message_debug_0</value>
-    </param>
-    <param>
-      <key>_enabled</key>
-      <value>True</value>
-    </param>
-    <param>
-      <key>affinity</key>
-      <value></value>
-    </param>
-    <param>
-      <key>_coordinate</key>
-      <value>(905, 249)</value>
+      <value>(118, 171)</value>
     </param>
     <param>
       <key>_rotation</key>
diff --git a/examples/receiver_usrp.grc b/examples/receiver_usrp.grc
index b3be775..00d6852 100644
--- a/examples/receiver_usrp.grc
+++ b/examples/receiver_usrp.grc
@@ -1,6 +1,6 @@
 <?xml version='1.0' encoding='ASCII'?>
 <flow_graph>
-  <timestamp>Sat Feb  8 22:28:34 2014</timestamp>
+  <timestamp>Fri Jul 18 11:26:16 2014</timestamp>
   <block>
     <key>options</key>
     <param>
@@ -52,6 +52,10 @@
       <value></value>
     </param>
     <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
       <key>_coordinate</key>
       <value>(0, -1)</value>
     </param>
@@ -75,6 +79,10 @@
       <value>100e6/80</value>
     </param>
     <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
       <key>_coordinate</key>
       <value>(-1, 160)</value>
     </param>
@@ -110,6 +118,10 @@
       <value></value>
     </param>
     <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
       <key>_coordinate</key>
       <value>(486, 10)</value>
     </param>
@@ -165,6 +177,10 @@
       <value></value>
     </param>
     <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
       <key>_coordinate</key>
       <value>(368, -1)</value>
     </param>
@@ -174,6 +190,80 @@
     </param>
   </block>
   <block>
+    <key>gsm_receiver_hier</key>
+    <param>
+      <key>id</key>
+      <value>gsm_receiver_hier_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>input_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>osr</key>
+      <value>4</value>
+    </param>
+    <param>
+      <key>arfcn</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>minoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>maxoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(348, 237)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gsm_bursts_printer</key>
+    <param>
+      <key>id</key>
+      <value>gsm_bursts_printer_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(587, 257)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
     <key>variable_slider</key>
     <param>
       <key>id</key>
@@ -193,15 +283,15 @@
     </param>
     <param>
       <key>min</key>
-      <value>800</value>
+      <value>900</value>
     </param>
     <param>
       <key>max</key>
-      <value>1900</value>
+      <value>1000</value>
     </param>
     <param>
       <key>num_steps</key>
-      <value>1000</value>
+      <value>500</value>
     </param>
     <param>
       <key>style</key>
@@ -220,6 +310,10 @@
       <value></value>
     </param>
     <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
       <key>_coordinate</key>
       <value>(236, 0)</value>
     </param>
@@ -229,38 +323,98 @@
     </param>
   </block>
   <block>
-    <key>gsm_receiver_hier</key>
+    <key>wxgui_fftsink2</key>
     <param>
       <key>id</key>
-      <value>gsm_receiver_hier_0</value>
+      <value>wxgui_fftsink2_0</value>
     </param>
     <param>
       <key>_enabled</key>
       <value>True</value>
     </param>
     <param>
-      <key>input_rate</key>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>FFT Plot</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
       <value>samp_rate</value>
     </param>
     <param>
-      <key>osr</key>
-      <value>4</value>
+      <key>baseband_freq</key>
+      <value>fc</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>2.0</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>15</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>win</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>freqvar</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
     </param>
     <param>
       <key>affinity</key>
       <value></value>
     </param>
     <param>
-      <key>minoutbuf</key>
-      <value>0</value>
-    </param>
-    <param>
-      <key>maxoutbuf</key>
-      <value>0</value>
-    </param>
-    <param>
       <key>_coordinate</key>
-      <value>(523, 275)</value>
+      <value>(654, 52)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -295,7 +449,11 @@
     </param>
     <param>
       <key>dev_addr</key>
-      <value>addr=192.168.11.2</value>
+      <value></value>
+    </param>
+    <param>
+      <key>dev_args</key>
+      <value>""</value>
     </param>
     <param>
       <key>sync</key>
@@ -311,7 +469,7 @@
     </param>
     <param>
       <key>clock_source0</key>
-      <value></value>
+      <value>internal</value>
     </param>
     <param>
       <key>time_source0</key>
@@ -926,6 +1084,10 @@
       <value>0</value>
     </param>
     <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
       <key>affinity</key>
       <value></value>
     </param>
@@ -939,36 +1101,19 @@
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(235, 251)</value>
+      <value>(101, 229)</value>
     </param>
     <param>
       <key>_rotation</key>
       <value>0</value>
     </param>
   </block>
-  <block>
-    <key>gsm_bursts_printer</key>
-    <param>
-      <key>id</key>
-      <value>gsm_bursts_printer_0</value>
-    </param>
-    <param>
-      <key>_enabled</key>
-      <value>True</value>
-    </param>
-    <param>
-      <key>affinity</key>
-      <value></value>
-    </param>
-    <param>
-      <key>_coordinate</key>
-      <value>(776, 287)</value>
-    </param>
-    <param>
-      <key>_rotation</key>
-      <value>0</value>
-    </param>
-  </block>
+  <connection>
+    <source_block_id>uhd_usrp_source_0</source_block_id>
+    <sink_block_id>gsm_receiver_hier_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
   <connection>
     <source_block_id>gsm_receiver_hier_0</source_block_id>
     <sink_block_id>gsm_bursts_printer_0</sink_block_id>
@@ -977,7 +1122,7 @@
   </connection>
   <connection>
     <source_block_id>uhd_usrp_source_0</source_block_id>
-    <sink_block_id>gsm_receiver_hier_0</sink_block_id>
+    <sink_block_id>wxgui_fftsink2_0</sink_block_id>
     <source_key>0</source_key>
     <sink_key>0</sink_key>
   </connection>
diff --git a/examples/receiver_usrp_channelizer.grc b/examples/receiver_usrp_channelizer.grc
index bae5c32..1c45f45 100644
--- a/examples/receiver_usrp_channelizer.grc
+++ b/examples/receiver_usrp_channelizer.grc
@@ -1,6 +1,6 @@
 <?xml version='1.0' encoding='ASCII'?>
 <flow_graph>
-  <timestamp>Sun Feb  9 11:14:11 2014</timestamp>
+  <timestamp>Fri Jul 18 10:24:38 2014</timestamp>
   <block>
     <key>options</key>
     <param>
@@ -52,6 +52,10 @@
       <value></value>
     </param>
     <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
       <key>_coordinate</key>
       <value>(0, -1)</value>
     </param>
@@ -64,29 +68,6 @@
     <key>variable</key>
     <param>
       <key>id</key>
-      <value>samp_rate2</value>
-    </param>
-    <param>
-      <key>_enabled</key>
-      <value>True</value>
-    </param>
-    <param>
-      <key>value</key>
-      <value>samp_rate/25</value>
-    </param>
-    <param>
-      <key>_coordinate</key>
-      <value>(-1, 160)</value>
-    </param>
-    <param>
-      <key>_rotation</key>
-      <value>0</value>
-    </param>
-  </block>
-  <block>
-    <key>variable</key>
-    <param>
-      <key>id</key>
       <value>samp_rate</value>
     </param>
     <param>
@@ -98,6 +79,10 @@
       <value>100e6/10</value>
     </param>
     <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
       <key>_coordinate</key>
       <value>(2, 223)</value>
     </param>
@@ -107,6 +92,33 @@
     </param>
   </block>
   <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>samp_rate2</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>samp_rate/25</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(-1, 160)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
     <key>parameter</key>
     <param>
       <key>id</key>
@@ -133,6 +145,10 @@
       <value></value>
     </param>
     <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
       <key>_coordinate</key>
       <value>(486, 10)</value>
     </param>
@@ -188,6 +204,10 @@
       <value></value>
     </param>
     <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
       <key>_coordinate</key>
       <value>(368, -1)</value>
     </param>
@@ -197,6 +217,198 @@
     </param>
   </block>
   <block>
+    <key>gsm_bursts_printer</key>
+    <param>
+      <key>id</key>
+      <value>gsm_bursts_printer_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1019, 136)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>fc</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value></value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>957</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>800</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(236, 0)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>gsm_receiver_hier</key>
+    <param>
+      <key>id</key>
+      <value>gsm_receiver_hier_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>input_rate</key>
+      <value>samp_rate2</value>
+    </param>
+    <param>
+      <key>osr</key>
+      <value>4</value>
+    </param>
+    <param>
+      <key>arfcn</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>minoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>maxoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(755, 130)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>pfb_channelizer_ccf</key>
+    <param>
+      <key>id</key>
+      <value>pfb_channelizer_ccf_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>nchans</key>
+      <value>25</value>
+    </param>
+    <param>
+      <key>taps</key>
+      <value></value>
+    </param>
+    <param>
+      <key>osr</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>atten</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>ch_map</key>
+      <value>[]</value>
+    </param>
+    <param>
+      <key>bus_conns</key>
+      <value>[[0,],]</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>minoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>maxoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(384, 217)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
     <key>uhd_usrp_source</key>
     <param>
       <key>id</key>
@@ -224,7 +436,11 @@
     </param>
     <param>
       <key>dev_addr</key>
-      <value>addr=192.168.11.2</value>
+      <value></value>
+    </param>
+    <param>
+      <key>dev_args</key>
+      <value>""</value>
     </param>
     <param>
       <key>sync</key>
@@ -855,123 +1071,10 @@
       <value>0</value>
     </param>
     <param>
-      <key>affinity</key>
+      <key>alias</key>
       <value></value>
     </param>
     <param>
-      <key>minoutbuf</key>
-      <value>0</value>
-    </param>
-    <param>
-      <key>maxoutbuf</key>
-      <value>0</value>
-    </param>
-    <param>
-      <key>_coordinate</key>
-      <value>(126, 251)</value>
-    </param>
-    <param>
-      <key>_rotation</key>
-      <value>0</value>
-    </param>
-  </block>
-  <block>
-    <key>gsm_bursts_printer</key>
-    <param>
-      <key>id</key>
-      <value>gsm_bursts_printer_0</value>
-    </param>
-    <param>
-      <key>_enabled</key>
-      <value>True</value>
-    </param>
-    <param>
-      <key>affinity</key>
-      <value></value>
-    </param>
-    <param>
-      <key>_coordinate</key>
-      <value>(1019, 136)</value>
-    </param>
-    <param>
-      <key>_rotation</key>
-      <value>0</value>
-    </param>
-  </block>
-  <block>
-    <key>variable_slider</key>
-    <param>
-      <key>id</key>
-      <value>fc</value>
-    </param>
-    <param>
-      <key>_enabled</key>
-      <value>True</value>
-    </param>
-    <param>
-      <key>label</key>
-      <value></value>
-    </param>
-    <param>
-      <key>value</key>
-      <value>957</value>
-    </param>
-    <param>
-      <key>min</key>
-      <value>800</value>
-    </param>
-    <param>
-      <key>max</key>
-      <value>1000</value>
-    </param>
-    <param>
-      <key>num_steps</key>
-      <value>1000</value>
-    </param>
-    <param>
-      <key>style</key>
-      <value>wx.SL_HORIZONTAL</value>
-    </param>
-    <param>
-      <key>converver</key>
-      <value>float_converter</value>
-    </param>
-    <param>
-      <key>grid_pos</key>
-      <value></value>
-    </param>
-    <param>
-      <key>notebook</key>
-      <value></value>
-    </param>
-    <param>
-      <key>_coordinate</key>
-      <value>(236, 0)</value>
-    </param>
-    <param>
-      <key>_rotation</key>
-      <value>0</value>
-    </param>
-  </block>
-  <block>
-    <key>gsm_receiver_hier</key>
-    <param>
-      <key>id</key>
-      <value>gsm_receiver_hier_0_0</value>
-    </param>
-    <param>
-      <key>_enabled</key>
-      <value>True</value>
-    </param>
-    <param>
-      <key>input_rate</key>
-      <value>samp_rate2</value>
-    </param>
-    <param>
-      <key>osr</key>
-      <value>4</value>
-    </param>
-    <param>
       <key>affinity</key>
       <value></value>
     </param>
@@ -985,58 +1088,7 @@
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(755, 130)</value>
-    </param>
-    <param>
-      <key>_rotation</key>
-      <value>0</value>
-    </param>
-  </block>
-  <block>
-    <key>pfb_channelizer_ccf</key>
-    <param>
-      <key>id</key>
-      <value>pfb_channelizer_ccf_0</value>
-    </param>
-    <param>
-      <key>_enabled</key>
-      <value>True</value>
-    </param>
-    <param>
-      <key>nchans</key>
-      <value>25</value>
-    </param>
-    <param>
-      <key>taps</key>
-      <value></value>
-    </param>
-    <param>
-      <key>osr</key>
-      <value>1</value>
-    </param>
-    <param>
-      <key>atten</key>
-      <value>100</value>
-    </param>
-    <param>
-      <key>ch_map</key>
-      <value>[]</value>
-    </param>
-    <param>
-      <key>affinity</key>
-      <value></value>
-    </param>
-    <param>
-      <key>minoutbuf</key>
-      <value>0</value>
-    </param>
-    <param>
-      <key>maxoutbuf</key>
-      <value>0</value>
-    </param>
-    <param>
-      <key>_coordinate</key>
-      <value>(373, 282)</value>
+      <value>(126, 251)</value>
     </param>
     <param>
       <key>_rotation</key>
diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt
index 6de687a..15b3673 100644
--- a/grc/CMakeLists.txt
+++ b/grc/CMakeLists.txt
@@ -21,5 +21,7 @@
     gsm_bursts_printer.xml
     gsm_fcch_burst_tagger.xml
     gsm_sch_detector.xml
-    gsm_fcch_detector.xml DESTINATION share/gnuradio/grc/blocks
+    gsm_fcch_detector.xml
+    gsm_get_bcch_or_ccch_bursts.xml
+    gsm_control_channels_decoder.xml DESTINATION share/gnuradio/grc/blocks
 )
diff --git a/grc/gsm_control_channels_decoder.xml b/grc/gsm_control_channels_decoder.xml
new file mode 100644
index 0000000..b106ff7
--- /dev/null
+++ b/grc/gsm_control_channels_decoder.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<block>
+  <name>Control channels decoder</name>
+  <key>gsm_control_channels_decoder</key>
+  <category>GSM</category>
+  <import>import gsm</import>
+  <make>gsm.control_channels_decoder()</make>
+  <sink>
+    <name>bursts</name>
+    <type>message</type>
+  </sink>
+<!--  <source>-->
+<!--    <name>msgs_out</name>-->
+<!--    <type>message</type>-->
+<!--  </source>-->
+</block>
diff --git a/grc/gsm_get_bcch_or_ccch_bursts.xml b/grc/gsm_get_bcch_or_ccch_bursts.xml
new file mode 100644
index 0000000..c08bdd7
--- /dev/null
+++ b/grc/gsm_get_bcch_or_ccch_bursts.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<block>
+  <name>Demapper for BCCH and CCCH</name>
+  <key>gsm_get_bcch_or_ccch_bursts</key>
+  <category>GSM</category>
+  <import>import gsm</import>
+  <make>gsm.get_bcch_or_ccch_bursts()</make>
+  <sink>
+    <name>bursts</name>
+    <type>message</type>
+  </sink>
+  <source>
+    <name>bursts</name>
+    <type>message</type>
+  </source>
+</block>
diff --git a/include/gsm/CMakeLists.txt b/include/gsm/CMakeLists.txt
index c7f4fb3..49f4a43 100644
--- a/include/gsm/CMakeLists.txt
+++ b/include/gsm/CMakeLists.txt
@@ -23,5 +23,8 @@
 install(FILES
     api.h
     receiver.h
-    bursts_printer.h DESTINATION include/gsm
+    bursts_printer.h
+    get_bcch_or_ccch_bursts.h
+    control_channels_decoder.h 
+    gsmtap.h DESTINATION include/gsm
 )
diff --git a/include/gsm/control_channels_decoder.h b/include/gsm/control_channels_decoder.h
new file mode 100644
index 0000000..a44f43e
--- /dev/null
+++ b/include/gsm/control_channels_decoder.h
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2014 <+YOU OR YOUR COMPANY+>.
+ * 
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_GSM_CONTROL_CHANNELS_DECODER_H
+#define INCLUDED_GSM_CONTROL_CHANNELS_DECODER_H
+
+#include <gsm/api.h>
+#include <gnuradio/block.h>
+
+namespace gr {
+  namespace gsm {
+
+    /*!
+     * \brief <+description of block+>
+     * \ingroup gsm
+     *
+     */
+    class GSM_API control_channels_decoder : virtual public gr::block
+    {
+     public:
+      typedef boost::shared_ptr<control_channels_decoder> sptr;
+
+      /*!
+       * \brief Return a shared_ptr to a new instance of gsm::control_channels_decoder.
+       *
+       * To avoid accidental use of raw pointers, gsm::control_channels_decoder's
+       * constructor is in a private implementation
+       * class. gsm::control_channels_decoder::make is the public interface for
+       * creating new instances.
+       */
+      static sptr make();
+    };
+
+  } // namespace gsm
+} // namespace gr
+
+#endif /* INCLUDED_GSM_CONTROL_CHANNELS_DECODER_H */
+
diff --git a/include/gsm/get_bcch_or_ccch_bursts.h b/include/gsm/get_bcch_or_ccch_bursts.h
new file mode 100644
index 0000000..d74137a
--- /dev/null
+++ b/include/gsm/get_bcch_or_ccch_bursts.h
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2014 <+YOU OR YOUR COMPANY+>.
+ * 
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_GSM_GET_BCCH_OR_CCCH_BURSTS_H
+#define INCLUDED_GSM_GET_BCCH_OR_CCCH_BURSTS_H
+
+#include <gsm/api.h>
+#include <gnuradio/block.h>
+
+namespace gr {
+  namespace gsm {
+
+    /*!
+     * \brief <+description of block+>
+     * \ingroup gsm
+     *
+     */
+    class GSM_API get_bcch_or_ccch_bursts : virtual public gr::block
+    {
+     public:
+      typedef boost::shared_ptr<get_bcch_or_ccch_bursts> sptr;
+
+      /*!
+       * \brief Return a shared_ptr to a new instance of gsm::get_bcch_or_ccch_bursts.
+       *
+       * To avoid accidental use of raw pointers, gsm::get_bcch_or_ccch_bursts's
+       * constructor is in a private implementation
+       * class. gsm::get_bcch_or_ccch_bursts::make is the public interface for
+       * creating new instances.
+       */
+      static sptr make();
+    };
+
+  } // namespace gsm
+} // namespace gr
+
+#endif /* INCLUDED_GSM_GET_BCCH_OR_CCCH_BURSTS_H */
+
diff --git a/lib/receiver/gsmtap.h b/include/gsm/gsmtap.h
similarity index 100%
rename from lib/receiver/gsmtap.h
rename to include/gsm/gsmtap.h
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 931e0c1..79fa57a 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -30,7 +30,11 @@
     receiver/viterbi_detector.cc 
     receiver/sch.c
     burst_printer/bursts_printer_impl.cc
-    )
+    demapping/get_bcch_or_ccch_bursts_impl.cc
+    decoding/control_channels_decoder_impl.cc
+    decoding/cch.c
+    decoding/fire_crc.c
+)
 
 add_library(gnuradio-gsm SHARED ${gsm_sources})
 target_link_libraries(gnuradio-gsm ${Boost_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES}  
diff --git a/lib/burst_printer/bursts_printer_impl.cc b/lib/burst_printer/bursts_printer_impl.cc
index dbb7023..c37838b 100644
--- a/lib/burst_printer/bursts_printer_impl.cc
+++ b/lib/burst_printer/bursts_printer_impl.cc
@@ -23,10 +23,10 @@
 #endif
 
 #include <gnuradio/io_signature.h>
-#include "bursts_printer_impl.h"
-#include <gsmtap.h>
+#include <gsm/gsmtap.h>
 #include <iterator>
 #include <algorithm>
+#include "bursts_printer_impl.h"
 
 namespace gr {
   namespace gsm {
diff --git a/lib/decoding/cch.c b/lib/decoding/cch.c
new file mode 100644
index 0000000..16db5eb
--- /dev/null
+++ b/lib/decoding/cch.c
@@ -0,0 +1,553 @@
+//#include "system.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+
+//#include <exception>
+//#include <stdexcept>
+#include <math.h>
+//#include "burst_types.h"
+#include "cch.h"
+#include "fire_crc.h"
+
+
+/*
+ * GSM SACCH -- Slow Associated Control Channel
+ *
+ * These messages are encoded exactly the same as on the BCCH.
+ * (Broadcast Control Channel.)
+ *
+ * 	Input: 184 bits
+ * 	
+ * 	1. Add parity and flushing bits. (Output 184 + 40 + 4 = 228 bit)
+ * 	2. Convolutional encode. (Output 228 * 2 = 456 bit)
+ * 	3. Interleave. (Output 456 bit)
+ * 	4. Map on bursts. (4 x 156 bit bursts with each 2x57 bit content data)
+ */
+
+
+/*
+ * Parity (FIRE) for the GSM SACCH channel.
+ *
+ * 	g(x) = (x^23 + 1)(x^17 + x^3 + 1)
+ * 	     = x^40 + x^26 + x^23 + x^17 + x^3 + 1
+ */
+
+static const unsigned char parity_polynomial[PARITY_SIZE + 1] = {
+   1, 0, 0, 0, 0, 0, 0, 0,
+   0, 0, 0, 0, 0, 0, 1, 0,
+   0, 1, 0, 0, 0, 0, 0, 1,
+   0, 0, 0, 0, 0, 0, 0, 0,
+   0, 0, 0, 0, 0, 1, 0, 0,
+   1
+};
+
+// remainder after dividing data polynomial by g(x)
+static const unsigned char parity_remainder[PARITY_SIZE] = {
+   1, 1, 1, 1, 1, 1, 1, 1,
+   1, 1, 1, 1, 1, 1, 1, 1,
+   1, 1, 1, 1, 1, 1, 1, 1,
+   1, 1, 1, 1, 1, 1, 1, 1,
+   1, 1, 1, 1, 1, 1, 1, 1
+};
+
+
+/*
+static void parity_encode(unsigned char *d, unsigned char *p) {
+
+	int i;
+	unsigned char buf[DATA_BLOCK_SIZE + PARITY_SIZE], *q;
+
+	memcpy(buf, d, DATA_BLOCK_SIZE);
+	memset(buf + DATA_BLOCK_SIZE, 0, PARITY_SIZE);
+
+	for(q = buf; q < buf + DATA_BLOCK_SIZE; q++)
+		if(*q)
+			for(i = 0; i < PARITY_SIZE + 1; i++)
+				q[i] ^= parity_polynomial[i];
+	for(i = 0; i < PARITY_SIZE; i++)
+		p[i] = !buf[DATA_BLOCK_SIZE + i];
+}
+ */
+
+
+int parity_check(unsigned char *d) {
+
+	unsigned int i;
+	unsigned char buf[DATA_BLOCK_SIZE + PARITY_SIZE], *q;
+
+	memcpy(buf, d, DATA_BLOCK_SIZE + PARITY_SIZE);
+
+	for(q = buf; q < buf + DATA_BLOCK_SIZE; q++)
+		if(*q)
+			for(i = 0; i < PARITY_SIZE + 1; i++)
+				q[i] ^= parity_polynomial[i];
+	return memcmp(buf + DATA_BLOCK_SIZE, parity_remainder, PARITY_SIZE);
+}
+
+
+/*
+ * Convolutional encoding and Viterbi decoding for the GSM SACCH channel.
+ */
+
+/*
+ * Convolutional encoding:
+ *
+ *	G_0 = 1 + x^3 + x^4
+ *	G_1 = 1 + x + x^3 + x^4
+ *
+ * i.e.,
+ *
+ *	c_{2k} = u_k + u_{k - 3} + u_{k - 4}
+ *	c_{2k + 1} = u_k + u_{k - 1} + u_{k - 3} + u_{k - 4}
+ */
+#define K		5
+#define MAX_ERROR	(2 * CONV_INPUT_SIZE + 1)
+
+
+/*
+ * Given the current state and input bit, what are the output bits?
+ *
+ * 	encode[current_state][input_bit]
+ */
+static const unsigned int encode[1 << (K - 1)][2] = {
+	{0, 3}, {3, 0}, {3, 0}, {0, 3},
+	{0, 3}, {3, 0}, {3, 0}, {0, 3},
+	{1, 2}, {2, 1}, {2, 1}, {1, 2},
+	{1, 2}, {2, 1}, {2, 1}, {1, 2}
+};
+
+
+/*
+ * Given the current state and input bit, what is the next state?
+ * 
+ * 	next_state[current_state][input_bit]
+ */
+static const unsigned int next_state[1 << (K - 1)][2] = {
+	{0, 8}, {0, 8}, {1, 9}, {1, 9},
+	{2, 10}, {2, 10}, {3, 11}, {3, 11},
+	{4, 12}, {4, 12}, {5, 13}, {5, 13},
+	{6, 14}, {6, 14}, {7, 15}, {7, 15}
+};
+
+
+/*
+ * Given the previous state and the current state, what input bit caused
+ * the transition?  If it is impossible to transition between the two
+ * states, the value is 2.
+ *
+ * 	prev_next_state[previous_state][current_state]
+ */
+static const unsigned int prev_next_state[1 << (K - 1)][1 << (K - 1)] = {
+        { 0,  2,  2,  2,  2,  2,  2,  2,  1,  2,  2,  2,  2,  2,  2,  2},
+        { 0,  2,  2,  2,  2,  2,  2,  2,  1,  2,  2,  2,  2,  2,  2,  2},
+        { 2,  0,  2,  2,  2,  2,  2,  2,  2,  1,  2,  2,  2,  2,  2,  2},
+        { 2,  0,  2,  2,  2,  2,  2,  2,  2,  1,  2,  2,  2,  2,  2,  2},
+        { 2,  2,  0,  2,  2,  2,  2,  2,  2,  2,  1,  2,  2,  2,  2,  2},
+        { 2,  2,  0,  2,  2,  2,  2,  2,  2,  2,  1,  2,  2,  2,  2,  2},
+        { 2,  2,  2,  0,  2,  2,  2,  2,  2,  2,  2,  1,  2,  2,  2,  2},
+        { 2,  2,  2,  0,  2,  2,  2,  2,  2,  2,  2,  1,  2,  2,  2,  2},
+        { 2,  2,  2,  2,  0,  2,  2,  2,  2,  2,  2,  2,  1,  2,  2,  2},
+        { 2,  2,  2,  2,  0,  2,  2,  2,  2,  2,  2,  2,  1,  2,  2,  2},
+        { 2,  2,  2,  2,  2,  0,  2,  2,  2,  2,  2,  2,  2,  1,  2,  2},
+        { 2,  2,  2,  2,  2,  0,  2,  2,  2,  2,  2,  2,  2,  1,  2,  2},
+        { 2,  2,  2,  2,  2,  2,  0,  2,  2,  2,  2,  2,  2,  2,  1,  2},
+        { 2,  2,  2,  2,  2,  2,  0,  2,  2,  2,  2,  2,  2,  2,  1,  2},
+        { 2,  2,  2,  2,  2,  2,  2,  0,  2,  2,  2,  2,  2,  2,  2,  1},
+        { 2,  2,  2,  2,  2,  2,  2,  0,  2,  2,  2,  2,  2,  2,  2,  1}
+};
+
+
+static inline unsigned int hamming_distance2(unsigned int w) {
+
+	return (w & 1) + !!(w & 2);
+}
+
+
+/*
+static void conv_encode(unsigned char *data, unsigned char *output) {
+
+	unsigned int i, state = 0, o;
+
+	// encode data
+	for(i = 0; i < CONV_INPUT_SIZE; i++) {
+		o = encode[state][data[i]];
+		state = next_state[state][data[i]];
+		*output++ = !!(o & 2);
+		*output++ = o & 1;
+	}
+}
+ */
+
+
+int conv_decode(unsigned char *output, unsigned char *data) {
+
+	int i, t;
+	unsigned int rdata, state, nstate, b, o, distance, accumulated_error,
+	   min_state, min_error, cur_state;
+
+	unsigned int ae[1 << (K - 1)]; // accumulated error
+	unsigned int nae[1 << (K - 1)]; // next accumulated error
+	unsigned int state_history[1 << (K - 1)][CONV_INPUT_SIZE + 1];
+
+	// initialize accumulated error, assume starting state is 0
+	for(i = 0; i < (1 << (K - 1)); i++){
+		ae[i] = nae[i] = MAX_ERROR;
+	}
+	
+	ae[0] = 0;
+
+	// build trellis
+	for(t = 0; t < CONV_INPUT_SIZE; t++) {
+
+		// get received data symbol
+		rdata = (data[2 * t] << 1) | data[2 * t + 1];
+
+		// for each state
+		for(state = 0; state < (1 << (K - 1)); state++) {
+
+			// make sure this state is possible
+			if(ae[state] >= MAX_ERROR)
+				continue;
+
+			// find all states we lead to
+			for(b = 0; b < 2; b++) {
+
+				// get next state given input bit b
+				nstate = next_state[state][b];
+
+				// find output for this transition
+				o = encode[state][b];
+
+				// calculate distance from received data
+				distance = hamming_distance2(rdata ^ o);
+
+				// choose surviving path
+				accumulated_error = ae[state] + distance;
+				if(accumulated_error < nae[nstate]) {
+
+					// save error for surviving state
+					nae[nstate] = accumulated_error;
+
+					// update state history
+					state_history[nstate][t + 1] = state;
+				}
+			}
+		}
+		
+		// get accumulated error ready for next time slice
+		for(i = 0; i < (1 << (K - 1)); i++) {
+			ae[i] = nae[i];
+			nae[i] = MAX_ERROR;
+		}
+	}
+
+	// the final state is the state with the fewest errors
+	min_state = (unsigned int)-1;
+	min_error = MAX_ERROR;
+	for(i = 0; i < (1 << (K - 1)); i++) {
+		if(ae[i] < min_error) {
+			min_state = i;
+			min_error = ae[i];
+		}
+	}
+
+	// trace the path
+	cur_state = min_state;
+	for(t = CONV_INPUT_SIZE; t >= 1; t--) {
+		min_state = cur_state;
+		cur_state = state_history[cur_state][t]; // get previous
+		output[t - 1] = prev_next_state[cur_state][min_state];
+	}
+
+	// return the number of errors detected (hard-decision)
+	return min_error;
+}
+
+
+/*
+ * GSM SACCH interleaving and burst mapping
+ *
+ * Interleaving:
+ *
+ * Given 456 coded input bits, form 4 blocks of 114 bits:
+ *
+ * 	i(B, j) = c(n, k)	k = 0, ..., 455
+ * 				n = 0, ..., N, N + 1, ...
+ * 				B = B_0 + 4n + (k mod 4)
+ * 				j = 2(49k mod 57) + ((k mod 8) div 4)
+ *
+ * Mapping on Burst:
+ *
+ * 	e(B, j) = i(B, j)
+ * 	e(B, 59 + j) = i(B, 57 + j)	j = 0, ..., 56
+ * 	e(B, 57) = h_l(B)
+ * 	e(B, 58) = h_n(B)
+ *
+ * Where h_l(B) and h_n(B) are bits in burst B indicating flags.
+ */
+
+/*
+static void interleave(unsigned char *data, unsigned char *iBLOCK) {
+
+	int j, k, B;
+
+	// for each bit in input data
+	for(k = 0; k < CONV_SIZE; k++) {
+		B = k % 4;
+		j = 2 * ((49 * k) % 57) + ((k % 8) / 4);
+		iBLOCK[B * iBLOCK_SIZE + j] = data[k];
+	}
+}
+ */
+
+
+#if 0
+static void decode_interleave(unsigned char *data, unsigned char *iBLOCK) {
+
+	int j, k, B;
+
+	for(k = 0; k < CONV_SIZE; k++) {
+		B = k % 4;
+		j = 2 * ((49 * k) % 57) + ((k % 8) / 4);
+		data[k] = iBLOCK[B * iBLOCK_SIZE + j];
+	}
+}
+
+#endif
+
+/*
+static void burstmap(unsigned char *iBLOCK, unsigned char *eBLOCK,
+   unsigned char hl, unsigned char hn) {
+
+	int j;
+
+	for(j = 0; j < 57; j++) {
+		eBLOCK[j] = iBLOCK[j];
+		eBLOCK[j + 59] = iBLOCK[j + 57];
+	}
+	eBLOCK[57] = hl;
+	eBLOCK[58] = hn;
+}
+ */
+
+
+static void decode_burstmap(unsigned char *iBLOCK, unsigned char *eBLOCK,
+   unsigned char *hl, unsigned char *hn) {
+
+	int j;
+
+	for(j = 0; j < 57; j++) {
+		iBLOCK[j] = eBLOCK[j];
+		iBLOCK[j + 57] = eBLOCK[j + 59];
+	}
+	*hl = eBLOCK[57];
+	*hn = eBLOCK[58];
+}
+
+
+/*
+ * Transmitted bits are sent least-significant first.
+ */
+static int compress_bits(unsigned char *dbuf, unsigned int dbuf_len,
+   unsigned char *sbuf, unsigned int sbuf_len) {
+
+	unsigned int i, j, c, pos = 0;
+
+	if(dbuf_len < ((sbuf_len + 7) >> 3))
+		return -1;
+
+	for(i = 0; i < sbuf_len; i += 8) {
+		for(j = 0, c = 0; (j < 8) && (i + j < sbuf_len); j++)
+			c |= (!!sbuf[i + j]) << j;
+		dbuf[pos++] = c & 0xff;
+	}
+	return pos;
+}
+
+
+#if 0
+int get_ns_l3_len(unsigned char *data, unsigned int datalen) {
+
+	if((data[0] & 3) != 1) {
+		fprintf(stderr, "error: get_ns_l3_len: pseudo-length reserved "
+		   "bits bad (%2.2x)\n", data[0] & 3);
+		return -1;
+	}
+	return (data[0] >> 2);
+}
+
+#endif
+
+
+/*static unsigned char *decode_sacch(GS_CTX *ctx, unsigned char *burst, unsigned int *datalen) {*/
+
+/*	int errors, len, data_size;*/
+/*	unsigned char conv_data[CONV_SIZE], iBLOCK[BLOCKS][iBLOCK_SIZE],*/
+/*	   hl, hn, decoded_data[PARITY_OUTPUT_SIZE];*/
+/*	FC_CTX fc_ctx;*/
+
+/*	data_size = sizeof ctx->msg;*/
+/*	if(datalen)*/
+/*		*datalen = 0;*/
+
+/*	// unmap the bursts*/
+/*	decode_burstmap(iBLOCK[0], burst, &hl, &hn); // XXX ignore stealing bits*/
+/*	decode_burstmap(iBLOCK[1], burst + 116, &hl, &hn);*/
+/*	decode_burstmap(iBLOCK[2], burst + 116 * 2, &hl, &hn);*/
+/*	decode_burstmap(iBLOCK[3], burst + 116 * 3, &hl, &hn);*/
+
+/*	// remove interleave*/
+/*	interleave_decode(&ctx->interleave_ctx, conv_data, (unsigned char *)iBLOCK);*/
+/*	//decode_interleave(conv_data, (unsigned char *)iBLOCK);*/
+
+/*	// Viterbi decode*/
+/*	errors = conv_decode(decoded_data, conv_data);*/
+/*	//DEBUGF("conv_decode: %d\n", errors);*/
+
+/*	// check parity*/
+/*	// If parity check error detected try to fix it.*/
+/*	if (parity_check(decoded_data))*/
+/*	{*/
+/*		unsigned char crc_result[224];*/
+/*		if (FC_check_crc(&fc_ctx, decoded_data, crc_result) == 0)*/
+/*		{*/
+/*			errors = -1;*/
+/*			//DEBUGF("error: sacch: parity error (%d fn=%d)\n",*/
+/*			//	errors, ctx->fn);*/
+/*			return NULL;*/
+/*		} else {*/
+/*			//DEBUGF("Successfully corrected parity bits! (errors=%d fn=%d)\n",*/
+/*			//	errors, ctx->fn);*/
+/*			memcpy(decoded_data, crc_result, sizeof crc_result);*/
+/*			errors = 0;*/
+/*		}*/
+/*	}*/
+
+/*	if (errors)*/
+/*		printf("WRN: errors=%d fn=%d\n", errors, ctx->fn);*/
+
+/*	if((len = compress_bits(ctx->msg, data_size, decoded_data,*/
+/*	   DATA_BLOCK_SIZE)) < 0) {*/
+/*		fprintf(stderr, "error: compress_bits\n");*/
+/*		return NULL;*/
+/*	}*/
+/*	if(len < data_size) {*/
+/*		fprintf(stderr, "error: buf too small (%d < %d)\n",*/
+/*		   sizeof(ctx->msg), len);*/
+/*		return NULL;*/
+/*	}*/
+
+/*	if(datalen)*/
+/*		*datalen = (unsigned int)len;*/
+/*	return ctx->msg;*/
+/*}*/
+
+
+/*
+ * decode_cch
+ *
+ * 	Decode a "common" control channel.  Most control channels use
+ * 	the same burst, interleave, Viterbi and parity configuration.
+ * 	The documentation for the control channels defines SACCH first
+ * 	and then just keeps referring to that.
+ *
+ * 	The current (investigated) list is as follows:
+ *
+ * 		BCCH Norm
+ * 		BCCH Ext
+ * 		PCH
+ * 		AGCH
+ * 		CBCH (SDCCH/4)
+ * 		CBCH (SDCCH/8)
+ * 		SDCCH/4
+ * 		SACCH/C4
+ * 		SDCCH/8
+ * 		SACCH/C8
+ *
+ * 	We provide two functions, one for where all four bursts are
+ * 	contiguous, and one where they aren't.
+ */
+/*unsigned char *decode_cch(GS_CTX *ctx, unsigned char *burst, unsigned int *datalen) {*/
+
+/*	return decode_sacch(ctx, burst, datalen);*/
+/*}*/
+
+
+#if 0
+unsigned char *decode_cch(GS_CTX *ctx, unsigned char *e, unsigned int *datalen) {
+
+	return decode_sacch(ctx, e, e + eBLOCK_SIZE, e + 2 * eBLOCK_SIZE,
+	   e + 3 * eBLOCK_SIZE, datalen);
+}
+#endif
+
+/*unsigned char *decode_facch(GS_CTX *ctx, unsigned char *burst, unsigned int *datalen, int offset) {*/
+
+/*	int errors, len, data_size;*/
+/*	unsigned char conv_data[CONV_SIZE], iBLOCK[BLOCKS * 2][iBLOCK_SIZE],*/
+/*	   hl, hn, decoded_data[PARITY_OUTPUT_SIZE];*/
+/*	FC_CTX fc_ctx;*/
+
+/*	data_size = sizeof ctx->msg;*/
+/*	if(datalen)*/
+/*		*datalen = 0;*/
+
+/*	// unmap the bursts*/
+/*	decode_burstmap(iBLOCK[0], burst, &hl, &hn); // XXX ignore stealing bits*/
+/*	decode_burstmap(iBLOCK[1], burst + 116, &hl, &hn);*/
+/*	decode_burstmap(iBLOCK[2], burst + 116 * 2, &hl, &hn);*/
+/*	decode_burstmap(iBLOCK[3], burst + 116 * 3, &hl, &hn);*/
+/*	decode_burstmap(iBLOCK[4], burst + 116 * 4, &hl, &hn);*/
+/*	decode_burstmap(iBLOCK[5], burst + 116 * 5, &hl, &hn);*/
+/*	decode_burstmap(iBLOCK[6], burst + 116 * 6, &hl, &hn);*/
+/*	decode_burstmap(iBLOCK[7], burst + 116 * 7, &hl, &hn);*/
+
+/*	// remove interleave*/
+/*	if (offset == 0)*/
+/*		interleave_decode(&ctx->interleave_facch_f1_ctx, conv_data, (unsigned char *)iBLOCK);*/
+/*	else*/
+/*		interleave_decode(&ctx->interleave_facch_f2_ctx, conv_data, (unsigned char *)iBLOCK);*/
+/*	//decode_interleave(conv_data, (unsigned char *)iBLOCK);*/
+
+/*	// Viterbi decode*/
+/*	errors = conv_decode(decoded_data, conv_data);*/
+/*	//DEBUGF("conv_decode: %d\n", errors);*/
+
+/*	// check parity*/
+/*	// If parity check error detected try to fix it.*/
+/*	if (parity_check(decoded_data)) {*/
+/*		FC_init(&fc_ctx, 40, 184);*/
+/*		unsigned char crc_result[224];*/
+/*		if (FC_check_crc(&fc_ctx, decoded_data, crc_result) == 0)*/
+/*		{*/
+/*			//DEBUGF("error: sacch: parity error (errors=%d fn=%d)\n", errors, ctx->fn);*/
+/*			errors = -1;*/
+/*			return NULL;*/
+/*		} else {*/
+/*			//DEBUGF("Successfully corrected parity bits! (errors=%d fn=%d)\n", errors, ctx->fn);*/
+/*			memcpy(decoded_data, crc_result, sizeof crc_result);*/
+/*			errors = 0;*/
+/*		}*/
+/*	}*/
+
+/*	if (errors)*/
+/*		fprintf(stderr, "WRN: errors=%d fn=%d\n", errors, ctx->fn);*/
+
+/*	if ((len = compress_bits(ctx->msg, data_size, decoded_data,*/
+/*							DATA_BLOCK_SIZE)) < 0) {*/
+/*		fprintf(stderr, "error: compress_bits\n");*/
+/*		return NULL;*/
+/*	}*/
+/*	if (len < data_size) {*/
+/*		fprintf(stderr, "error: buf too small (%d < %d)\n",*/
+/*		   sizeof(ctx->msg), len);*/
+/*		return NULL;*/
+/*	}*/
+
+/*	if (datalen)*/
+/*		*datalen = (unsigned int)len;*/
+/*	return ctx->msg;*/
+/*}*/
diff --git a/lib/decoding/cch.h b/lib/decoding/cch.h
new file mode 100644
index 0000000..efd5615
--- /dev/null
+++ b/lib/decoding/cch.h
@@ -0,0 +1,59 @@
+//TODO: this file shouldn't be part of the GSM Receiver
+#ifndef __GSMSTACK_CCH_H__
+#define __GSMSTACK_CCH_H__ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//#include "gsmstack.h"
+
+/*
+ * decode_cch
+ *
+ * 	Decode a "common" control channel.  Most control channels use
+ * 	the same burst, interleave, Viterbi and parity configuration.
+ * 	The documentation for the control channels defines SACCH first
+ * 	and then just keeps referring to that.
+ *
+ * 	The current (investigated) list is as follows:
+ *
+ * 		BCCH Norm
+ * 		BCCH Ext
+ * 		PCH
+ * 		AGCH
+ * 		CBCH (SDCCH/4)
+ * 		CBCH (SDCCH/8)
+ * 		SDCCH/4
+ * 		SACCH/C4
+ * 		SDCCH/8
+ * 		SACCH/C8
+ *
+ * 	We provide two functions, one for where all four bursts are
+ * 	contiguous, and one where they aren't.
+ */
+
+#define DATA_BLOCK_SIZE		184
+#define PARITY_SIZE		40
+#define FLUSH_BITS_SIZE		4
+#define PARITY_OUTPUT_SIZE (DATA_BLOCK_SIZE + PARITY_SIZE + FLUSH_BITS_SIZE)
+
+#define CONV_INPUT_SIZE		PARITY_OUTPUT_SIZE
+#define CONV_SIZE		(2 * CONV_INPUT_SIZE)
+
+#define BLOCKS			4
+#define iBLOCK_SIZE		(CONV_SIZE / BLOCKS)
+#define eBLOCK_SIZE		(iBLOCK_SIZE + 2)
+
+int conv_decode(unsigned char *output, unsigned char *data);
+int parity_check(unsigned char *d);
+//unsigned char *decode_cch(GS_CTX *ctx, unsigned char *burst, unsigned int *len);
+//unsigned char *decode_facch(GS_CTX *ctx, unsigned char *burst, unsigned int *len, int offset);
+//unsigned char *decode_cch(GS_CTX *ctx, unsigned char *, unsigned char *, unsigned char *, unsigned char *, unsigned int *len);
+//unsigned char *decode_cch(GS_CTX *ctx, unsigned char *, unsigned int *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/decoding/control_channels_decoder_impl.cc b/lib/decoding/control_channels_decoder_impl.cc
new file mode 100644
index 0000000..544e6bb
--- /dev/null
+++ b/lib/decoding/control_channels_decoder_impl.cc
@@ -0,0 +1,147 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2014 <+YOU OR YOUR COMPANY+>.
+ * 
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this software; 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 <gsm/gsmtap.h>
+#include "control_channels_decoder_impl.h"
+
+namespace gr {
+  namespace gsm {
+
+    control_channels_decoder::sptr
+    control_channels_decoder::make()
+    {
+      return gnuradio::get_initial_sptr
+        (new control_channels_decoder_impl());
+    }
+
+    /*
+     * The private constructor
+     */
+    control_channels_decoder_impl::control_channels_decoder_impl()
+      : gr::block("control_channels_decoder",
+              gr::io_signature::make(0, 0, 0),
+              gr::io_signature::make(0, 0, 0)),
+              d_collected_bursts_num(0)
+    {
+        //initialize de/interleaver
+        int j, k, B;
+        for (k = 0; k < CONV_SIZE; k++)
+        {
+            B = k % 4;
+            j = 2 * ((49 * k) % 57) + ((k % 8) / 4);
+            interleave_trans[k] = B * 114 + j; //114=57 + 57
+        }
+
+        FC_init(&fc_ctx, 40, 184);
+        message_port_register_in(pmt::mp("bursts"));
+        set_msg_handler(pmt::mp("bursts"), boost::bind(&control_channels_decoder_impl::decode, this, _1));
+//        message_port_register_out(pmt::mp(""));
+    }
+
+    /*
+     * Our virtual destructor.
+     */
+    control_channels_decoder_impl::~control_channels_decoder_impl()
+    {
+    }
+
+    void control_channels_decoder_impl::decode(pmt::pmt_t msg)
+    {
+        unsigned char iBLOCK[BLOCKS*iBLOCK_SIZE], hl, hn, conv_data[CONV_SIZE], decoded_data[PARITY_OUTPUT_SIZE];
+        d_bursts[d_collected_bursts_num] = msg;
+        d_collected_bursts_num++;
+        //get convecutive bursts
+        pmt::pmt_t header_blob = pmt::car(msg);
+        gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(header_blob);
+        
+        if(d_collected_bursts_num==4)
+        {
+            d_collected_bursts_num=0;
+            //reorganize data
+            for(int ii = 0; ii < 4; ii++)
+            {
+                pmt::pmt_t burst_content = pmt::cdr(d_bursts[ii]);
+                int8_t * burst_bits = (int8_t *)pmt::blob_data(burst_content);
+
+                for(int jj = 0; jj < 57; jj++)
+                {
+                    iBLOCK[ii*iBLOCK_SIZE+jj] = burst_bits[jj + 3];
+                    iBLOCK[ii*iBLOCK_SIZE+jj+57] = burst_bits[jj + 88]; //88 = 3+57+1+26+1
+                }
+            }
+            //deinterleave
+            for (int k = 0; k < CONV_SIZE; k++)
+            {
+                conv_data[k] = iBLOCK[interleave_trans[k]];
+            }
+            //convolutional code decode
+            int errors = conv_decode(decoded_data, conv_data);
+            //std::cout << "Errors:" << errors << " " << parity_check(decoded_data) << std::endl;
+            // check parity
+            // If parity check error detected try to fix it.
+
+            if (parity_check(decoded_data))
+            {
+                FC_init(&fc_ctx, 40, 184);
+                unsigned char crc_result[PARITY_OUTPUT_SIZE];
+                if (FC_check_crc(&fc_ctx, decoded_data, crc_result) == 0)
+                {
+                    //("error: sacch: parity error (errors=%d fn=%d)\n", errors, ctx->fn);
+                    //std::cout << "Uncorrectable errors!" << std::endl;
+                    errors = -1;
+                } else {
+                    //DEBUGF("Successfully corrected parity bits! (errors=%d fn=%d)\n", errors, ctx->fn);
+                    //std::cout << "Corrected some errors" << std::endl;
+                    memcpy(decoded_data, crc_result, PARITY_OUTPUT_SIZE);
+                    errors = 0;
+                }
+            } else {
+                //std::cout << "Everything correct" << std::endl;
+            }
+           //compress bits
+           unsigned char outmsg[27];
+           unsigned char sbuf_len=224;
+           int i, j, c, pos=0;
+           for(i = 0; i < sbuf_len; i += 8) {
+                 for(j = 0, c = 0; (j < 8) && (i + j < sbuf_len); j++){
+                     c |= (!!decoded_data[i + j]) << j;
+                 }
+                 outmsg[pos++] = c & 0xff;
+             }
+
+           //printf("%6d %d:", (0 + 1), 0);
+           int jj=0;
+             while (jj < 23){
+                 printf(" %02x", outmsg[jj]);//decoded_data[jj]);
+                 jj++;
+               }
+             printf("\n");
+             fflush(stdout);
+        }
+        return;
+    }
+  } /* namespace gsm */
+} /* namespace gr */
+
diff --git a/lib/decoding/control_channels_decoder_impl.h b/lib/decoding/control_channels_decoder_impl.h
new file mode 100644
index 0000000..41404fa
--- /dev/null
+++ b/lib/decoding/control_channels_decoder_impl.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2014 <+YOU OR YOUR COMPANY+>.
+ * 
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GSM_CONTROL_CHANNELS_DECODER_IMPL_H
+#define INCLUDED_GSM_CONTROL_CHANNELS_DECODER_IMPL_H
+
+#include <gsm/control_channels_decoder.h>
+#include "fire_crc.h"
+#include "cch.h"
+
+namespace gr {
+  namespace gsm {
+
+    class control_channels_decoder_impl : public control_channels_decoder
+    {
+     private:
+      unsigned int d_collected_bursts_num;
+      pmt::pmt_t d_bursts[4];
+      unsigned short interleave_trans[CONV_SIZE];      
+      FC_CTX fc_ctx;      
+      void decode(pmt::pmt_t msg);
+     public:
+      control_channels_decoder_impl();
+      ~control_channels_decoder_impl();
+    };
+
+  } // namespace gsm
+} // namespace gr
+
+#endif /* INCLUDED_GSM_CONTROL_CHANNELS_DECODER_IMPL_H */
+
diff --git a/lib/decoding/fire_crc.c b/lib/decoding/fire_crc.c
new file mode 100644
index 0000000..7cdfc0b
--- /dev/null
+++ b/lib/decoding/fire_crc.c
@@ -0,0 +1,179 @@
+//TODO: this file shouldn't be part of the GSM Receiver
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "fire_crc.h"
+#include <stdio.h>
+#include <string.h>
+
+#define REM(x, y)	(x) % (y)
+
+static int FC_syndrome_shift(FC_CTX *ctx, unsigned int bit);
+
+static int
+outit(int *data, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		printf("%d ", data[i]);
+	printf("\n");
+}
+
+int
+FC_init(FC_CTX *ctx, unsigned int crc_size, unsigned int data_size)
+{
+	ctx->crc_size = crc_size;
+	ctx->data_size = data_size;
+	ctx->syn_start = 0;
+
+	return 0;
+}
+
+int
+FC_check_crc(FC_CTX *ctx, unsigned char *input_bits, unsigned char *control_data)
+{ 
+	int j,error_count = 0, error_index = 0, success_flag = 0, syn_index = 0;
+	unsigned int i;
+
+	ctx->syn_start = 0;
+	// reset the syndrome register
+	memset(ctx->syndrome_reg, 0, sizeof ctx->syndrome_reg);
+
+	// shift in the data bits
+    for (i=0; i < ctx->data_size; i++) {
+        error_count = FC_syndrome_shift(ctx, input_bits[i]);
+        control_data[i] = input_bits[i];
+    }
+
+    // shift in the crc bits
+    for (i=0; i < ctx->crc_size; i++) {
+        error_count = FC_syndrome_shift(ctx, 1-input_bits[i+ctx->data_size]);
+    }
+
+    // Find position of error burst
+    if (error_count == 0) {
+        error_index = 0;
+    }
+    else {
+        error_index = 1;
+        error_count = FC_syndrome_shift(ctx, 0);
+        error_index += 1;
+        while (error_index < (ctx->data_size + ctx->crc_size) ) {
+            error_count = FC_syndrome_shift(ctx, 0);
+            error_index += 1;
+            if ( error_count == 0 ) break;
+        }
+    }
+
+    // Test for correctable errors
+    //printf("error_index %d\n",error_index);
+    if (error_index == 224) success_flag = 0;
+    else {
+
+        // correct index depending on the position of the error
+        if (error_index == 0) syn_index = error_index;
+        else syn_index = error_index - 1;
+        
+        // error burst lies within data bits
+        if (error_index < 184) {
+            //printf("error < bit 184,%d\n",error_index);
+            j = error_index;
+            while ( j < (error_index+12) ) {
+                if (j < 184) {
+                    control_data[j] = control_data[j] ^ 
+                       ctx->syndrome_reg[REM(ctx->syn_start+39-j+syn_index,40)];
+                }               
+                else break;
+                j = j + 1;
+            }
+        }
+        else if ( error_index > 212 ) {
+            //printf("error > bit 212,%d\n",error_index);
+            j = 0;
+            while ( j < (error_index - 212) ) {
+                control_data[j] = control_data[j] ^ 
+                      ctx->syndrome_reg[REM(ctx->syn_start+39-j-224+syn_index,40)];
+                j = j + 1;
+            }
+        }
+        // for 183 < error_index < 213 error in parity alone so ignore
+        success_flag = 1;
+    }
+    return success_flag;
+}    
+
+static int 
+FC_syndrome_shift(FC_CTX *ctx, unsigned int bit)
+{
+	int error_count = 0;
+	unsigned int i;
+
+	if (ctx->syn_start == 0)
+		ctx->syn_start = 39;
+	else ctx->syn_start -= 1;
+
+	int temp_syndrome_reg[sizeof ctx->syndrome_reg];
+
+	memcpy(temp_syndrome_reg, ctx->syndrome_reg, sizeof temp_syndrome_reg);
+
+    temp_syndrome_reg[REM(ctx->syn_start+3,40)] = 
+                       ctx->syndrome_reg[REM(ctx->syn_start+3,40)] ^
+                       ctx->syndrome_reg[ctx->syn_start];
+    temp_syndrome_reg[REM(ctx->syn_start+17,40)] = 
+                       ctx->syndrome_reg[REM(ctx->syn_start+17,40)] ^
+                       ctx->syndrome_reg[ctx->syn_start];
+    temp_syndrome_reg[REM(ctx->syn_start+23,40)] = 
+                       ctx->syndrome_reg[REM(ctx->syn_start+23,40)] ^
+                       ctx->syndrome_reg[ctx->syn_start];
+    temp_syndrome_reg[REM(ctx->syn_start+26,40)] = 
+                       ctx->syndrome_reg[REM(ctx->syn_start+26,40)] ^
+                       ctx->syndrome_reg[ctx->syn_start];
+
+    temp_syndrome_reg[REM(ctx->syn_start+4,40)] = 
+                       ctx->syndrome_reg[REM(ctx->syn_start+4,40)] ^ bit;
+    temp_syndrome_reg[REM(ctx->syn_start+6,40)] = 
+                       ctx->syndrome_reg[REM(ctx->syn_start+6,40)] ^ bit;
+    temp_syndrome_reg[REM(ctx->syn_start+10,40)] = 
+                       ctx->syndrome_reg[REM(ctx->syn_start+10,40)] ^ bit;
+    temp_syndrome_reg[REM(ctx->syn_start+16,40)] = 
+                       ctx->syndrome_reg[REM(ctx->syn_start+16,40)] ^ bit;
+    temp_syndrome_reg[REM(ctx->syn_start+27,40)] = 
+                       ctx->syndrome_reg[REM(ctx->syn_start+27,40)] ^ bit;
+    temp_syndrome_reg[REM(ctx->syn_start+29,40)] = 
+                       ctx->syndrome_reg[REM(ctx->syn_start+29,40)] ^ bit;
+    temp_syndrome_reg[REM(ctx->syn_start+33,40)] = 
+                       ctx->syndrome_reg[REM(ctx->syn_start+33,40)] ^ bit;
+    temp_syndrome_reg[REM(ctx->syn_start+39,40)] = 
+                       ctx->syndrome_reg[REM(ctx->syn_start+39,40)] ^ bit;
+
+    temp_syndrome_reg[ctx->syn_start] = ctx->syndrome_reg[ctx->syn_start] ^ bit;
+
+	memcpy(ctx->syndrome_reg, temp_syndrome_reg, sizeof ctx->syndrome_reg);
+
+    for (i = 0; i < 28; i++) {
+       error_count = error_count + ctx->syndrome_reg[REM(ctx->syn_start+i,40)];
+    }
+    return error_count;
+}
+ 
+
diff --git a/lib/decoding/fire_crc.h b/lib/decoding/fire_crc.h
new file mode 100644
index 0000000..aa6319c
--- /dev/null
+++ b/lib/decoding/fire_crc.h
@@ -0,0 +1,47 @@
+//TODO: this file shouldn't be part of the GSM Receiver
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef INCLUDED_FIRE_CRC_H
+#define INCLUDED_FIRE_CRC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct
+{
+	unsigned int crc_size;
+	unsigned int data_size;
+	unsigned int syn_start;
+	int syndrome_reg[40];
+} FC_CTX;
+
+int FC_init(FC_CTX *ctx, unsigned int crc_size, unsigned int data_size);
+int FC_check_crc(FC_CTX *ctx, unsigned char *input_bits, unsigned char *control_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/decoding/interleave.c b/lib/decoding/interleave.c
new file mode 100644
index 0000000..8388a6f
--- /dev/null
+++ b/lib/decoding/interleave.c
@@ -0,0 +1,71 @@
+//TODO: this file shouldn't be part of the GSM Receiver
+#include <stdlib.h>
+#include <stdio.h>
+#include "interleave.h"
+
+int
+interleave_init(INTERLEAVE_CTX *ictx, int size, int block_size)
+{
+	ictx->trans_size = size;
+	ictx->trans = (unsigned short *)malloc(size * sizeof *ictx->trans);
+
+//	DEBUGF("size: %d\n", size);
+//	DEBUGF("Block size: %d\n", block_size);
+	int j, k, B;
+	for (k = 0; k < size; k++)
+	{
+		B = k % 4;
+		j = 2 * ((49 * k) % 57) + ((k % 8) / 4);
+		ictx->trans[k] = B * block_size + j;
+		/* Mapping: pos1 goes to pos2: pos1 -> pos2 */
+		//printf("%d -> %d\n", ictx->trans[k], k);
+	}
+//	exit(0);
+	return 0;
+}
+
+int
+interleave_init_facch_f(INTERLEAVE_CTX *ictx, int size, int block_size, int block_offset)
+{
+	ictx->trans_size = size;
+	ictx->trans = (unsigned short *)malloc(size * sizeof *ictx->trans);
+
+//	DEBUGF("size: %d\n", size);
+//	DEBUGF("Block size: %d\n", block_size);
+	int j, k, B;
+	for (k = 0; k < size; k++)
+	{
+		B = (k + block_offset) % 8;
+		j = 2 * ((49 * k) % 57) + ((k % 8) / 4);
+		ictx->trans[k] = B * block_size + j;
+		/* Mapping: pos1 goes to pos2: pos1 -> pos2 */
+//		DEBUGF("%d -> %d\n", ictx->trans[k], k);
+	}
+//	exit(0);
+	return 0;
+}
+
+int
+interleave_deinit(INTERLEAVE_CTX *ictx)
+{
+	if (ictx->trans != NULL)
+	{
+		free(ictx->trans);
+		ictx->trans = NULL;
+	}
+
+	return 0;
+}
+
+void
+interleave_decode(INTERLEAVE_CTX *ictx, unsigned char *dst, unsigned char *src)
+{
+    printf("Lol\n");
+	int k;
+	for (k = 0; k < ictx->trans_size; k++)
+	{
+		printf("k=%d, ictx->trans[k]=%d\n", k, ictx->trans[k]);
+		dst[k] = src[ictx->trans[k]];
+    }
+}
+
diff --git a/lib/decoding/interleave.h b/lib/decoding/interleave.h
new file mode 100644
index 0000000..a50434a
--- /dev/null
+++ b/lib/decoding/interleave.h
@@ -0,0 +1,28 @@
+//TODO: this file shouldn't be part of the GSM Receiver
+/*
+ * $Id:$
+ */
+
+#ifndef __GSMSP_INTERLEAVE_H__
+#define __GSMSP_INTERLEAVE_H__ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _interleave_ctx
+{
+	unsigned short *trans;
+	int trans_size;
+} INTERLEAVE_CTX;
+
+int interleave_init(INTERLEAVE_CTX *ictx, int size, int block_size);
+int interleave_init_facch_f(INTERLEAVE_CTX *ictx, int size, int block_size, int block_offset);
+int interleave_deinit(INTERLEAVE_CTX *ictx);
+void interleave_decode(INTERLEAVE_CTX *ictx, unsigned char *dst, unsigned char *src);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/demapping/get_bcch_or_ccch_bursts_impl.cc b/lib/demapping/get_bcch_or_ccch_bursts_impl.cc
new file mode 100644
index 0000000..4e8d369
--- /dev/null
+++ b/lib/demapping/get_bcch_or_ccch_bursts_impl.cc
@@ -0,0 +1,100 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2014 <+YOU OR YOUR COMPANY+>.
+ * 
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this software; 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 <gsm/gsmtap.h>
+#include "get_bcch_or_ccch_bursts_impl.h"
+
+namespace gr {
+  namespace gsm {
+
+    get_bcch_or_ccch_bursts::sptr
+    get_bcch_or_ccch_bursts::make()
+    {
+      return gnuradio::get_initial_sptr
+        (new get_bcch_or_ccch_bursts_impl());
+    }
+
+    /*
+     * The private constructor
+     */
+    get_bcch_or_ccch_bursts_impl::get_bcch_or_ccch_bursts_impl()
+      : gr::block("get_bcch_or_ccch_bursts",
+              gr::io_signature::make(0, 0, 0),
+              gr::io_signature::make(0, 0, 0))
+    {
+        message_port_register_in(pmt::mp("bursts"));
+        set_msg_handler(pmt::mp("bursts"), boost::bind(&get_bcch_or_ccch_bursts_impl::filter_ccch, this, _1));
+        message_port_register_out(pmt::mp("bursts"));
+    }
+
+    /*
+     * Our virtual destructor.
+     */
+    get_bcch_or_ccch_bursts_impl::~get_bcch_or_ccch_bursts_impl()
+    {
+    }
+
+    void get_bcch_or_ccch_bursts_impl::filter_ccch(pmt::pmt_t msg)
+    {
+        pmt::pmt_t header_blob = pmt::car(msg);
+        pmt::pmt_t content = pmt::cdr(msg);
+        gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(header_blob);
+        uint32_t frame_nr = header->frame_number;
+
+        uint32_t fn_mod51 = header->frame_number % 51;
+        const int fn51_start = 6;
+        const int fn51_stop = 9;
+
+        if(header->timeslot==0){
+            if(fn_mod51>=fn51_start && fn_mod51<=fn51_stop){
+                uint32_t ii = fn_mod51-fn51_start;
+                d_frame_numbers[ii]=header->frame_number;
+                d_bursts[ii] = msg;
+            }
+            
+            if(fn_mod51==fn51_stop){
+                //check for a situation where some BCCH bursts were lost
+                //in this situation frame numbers won't be consecutive
+                bool frames_are_consecutive = true;
+                for(int jj=1; jj<4; jj++)
+                {
+                    if((d_frame_numbers[jj]-d_frame_numbers[jj-1])!=1){
+                        frames_are_consecutive = false;
+                    }
+                }
+                if(frames_are_consecutive)
+                {
+                    //send bursts to the output
+                    for(int jj=0; jj<4; jj++)
+                    {
+                        message_port_pub(pmt::mp("bursts"), d_bursts[jj]);
+                    }              
+                } 
+            }
+        }
+    }
+  } /* namespace gsm */
+} /* namespace gr */
+
diff --git a/lib/demapping/get_bcch_or_ccch_bursts_impl.h b/lib/demapping/get_bcch_or_ccch_bursts_impl.h
new file mode 100644
index 0000000..c3c4c59
--- /dev/null
+++ b/lib/demapping/get_bcch_or_ccch_bursts_impl.h
@@ -0,0 +1,44 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2014 <+YOU OR YOUR COMPANY+>.
+ * 
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GSM_GET_BCCH_OR_CCCH_BURSTS_IMPL_H
+#define INCLUDED_GSM_GET_BCCH_OR_CCCH_BURSTS_IMPL_H
+
+#include <gsm/get_bcch_or_ccch_bursts.h>
+
+namespace gr {
+  namespace gsm {
+
+    class get_bcch_or_ccch_bursts_impl : public get_bcch_or_ccch_bursts
+    {
+     private:
+         uint32_t d_frame_numbers[4];     
+         pmt::pmt_t d_bursts[4];                
+     public:
+        get_bcch_or_ccch_bursts_impl();
+        ~get_bcch_or_ccch_bursts_impl();
+        void filter_ccch(pmt::pmt_t msg);
+    };
+
+  } // namespace gsm
+} // namespace gr
+
+#endif /* INCLUDED_GSM_GET_BCCH_OR_CCCH_BURSTS_IMPL_H */
+
diff --git a/lib/receiver/receiver_impl.h b/lib/receiver/receiver_impl.h
index 42e6d01..200a951 100644
--- a/lib/receiver/receiver_impl.h
+++ b/lib/receiver/receiver_impl.h
@@ -22,9 +22,9 @@
 #define INCLUDED_GSM_RECEIVER_IMPL_H
 
 #include <gsm/receiver.h>
+#include <gsm/gsmtap.h>
 #include <gsm_constants.h>
 #include <receiver_config.h>
-#include <gsmtap.h>
 
 namespace gr {
   namespace gsm {
diff --git a/swig/gsm_swig.i b/swig/gsm_swig.i
index 12f48a4..27163f5 100644
--- a/swig/gsm_swig.i
+++ b/swig/gsm_swig.i
@@ -10,6 +10,8 @@
 %{
 #include "gsm/receiver.h"
 #include "gsm/bursts_printer.h"
+#include "gsm/get_bcch_or_ccch_bursts.h"
+#include "gsm/control_channels_decoder.h"
 %}
 
 
@@ -18,3 +20,7 @@
 %include "gsm/bursts_printer.h"
 GR_SWIG_BLOCK_MAGIC2(gsm, bursts_printer);
 
+%include "gsm/get_bcch_or_ccch_bursts.h"
+GR_SWIG_BLOCK_MAGIC2(gsm, get_bcch_or_ccch_bursts);
+%include "gsm/control_channels_decoder.h"
+GR_SWIG_BLOCK_MAGIC2(gsm, control_channels_decoder);