Merge branch 'development' of https://github.com/ptrkrysik/gr-gsm into development
diff --git a/.gitignore b/.gitignore
index 321fa74..99dd781 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,5 @@
 *.pyo
 .unittests
 build/
+debian/tmp/
+debian/files
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 551b982..0c84262 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,7 +5,7 @@
 env:
   #- DOCKERFILE=tests/dockerfiles/Debian_Jessie.docker IMGNAME=debjess-grgsm
   #- DOCKERFILE=tests/dockerfiles/Ubuntu_15_04.docker IMGNAME=ubu15.04-grgsm
-  - DOCKERFILE=tests/dockerfiles/Debian_testing.docker IMGNAME=debtest-grgsm
+  #- DOCKERFILE=tests/dockerfiles/Debian_testing.docker IMGNAME=debtest-grgsm
   - DOCKERFILE=tests/dockerfiles/Ubuntu_16_04.docker IMGNAME=ubu16.04-grgsm
 
 services:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 00c37dd..3e14c82 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -72,6 +72,8 @@
     if("${SWIG_VERSION}" VERSION_GREATER "1.3.30")
         set(SWIG_VERSION_CHECK TRUE)
     endif()
+else()
+    message(FATAL_ERROR "SWIG required to compile gr-gsm")
 endif(SWIG_FOUND)
 
 
diff --git a/README.md b/README.md
index c8ab407..bcd359f 100644
--- a/README.md
+++ b/README.md
@@ -26,7 +26,7 @@
 
 Development
 ===========
-New features are accepted through github's pull requests. When creating pull request try to make it adress one topic (addition of a feature x, corretion of bug y).
+New features are accepted through github's pull requests. When creating pull request try to make it adress one topic (addition of a feature x, correction of bug y).
 
 If you wish to develop something for gr-gsm but don't know exactly what, then look for issues with label "Enhancement". Select one that you feel you are able to complete. After that claim it by commenting in the comment section of the issue. If there is any additional information about gr-gsm needed by you to make completing the task easier - just ask.
 
diff --git a/apps/grgsm_decode b/apps/grgsm_decode
index 89c03d3..14578d5 100755
--- a/apps/grgsm_decode
+++ b/apps/grgsm_decode
@@ -105,7 +105,9 @@
 
         self.cch_decoder = grgsm.control_channels_decoder()
 
+        self.socket_pdu_server = blocks.socket_pdu("UDP_SERVER", "127.0.0.1", "4729", 10000) #added in order to avoid generating ICMP messages
         self.socket_pdu = blocks.socket_pdu("UDP_CLIENT", "127.0.0.1", "4729", 10000)
+
         if self.verbose:
             self.message_printer = grgsm.message_printer(pmt.intern(""), True, True, False)
 
@@ -362,8 +364,8 @@
                     break
 
     # open udp port 4729 to avoid icmp messages
