Merge pull request #49 from romankh/master

Correction of TCH and FACCH burst demapping
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e0dff42..0e92e87 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -22,7 +22,7 @@
 # Project setup
 ########################################################################
 cmake_minimum_required(VERSION 2.6)
-project(gr-gsm CXX C)
+project(gr-grgsm CXX C)
 enable_testing()
 
 #set(CMAKE_BUILD_TYPE "Debug")
diff --git a/README.md b/README.md
index 4245bae..06ff638 100644
--- a/README.md
+++ b/README.md
@@ -96,7 +96,7 @@
 ```
 To start *Wireshark* straight to analysis of the *GSMTAP* packets obtained from *gr-gsm*'s airprobe use following command:
 ```
-sudo wireshark -k -Y '!icmp && gsmtap' -i lo
+sudo wireshark -k -f udp -Y gsmtap -i lo
 ````
 
 If you want to avoid the risks caused by running *Wireshark* with root privileges follow this short howto:
@@ -135,6 +135,8 @@
 cmake ..
 make
 sudo make install
+```
+
 
 Installation using Docker
 =========================
@@ -143,6 +145,12 @@
 The installation guide is available here:
 https://github.com/marcelmaatkamp/docker-gnuradio-gr-gsm-ptrkrysik
 
+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).
+
+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.
+
 Videos
 ======
 Short presentation of *Airprobe*'like application of *gr-gsm*:
diff --git a/apps/airprobe_rtlsdr.grc b/apps/airprobe_rtlsdr.grc
index 64e20a5..bbec4c0 100644
--- a/apps/airprobe_rtlsdr.grc
+++ b/apps/airprobe_rtlsdr.grc
@@ -513,7 +513,7 @@
     </param>
     <param>
       <key>stop</key>
-      <value>960e6</value>
+      <value>1990e6</value>
     </param>
     <param>
       <key>step</key>
diff --git a/apps/airprobe_rtlsdr.py b/apps/airprobe_rtlsdr.py
old mode 100644
new mode 100755
index 3ec4367..ba40fa9
--- a/apps/airprobe_rtlsdr.py
+++ b/apps/airprobe_rtlsdr.py
@@ -2,7 +2,7 @@
 ##################################################
 # Gnuradio Python Flow Graph
 # Title: Airprobe Rtlsdr
-# Generated: Sun Feb 15 11:35:00 2015
+# Generated: Tue Apr 28 22:47:46 2015
 ##################################################
 
 from PyQt4 import Qt
@@ -118,13 +118,13 @@
             def setValue(self, value):
                 super(Qwt.QwtCounter, self).setValue(value)
         self._fc_slider_counter = qwt_counter_pyslot()
-        self._fc_slider_counter.setRange(925e6, 960e6, 2e5)
+        self._fc_slider_counter.setRange(925e6, 1990e6, 2e5)
         self._fc_slider_counter.setNumButtons(2)
         self._fc_slider_counter.setValue(self.fc_slider)
         self._fc_slider_tool_bar.addWidget(self._fc_slider_counter)
         self._fc_slider_counter.valueChanged.connect(self.set_fc_slider)
         self._fc_slider_slider = Qwt.QwtSlider(None, Qt.Qt.Horizontal, Qwt.QwtSlider.BottomScale, Qwt.QwtSlider.BgSlot)
-        self._fc_slider_slider.setRange(925e6, 960e6, 2e5)
+        self._fc_slider_slider.setRange(925e6, 1990e6, 2e5)
         self._fc_slider_slider.setValue(self.fc_slider)
         self._fc_slider_slider.setMinimumWidth(100)
         self._fc_slider_slider.valueChanged.connect(self.set_fc_slider)
@@ -153,6 +153,27 @@
         )
         self.qtgui_freq_sink_x_0.set_update_time(0.10)
         self.qtgui_freq_sink_x_0.set_y_axis(-140, 10)
+        self.qtgui_freq_sink_x_0.enable_autoscale(False)
+        self.qtgui_freq_sink_x_0.enable_grid(False)
+        self.qtgui_freq_sink_x_0.set_fft_average(1.0)
+        
+        labels = ["", "", "", "", "",
+                  "", "", "", "", ""]
+        widths = [1, 1, 1, 1, 1,
+                  1, 1, 1, 1, 1]
+        colors = ["blue", "red", "green", "black", "cyan",
+                  "magenta", "yellow", "dark red", "dark green", "dark blue"]
+        alphas = [1.0, 1.0, 1.0, 1.0, 1.0,
+                  1.0, 1.0, 1.0, 1.0, 1.0]
+        for i in xrange(1):
+            if len(labels[i]) == 0:
+                self.qtgui_freq_sink_x_0.set_line_label(i, "Data {0}".format(i))
+            else:
+                self.qtgui_freq_sink_x_0.set_line_label(i, labels[i])
+            self.qtgui_freq_sink_x_0.set_line_width(i, widths[i])
+            self.qtgui_freq_sink_x_0.set_line_color(i, colors[i])
+            self.qtgui_freq_sink_x_0.set_line_alpha(i, alphas[i])
+        
         self._qtgui_freq_sink_x_0_win = sip.wrapinstance(self.qtgui_freq_sink_x_0.pyqwidget(), Qt.QWidget)
         self.top_layout.addWidget(self._qtgui_freq_sink_x_0_win)
         self.gsm_universal_ctrl_chans_demapper_0 = grgsm.universal_ctrl_chans_demapper(0, ([2,6,12,16,22,26,32,36,42,46]), ([BCCH,CCCH,CCCH,CCCH,CCCH,CCCH,CCCH,CCCH,CCCH,CCCH]))
@@ -166,7 +187,7 @@
         )
         self.gsm_control_channels_decoder_0 = grgsm.control_channels_decoder()
         self.gsm_clock_offset_control_0 = grgsm.clock_offset_control(fc)
-        self.blocks_socket_pdu_0 = blocks.socket_pdu("UDP_CLIENT", "127.0.0.1", "4729", 10000)
+        self.blocks_socket_pdu_0 = blocks.socket_pdu("UDP_CLIENT", "127.0.0.1", "4729", 10000, False)
 
         ##################################################
         # Connections
@@ -176,7 +197,7 @@
         self.connect((self.rtlsdr_source_0, 0), (self.qtgui_freq_sink_x_0, 0))
 
         ##################################################
-        # Message Connections
+        # Asynch Message Connections
         ##################################################
         self.msg_connect(self.gsm_receiver_0, "C0", self.gsm_universal_ctrl_chans_demapper_0, "bursts")
         self.msg_connect(self.gsm_clock_offset_control_0, "ppm", self.gsm_input_0, "ppm_in")
diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt
index 0baaac8..caf2660 100644
--- a/grc/CMakeLists.txt
+++ b/grc/CMakeLists.txt
@@ -22,7 +22,7 @@
 add_subdirectory(demapping)
 add_subdirectory(receiver)
 add_subdirectory(misc_utils)
-
 install(FILES
-    gsm_block_tree.xml DESTINATION share/gnuradio/grc/blocks
+    gsm_block_tree.xml
+    DESTINATION share/gnuradio/grc/blocks
 )
diff --git a/include/grgsm/CMakeLists.txt b/include/grgsm/CMakeLists.txt
index 6df01d7..fd44c54 100644
--- a/include/grgsm/CMakeLists.txt
+++ b/include/grgsm/CMakeLists.txt
@@ -20,14 +20,16 @@
 ########################################################################
 # Install public header files
 ########################################################################
+install(FILES
+    plotting.hpp
+    api.h
+    gsmtap.h
+    DESTINATION include/grgsm
+)
+
 add_subdirectory(decoding)
 add_subdirectory(decryption)
 add_subdirectory(demapping)
 add_subdirectory(receiver)
 add_subdirectory(misc_utils)
 
-install(FILES
-    plotting.hpp
-    api.h
-    gsmtap.h DESTINATION include/grgsm
-)
diff --git a/include/grgsm/endian.h b/include/grgsm/endian.h
index c176a49..231503d 100644
--- a/include/grgsm/endian.h
+++ b/include/grgsm/endian.h
@@ -9,6 +9,7 @@
 #  define htobe16(x) OSSwapHostToBigInt16(x)
 #  define htobe32(x) OSSwapHostToBigInt32(x)
 
+#  define be16toh(x) OSSwapBigToHostInt16(x)
 #  define be32toh(x) OSSwapBigToHostInt32(x)
 #endif
 
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 8bb97df..12bc893 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -24,7 +24,7 @@
 
 include_directories(${Boost_INCLUDE_DIR} receiver)
 link_directories(${Boost_LIBRARY_DIRS})
-list(APPEND gsm_sources
+list(APPEND grgsm_sources
     receiver/receiver_impl.cc
     receiver/receiver_config.cc 
     receiver/viterbi_detector.cc 
@@ -42,9 +42,9 @@
     misc_utils/message_printer_impl.cc
     misc_utils/tmsi_dumper_impl.cc
     decryption/decryption_impl.cc
-)
+    )
 
-add_library(gnuradio-gsm SHARED ${gsm_sources})
+add_library(gnuradio-gsm SHARED ${grgsm_sources})
 target_link_libraries(gnuradio-gsm ${Boost_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES} ${VOLK_LIBRARIES}
 # libraries required by plotting.h - have troubles to be installed by pybombs
 #    boost_iostreams
@@ -69,13 +69,13 @@
 
 #include_directories(${CPPUNIT_INCLUDE_DIRS})
 
-#list(APPEND test_gsm_sources
+#list(APPEND test_grgsm_sources
 #    ${CMAKE_CURRENT_SOURCE_DIR}/test_gsm.cc
 #    ${CMAKE_CURRENT_SOURCE_DIR}/qa_gsm.cc
 #    ${CMAKE_CURRENT_SOURCE_DIR}/qa_receiver.cc
 #)
 
-#add_executable(test-gsm ${test_gsm_sources})
+#add_executable(test-gsm ${test_grgsm_sources})
 
 #target_link_libraries(
 #  test-gsm
diff --git a/lib/decryption/decryption_impl.cc b/lib/decryption/decryption_impl.cc
index ecf97ce..de02353 100644
--- a/lib/decryption/decryption_impl.cc
+++ b/lib/decryption/decryption_impl.cc
@@ -1,17 +1,17 @@
 /* -*- 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,
@@ -23,12 +23,11 @@
 #endif
 
 #include <gnuradio/io_signature.h>
-#include <grgsm/endian.h>
 #include <grgsm/gsmtap.h>
+#include <grgsm/endian.h>
 #include "decryption_impl.h"
 #include "a5_1_2.h"
-#include "stdio.h"//!!
-#include <algorithm>//!!
+
 
 const uint32_t BURST_SIZE=148;
 
@@ -64,17 +63,17 @@
     decryption_impl::~decryption_impl()
     {
     }
-    
+
     void decryption_impl::set_k_c(const std::vector<uint8_t> & k_c)
     {
         d_k_c = k_c;
     }
-    
+
     void decryption_impl::decrypt(pmt::pmt_t msg)
     {
         if(d_k_c.size() != 8){
             message_port_pub(pmt::mp("bursts"), msg);
-        } else 
+        } else
         if(d_k_c[0] == 0 && d_k_c[1] == 0 && d_k_c[2] == 0 && d_k_c[3] == 0 &
            d_k_c[4] == 0 && d_k_c[5] == 0 && d_k_c[6] == 0 && d_k_c[7] == 0)
         {
@@ -85,11 +84,11 @@
             uint8_t AtoBkeystream[114];
             uint8_t BtoAkeystream[114];
             uint8_t * keystream;
-            
+
             pmt::pmt_t header_plus_burst = pmt::cdr(msg);
             gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(header_plus_burst);
             uint8_t * burst_binary = (uint8_t *)(pmt::blob_data(header_plus_burst))+sizeof(gsmtap_hdr);
-            
+
             uint32_t frame_number = be32toh(header->frame_number);
             bool uplink_burst = (be16toh(header->arfcn) & 0x4000) ? true : false;
             uint32_t t1 = frame_number / (26*51);
@@ -98,7 +97,7 @@
             uint32_t frame_number_mod = (t1 << 11) + (t3 << 5) + t2;
             keysetup(&d_k_c[0], frame_number_mod);
             runA51(AtoBkeystream, BtoAkeystream);
-            
+
             if(uplink_burst){
                 //process uplink burst
                 keystream = BtoAkeystream;
@@ -129,14 +128,13 @@
             uint8_t new_header_plus_burst[sizeof(gsmtap_hdr)+BURST_SIZE];
             memcpy(new_header_plus_burst, header, sizeof(gsmtap_hdr));
             memcpy(new_header_plus_burst+sizeof(gsmtap_hdr), decrypted_data, BURST_SIZE);
-            
+
             pmt::pmt_t msg_binary_blob = pmt::make_blob(new_header_plus_burst, sizeof(gsmtap_hdr)+BURST_SIZE);
             pmt::pmt_t msg_out = pmt::cons(pmt::PMT_NIL, msg_binary_blob);
-            
+
             message_port_pub(pmt::mp("bursts"), msg_out);
         }
         return;
     }
   } /* namespace gsm */
 } /* namespace gr */
-
diff --git a/lib/demapping/tch_f_chans_demapper_impl.cc b/lib/demapping/tch_f_chans_demapper_impl.cc
index a2458f1..719429e 100644
--- a/lib/demapping/tch_f_chans_demapper_impl.cc
+++ b/lib/demapping/tch_f_chans_demapper_impl.cc
@@ -49,16 +49,12 @@
               gr::io_signature::make(0, 0, 0)),
        d_timeslot(timeslot_nr)
               
-    {
-        for(int ii=0; ii<13; ii++)
+    {                
+        for (int ii=0; ii<3; ii++) 
         {
-            int startpos = ((int)(ii / 4) * 4);
-            d_starts_fn_mod26[ii] = startpos;
-            d_starts_fn_mod26[ii + 13] = startpos + 13;
+            d_bursts_stolen[ii] = false;
         }
         
-        d_bursts_stolen = false;
-
         message_port_register_in(pmt::mp("bursts"));
         set_msg_handler(pmt::mp("bursts"), boost::bind(&tch_f_chans_demapper_impl::filter_tch_chans, this, _1));
         message_port_register_out(pmt::mp("tch_bursts"));
@@ -79,14 +75,14 @@
 
         uint32_t frame_nr = be32toh(header->frame_number);
         uint32_t fn_mod26 = frame_nr % 26;
-        uint32_t fn26_start = d_starts_fn_mod26[fn_mod26];
-        uint32_t fn26_stop = fn26_start + 3;
+        uint32_t fn_mod13 = frame_nr % 13;
+        bool frames_are_consecutive = true;
         int8_t * burst_bits = (int8_t *)(pmt::blob_data(header_plus_burst))+sizeof(gsmtap_hdr);
 
         if(header->timeslot == d_timeslot){
             header->sub_type = GSMTAP_CHANNEL_TCH_F;
             
-            if (fn_mod26 == 12 || fn_mod26 == 25)
+            if (fn_mod13 == 12)
             {
                 header->sub_type = GSMTAP_CHANNEL_ACCH|GSMTAP_CHANNEL_TCH_F;
                 
@@ -115,7 +111,7 @@
                     {
                         //check for a situation where some bursts were lost
                         //in this situation frame numbers won't be consecutive
-                        bool frames_are_consecutive = true;
+                        frames_are_consecutive = true;
                         for(int jj=1; jj<4; jj++)
                         {
                             if((d_frame_numbers_sacch[jj]-d_frame_numbers_sacch[jj-1]) != 26)
@@ -136,49 +132,118 @@
             }
             else
             {
-                if(fn_mod26>=fn26_start && fn_mod26<=fn26_stop)
+                if (fn_mod13 <= 3) 
                 {
-                    uint32_t ii = fn_mod26 - fn26_start;
-                    d_frame_numbers[ii] = frame_nr;
-                    d_bursts[ii] = msg;
+                    // add to b1 and b3
+                    d_bursts[0][fn_mod13] = msg;
+                    d_bursts[2][fn_mod13 + 4] = msg;
+                    
+                    // set framenumber
+                    d_frame_numbers[0][fn_mod13] = frame_nr;
+                    d_frame_numbers[2][fn_mod13 + 4] = frame_nr;
                     
                     // check if stealing bits are set
-                    // see gsm 05.03 
-                    if (static_cast<int>(burst_bits[60]) == 1 && static_cast<int>(burst_bits[87]) == 1)
+                    // see 4.2.5 in gsm 05.03 
+                    if (static_cast<int>(burst_bits[60]) == 1)
                     {
-                        d_bursts_stolen = true;
+                        d_bursts_stolen[2] = true;
+                    }
+                    if (static_cast<int>(burst_bits[87]) == 1)
+                    {
+                        d_bursts_stolen[0] = true;
                     }
                 }
-                
-                if(fn_mod26==fn26_stop)
+                else if (fn_mod13 >= 4 && fn_mod13 <= 7)
                 {
+                    // add to b1 and b2
+                    d_bursts[0][fn_mod13] = msg;
+                    d_bursts[1][fn_mod13 - 4] = msg;
+                    
+                    // set framenumber
+                    d_frame_numbers[0][fn_mod13] = frame_nr;
+                    d_frame_numbers[1][fn_mod13 - 4] = frame_nr;
+                    
+                    // check if stealing bits are set
+                    // see 4.2.5 in gsm 05.03 
+                    if (static_cast<int>(burst_bits[60]) == 1)
+                    {
+                        d_bursts_stolen[0] = true;
+                    }
+                    if (static_cast<int>(burst_bits[87]) == 1)
+                    {
+                        d_bursts_stolen[1] = true;
+                    }
+                }
+                else if (fn_mod13 >= 8 && fn_mod13 <= 11)
+                {
+                    // add to b2 and b3
+                    d_bursts[1][fn_mod13 - 4] = msg;
+                    d_bursts[2][fn_mod13 - 8] = msg;
+                    
+                    // set framenumber
+                    d_frame_numbers[1][fn_mod13 - 4] = frame_nr;
+                    d_frame_numbers[2][fn_mod13 - 8] = frame_nr;
+                    
+                    // check if stealing bits are set
+                    // see 4.2.5 in gsm 05.03 
+                    if (static_cast<int>(burst_bits[60]) == 1)
+                    {
+                        d_bursts_stolen[1] = true;
+                    }
+                    if (static_cast<int>(burst_bits[87]) == 1)
+                    {
+                        d_bursts_stolen[2] = true;
+                    }
+                }
+
+                // send burst 1 or burst 2 to output
+                if (fn_mod13 == 3 || fn_mod13 == 7 || fn_mod13 == 11)
+                {
+                    int tch_burst_nr = 0;
+                    
+                    if (fn_mod13 == 11) 
+                    {
+                        tch_burst_nr = 1;
+                    }
+                    else if (fn_mod13 == 3)
+                    {
+                        tch_burst_nr = 2;
+                    }
+
                     //check for a situation where some bursts were lost
                     //in this situation frame numbers won't be consecutive
-                    bool frames_are_consecutive = true;
+                    frames_are_consecutive = true;
                     
-                    for(int jj=1; jj<4; jj++)
+                    for(int jj=1; jj<8; jj++)
                     {
-                        if((d_frame_numbers[jj]-d_frame_numbers[jj-1])!=1)
+                        if((d_frame_numbers[tch_burst_nr][jj] - d_frame_numbers[tch_burst_nr][jj-1]) != 1)
                         {
                             frames_are_consecutive = false;
+                            // burst 3 has 1 sacch burst in between
+                            if (tch_burst_nr == 2 && jj == 4 
+                                && d_frame_numbers[tch_burst_nr][jj] - d_frame_numbers[tch_burst_nr][jj - 1] == 2) 
+                            {
+                                frames_are_consecutive = true;
+                            }
                         }
                     }
+                    
                     if(frames_are_consecutive)
                     {
                         //send bursts to the output
-                        for(int jj=0; jj<4; jj++)
+                        for(int jj=0; jj<8; jj++)
                         {
-                            if (d_bursts_stolen)
+                            if (d_bursts_stolen[tch_burst_nr])
                             {
-                                message_port_pub(pmt::mp("acch_bursts"), d_bursts[jj]);
+                                message_port_pub(pmt::mp("acch_bursts"), d_bursts[tch_burst_nr][jj]);
                             }
                             else
                             {
-                                message_port_pub(pmt::mp("tch_bursts"), d_bursts[jj]);
+                                message_port_pub(pmt::mp("tch_bursts"), d_bursts[tch_burst_nr][jj]);
                             }
                         }
-                        d_bursts_stolen = false;
-                    } 
+                        d_bursts_stolen[tch_burst_nr] = false;
+                    }
                 }
             }
         }
diff --git a/lib/demapping/tch_f_chans_demapper_impl.h b/lib/demapping/tch_f_chans_demapper_impl.h
index 8abbc91..b989564 100644
--- a/lib/demapping/tch_f_chans_demapper_impl.h
+++ b/lib/demapping/tch_f_chans_demapper_impl.h
@@ -31,13 +31,13 @@
     class tch_f_chans_demapper_impl : public tch_f_chans_demapper
     {
      private:
-      unsigned int d_starts_fn_mod26[26];
       unsigned int d_timeslot;
-      uint32_t d_frame_numbers[4];
+      uint32_t d_frame_numbers[3][8];
       uint32_t d_frame_numbers_sacch[4];
-      pmt::pmt_t d_bursts[4];
-      bool d_bursts_stolen;
+      pmt::pmt_t d_bursts[3][8];
       pmt::pmt_t d_bursts_sacch[4];
+      bool d_bursts_stolen[3];
+
      public:
       tch_f_chans_demapper_impl(unsigned int timeslot_nr);
       ~tch_f_chans_demapper_impl();
diff --git a/lib/misc_utils/bursts_printer_impl.cc b/lib/misc_utils/bursts_printer_impl.cc
index 8be1422..a22e85f 100644
--- a/lib/misc_utils/bursts_printer_impl.cc
+++ b/lib/misc_utils/bursts_printer_impl.cc
@@ -26,6 +26,7 @@
 
 #include <gnuradio/io_signature.h>
 #include <grgsm/gsmtap.h>
+#include <grgsm/endian.h>
 #include <iterator>
 #include <algorithm>
 #include "bursts_printer_impl.h"
@@ -44,13 +45,13 @@
         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);
         uint32_t frame_nr;
-        
+
         std::cout << d_prepend_string;
-        if (d_prepend_fnr) 
+        if (d_prepend_fnr)
         {
             frame_nr = be32toh(header->frame_number);
             std::cout << frame_nr << ":";
-        } 
+        }
 
         for(int ii=0; ii<burst_len; ii++)
         {
@@ -58,7 +59,7 @@
         }
         std::cout << std::endl;
     }
-     
+
     bursts_printer::sptr
     bursts_printer::make(pmt::pmt_t prepend_string, bool prepend_fnr)
     {
@@ -79,7 +80,7 @@
         message_port_register_in(pmt::mp("bursts"));
         set_msg_handler(pmt::mp("bursts"), boost::bind(&bursts_printer_impl::bursts_print, this, _1));
     }
-    
+
     /*
      * Our virtual destructor.
      */
@@ -90,4 +91,3 @@
 
   } /* namespace gsm */
 } /* namespace gr */
-