-    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
-    sock.bind(("localhost", 4729))
+    #sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+    #sock.bind(("localhost", 4729))
 
     # instanciate decoder
     tb = grgsm_decoder(timeslot=options.timeslot, subslot=options.subslot, chan_mode=options.chan_mode,
@@ -379,4 +381,4 @@
     tb.wait()
 
     # we are done, close socket
-    sock.close()
+    #sock.close()
diff --git a/debian/build-package b/debian/build-package
index d0d822a..410ef0f 100755
--- a/debian/build-package
+++ b/debian/build-package
@@ -1,8 +1,10 @@
 #!/bin/bash
+VERSION=0.33
+
 cd ../..
 
-tar -acf gr-gsm_0.3.orig.tar.gz gr-gsm
+tar -acf gr-gsm_${VERSION}.orig.tar.gz gr-gsm
 cd gr-gsm
 debuild -S -sa
 cd ..
-dput ppa:ptrkrysik/gr-gsm gr-gsm_0.3-0ppa0_source.changes
+#dput ppa:ptrkrysik/gr-gsm gr-gsm_${VERSION}-0ppa0_source.changes
diff --git a/debian/changelog b/debian/changelog
index 2f7a22b..a43cd5c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,4 +1,4 @@
-gr-gsm (0.3-0ppa0) xenial; urgency=low
+gr-gsm (0.33-0ppa0) xenial; urgency=low
 
   * Initial upload!
 
diff --git a/debian/control b/debian/control
index d4e5661..d0c5f6c 100644
--- a/debian/control
+++ b/debian/control
@@ -1,13 +1,13 @@
 Source: gr-gsm
 Section: devel
 Priority: optional
-Maintainer: Your Name <your.email@some.where>
-Build-Depends: cmake, build-essential, python-scipy, gnuradio-dev, gr-osmosdr, libosmocore-dev
+Maintainer: Piotr Krysik <ptrkrysik@gmail.com>
+Build-Depends: cmake, python-scipy, gnuradio-dev, gr-osmosdr, libosmocore-dev, swig
 
-Homepage: http://www.yourhomepage.org
+Homepage: http://github.com/ptrkrysik/gr-gsm.git
 Package: gr-gsm
 Architecture: any
-Depends:  ${shlibs:Depends}, ${misc:Depends}, gnuradio, gr-osmosdr, python-scipy
-Description: First test-package
+Depends: gnuradio, gr-osmosdr, python-scipy, ${shlibs:Depends}, ${misc:Depends}
+Description: Gnuradio blocks and tools for receiving GSM transmissions
  Long description of greet-the-world.
  It can span multiple lines!
diff --git a/examples b/examples
index 9446043..405c987 160000
--- a/examples
+++ b/examples
@@ -1 +1 @@
-Subproject commit 9446043efe0fe6883e4e962261230c9034ac71a9
+Subproject commit 405c987b2bdb76bcfb0951e7aa90c8fb75f2f8dd
diff --git a/grc/decoding/gsm_tch_f_decoder.xml b/grc/decoding/gsm_tch_f_decoder.xml
index 632162f..3d1152e 100644
--- a/grc/decoding/gsm_tch_f_decoder.xml
+++ b/grc/decoding/gsm_tch_f_decoder.xml
@@ -3,7 +3,7 @@
   <name>TCH/F decoder</name>
   <key>gsm_tch_f_decoder</key>
   <import>import grgsm</import>
-  <make>grgsm.tch_f_decoder($mode, $file, $boundary_check)</make>
+  <make>grgsm.tch_f_decoder($mode, $boundary_check)</make>
 
   <param>
     <name>TCH coding mode</name>
@@ -51,15 +51,9 @@
     </option>
   </param>
   <param>
-    <name>destination file</name>
-    <key>file</key>
-    <value>/tmp/speech.gsm</value>
-    <type>file_open</type>
-  </param>
-  <param>
     <name>Voice boundary detection</name>
     <key>boundary_check</key>
-    <value>True</value>
+    <value>False</value>
     <type>bool</type>
     <option>
       <name>False</name>
@@ -80,7 +74,12 @@
     <type>message</type>
     <optional>1</optional>
   </source>
-  
+  <source>
+    <name>voice</name>
+    <type>message</type>
+    <optional>1</optional>
+  </source>
+    
   <doc>
 If "Voice boundary detection" is enabled, then only bursts are decoded as voice where
 
diff --git a/include/grgsm/decoding/tch_f_decoder.h b/include/grgsm/decoding/tch_f_decoder.h
index 18a1baa..93fe971 100644
--- a/include/grgsm/decoding/tch_f_decoder.h
+++ b/include/grgsm/decoding/tch_f_decoder.h
@@ -62,7 +62,7 @@
        * class. gsm::tch_f_decoder::make is the public interface for
        * creating new instances.
        */
-      static sptr make(tch_mode mode, const std::string &file, bool boundary_check=true);
+      static sptr make(tch_mode mode, bool boundary_check=false);
 
     };
 
diff --git a/lib/decoding/tch_f_decoder_impl.cc b/lib/decoding/tch_f_decoder_impl.cc
index f409d37..cc88c90 100644
--- a/lib/decoding/tch_f_decoder_impl.cc
+++ b/lib/decoding/tch_f_decoder_impl.cc
@@ -35,16 +35,16 @@
   namespace gsm {
 
     tch_f_decoder::sptr
-    tch_f_decoder::make(tch_mode mode, const std::string &file, bool boundary_check)
+    tch_f_decoder::make(tch_mode mode, bool boundary_check)
     {
       return gnuradio::get_initial_sptr
-        (new tch_f_decoder_impl(mode, file, boundary_check));
+        (new tch_f_decoder_impl(mode, boundary_check));
     }
 
     /*
      * Constructor
      */
-    tch_f_decoder_impl::tch_f_decoder_impl(tch_mode mode, const std::string &file, bool boundary_check)
+    tch_f_decoder_impl::tch_f_decoder_impl(tch_mode mode, bool boundary_check)
       : gr::block("tch_f_decoder",
               gr::io_signature::make(0, 0, 0),
               gr::io_signature::make(0, 0, 0)),
@@ -52,6 +52,7 @@
       d_collected_bursts_num(0),
       d_boundary_check(boundary_check),
       d_boundary_decode(!boundary_check),
+      d_header_sent(false),
       mBlockCoder(0x10004820009ULL, 40, 224),
       mU(228),
       mP(mU.segment(184,40)),
@@ -65,18 +66,11 @@
       mClass1A_d(mTCHD.head(50)),
       mTCHParity(0x0b, 3, 50)
     {
-        d_speech_file = fopen( file.c_str(), "wb" );
-        if (d_speech_file == NULL)
-        {
-            throw std::runtime_error("TCH/F Decoder: can't open file\n");
-        }
-
-        const unsigned char amr_nb_magic[6] = { 0x23, 0x21, 0x41, 0x4d, 0x52, 0x0a };
-
-        if (d_tch_mode != TCH_FS)
-        {
-            fwrite(amr_nb_magic, 1, 6, d_speech_file);
-        }
+        //setup input/output ports
+        message_port_register_in(pmt::mp("bursts"));
+        set_msg_handler(pmt::mp("bursts"), boost::bind(&tch_f_decoder_impl::decode, this, _1));
+        message_port_register_out(pmt::mp("msgs"));
+        message_port_register_out(pmt::mp("voice"));    
 
         int j, k, B;
         for (k = 0; k < CONV_SIZE; k++)
@@ -86,11 +80,6 @@
             interleave_trans[k] = B * 114 + j;
         }
 
-        //setup input/output ports
-        message_port_register_in(pmt::mp("bursts"));
-        set_msg_handler(pmt::mp("bursts"), boost::bind(&tch_f_decoder_impl::decode, this, _1));
-        message_port_register_out(pmt::mp("msgs"));
-
         setCodingMode(mode);
     }
 
@@ -100,9 +89,20 @@
 
     void tch_f_decoder_impl::decode(pmt::pmt_t msg)
     {
+        if(!d_header_sent)
+        {
+            if (d_tch_mode != TCH_FS)
+            {
+                const unsigned char amr_nb_magic[7] = "#!AMR\n";
+                message_port_pub(pmt::mp("voice"), pmt::cons(pmt::PMT_NIL, pmt::make_blob(amr_nb_magic,6)));
+            }
+            d_header_sent = true;
+        }
+
+
         d_bursts[d_collected_bursts_num] = msg;
         d_collected_bursts_num++;
-
+        
         bool stolen = false;
 
         if (d_collected_bursts_num == 8)
@@ -249,7 +249,7 @@
                 return;
             }
 
-            // Decode voice frames and write to file
+            // Decode voice frames and send to the output
             if (d_tch_mode == TCH_FS || d_tch_mode == TCH_EFR)
             {
                 mVR204Coder.decode(mClass1_c, mTCHU);
@@ -329,7 +329,7 @@
                         amrFrame.pack(frameBuffer);
 
                     }
-                    fwrite(frameBuffer, 1 , mTCHFrameLength, d_speech_file);
+                    message_port_pub(pmt::mp("voice"), pmt::cons(pmt::PMT_NIL, pmt::make_blob(frameBuffer,mTCHFrameLength)));
                 }
             }
             else
@@ -378,7 +378,7 @@
                     // mTCHD.unmap(mAMRBitOrder, payload.size(), payload);
                     mTCHD.copyTo(payload);
                     amrFrame.pack(frameBuffer);
-                    fwrite(frameBuffer, 1 , mAMRFrameLth, d_speech_file);
+                    message_port_pub(pmt::mp("voice"), pmt::cons(pmt::PMT_NIL, pmt::make_blob(frameBuffer,mAMRFrameLth)));
                 }
             }
         }
diff --git a/lib/decoding/tch_f_decoder_impl.h b/lib/decoding/tch_f_decoder_impl.h
index 3e8c79a..0119b5a 100644
--- a/lib/decoding/tch_f_decoder_impl.h
+++ b/lib/decoding/tch_f_decoder_impl.h
@@ -52,10 +52,10 @@
                 unsigned int d_collected_bursts_num;
                 unsigned short interleave_trans[CONV_SIZE];
                 pmt::pmt_t d_bursts[8];
-                FILE * d_speech_file;
                 enum tch_mode d_tch_mode;
                 bool d_boundary_check;
                 bool d_boundary_decode;
+                bool d_header_sent;
 
                 BitVector mU;
                 BitVector mP;
@@ -89,7 +89,7 @@
                 void decode(pmt::pmt_t msg);
                 void setCodingMode(tch_mode mode);
             public:
-                tch_f_decoder_impl(tch_mode mode, const std::string &file, bool boundary_check=true);
+                tch_f_decoder_impl(tch_mode mode, bool boundary_check=false);
                 ~tch_f_decoder_impl();
         };
 
diff --git a/lib/receiver/cx_channel_hopper_impl.cc b/lib/receiver/cx_channel_hopper_impl.cc
index 1fe15df..27a0cae 100644
--- a/lib/receiver/cx_channel_hopper_impl.cc
+++ b/lib/receiver/cx_channel_hopper_impl.cc
@@ -143,7 +143,9 @@
         gsmtap_hdr *header = (gsmtap_hdr *)pmt::blob_data(header_plus_burst);
 
         uint32_t frame_nr = be32toh(header->frame_number);
-        uint16_t frame_ca = be16toh(header->arfcn);
+        uint16_t frame_ca = be16toh(header->arfcn) & 0x3FFF;    //change highest bits to '0'
+                                                                //in order to leave only ARFCN number
+
         int mai = calculate_ma_sfh(d_maio, d_hsn, d_narfcn, frame_nr);
 
         if(d_ma[mai] == (int)frame_ca) {