Merge branch '213-3digit-mnc' of https://github.com/romankh/gr-gsm into libosmocore_integration
diff --git a/.gitignore b/.gitignore
index 99dd781..4a4e29c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,4 +7,5 @@
 .unittests
 build/
 debian/tmp/
-debian/files
\ No newline at end of file
+debian/files
+.directory
diff --git a/apps/grgsm_decode b/apps/grgsm_decode
index 94a2ba0..18536c3 100755
--- a/apps/grgsm_decode
+++ b/apps/grgsm_decode
@@ -39,6 +39,7 @@
                  cfile=None, fc=None, samp_rate=2e6, 
                  a5=1, a5_kc=None,
                  speech_file=None, speech_codec=None,
+                 enable_voice_boundary_detection=False,
                  verbose=False,
                  print_bursts=False, ppm=0):
 
@@ -62,6 +63,7 @@
         self.speech_codec = speech_codec
         self.verbose = verbose
         self.print_bursts = print_bursts
+        self.enable_voice_boundary_detection = enable_voice_boundary_detection
 
         ##################################################
         # Blocks
@@ -95,7 +97,7 @@
             self.sdcch8_demapper = grgsm.gsm_sdcch8_demapper(self.timeslot)
         elif self.chan_mode == 'TCHF':
             self.tch_f_demapper = grgsm.tch_f_chans_demapper(self.timeslot)
-            self.tch_f_decoder = grgsm.tch_f_decoder(speech_codec)
+            self.tch_f_decoder = grgsm.tch_f_decoder(speech_codec, enable_voice_boundary_detection)
             self.tch_f_pdu_to_tagged_stream = blocks.pdu_to_tagged_stream(blocks.byte_t, "packet_len")
             self.tch_f_file_sink = blocks.file_sink(gr.sizeof_char*1, speech_file, False)
 
@@ -317,6 +319,8 @@
                                 "Valid options are " + ", ".join(tch_codecs.keys()))
     tch_options.add_option("-o", "--output-tch", dest="speech_output_file", default="/tmp/speech.au.gsm",
                            help="TCH/F speech output file [default=%default].")
+    tch_options.add_option("--voice-boundary", dest="enable_voice_boundary_detection", action="store_true",
+                           help="Enable voice boundary detection for traffic channels. This can help reduce noice in the output.")
     parser.add_option_group(tch_options)
 
     # parse
@@ -378,6 +382,7 @@
                           cfile=options.cfile, fc=fc, samp_rate=options.samp_rate,
                           a5=options.a5, a5_kc=kc,
                           speech_file=options.speech_output_file, speech_codec=tch_codecs.get(options.speech_codec),
+                          enable_voice_boundary_detection=options.enable_voice_boundary_detection,
                           verbose=options.verbose,
                           print_bursts=options.print_bursts, ppm=options.ppm)
 
diff --git a/apps/grgsm_scanner b/apps/grgsm_scanner
index acd48d9..1688310 100755
--- a/apps/grgsm_scanner
+++ b/apps/grgsm_scanner
@@ -220,7 +220,7 @@
         # correction of central frequency
         # if the receiver has large frequency offset
         # the value of this variable should be set close to that offset in ppm
-        self.rtlsdr_source.set_freq_corr(options.ppm, 0)
+        self.rtlsdr_source.set_freq_corr(ppm, 0)
 
         self.rtlsdr_source.set_dc_offset_mode(2, 0)
         self.rtlsdr_source.set_iq_balance_mode(0, 0)
@@ -230,7 +230,7 @@
         self.head = blocks.head(gr.sizeof_gr_complex * 1, int(rec_len * sample_rate))
 
         # shift again by -0.1MHz in order to align channel center in 0Hz
-        self.blocks_rotator_cc = blocks.rotator_cc(-2 * pi * 0.1e6 / options.samp_rate)
+        self.blocks_rotator_cc = blocks.rotator_cc(-2 * pi * 0.1e6 / sample_rate)
 
         self.wideband_receiver = wideband_receiver(OSR=4, fc=carrier_frequency, samp_rate=sample_rate)
         self.gsm_extract_system_info = grgsm.extract_system_info()
diff --git a/apps/helpers/grgsm_capture.py b/apps/helpers/grgsm_capture.py
index caea805..a71c2c8 100755
--- a/apps/helpers/grgsm_capture.py
+++ b/apps/helpers/grgsm_capture.py
@@ -86,7 +86,7 @@
                 fc=fc,
                 samp_rate_in=samp_rate,
             )
-            self.gsm_clock_offset_control = grgsm.clock_offset_control(fc-shiftoff, sample_rate, osr=4)
+            self.gsm_clock_offset_control = grgsm.clock_offset_control(fc-shiftoff, samp_rate, osr=4)
 
         if self.burst_file:
             self.gsm_burst_file_sink = grgsm.burst_file_sink(self.burst_file)
@@ -115,7 +115,7 @@
         if self.verbose or self.burst_file:
             self.connect((self.gsm_input, 0), (self.gsm_receiver, 0))
             self.connect((self.blocks_rotator, 0), (self.gsm_input, 0))
-            self.msg_connect(self.gsm_clock_offset_control, "ppm", self.gsm_input, "ppm_in")
+            self.msg_connect(self.gsm_clock_offset_control, "ctrl", self.gsm_input, "ctrl_in")
             self.msg_connect(self.gsm_receiver, "measurements", self.gsm_clock_offset_control, "measurements")
 
             if self.burst_file:
diff --git a/lib/demapping/tch_f_chans_demapper_impl.cc b/lib/demapping/tch_f_chans_demapper_impl.cc
index a672b24..53f46fb 100644
--- a/lib/demapping/tch_f_chans_demapper_impl.cc
+++ b/lib/demapping/tch_f_chans_demapper_impl.cc
@@ -87,7 +87,7 @@
 
             new_hdr->sub_type = GSMTAP_CHANNEL_TCH_F;
             if (fn_mod13 == 12)
-                header->sub_type = GSMTAP_CHANNEL_ACCH|GSMTAP_CHANNEL_TCH_F;
+                new_hdr->sub_type = GSMTAP_CHANNEL_ACCH|GSMTAP_CHANNEL_TCH_F;
 
             pmt::pmt_t msg_binary_blob = pmt::make_blob(new_msg,sizeof(gsmtap_hdr)+BURST_SIZE);
             pmt::pmt_t msg_out = pmt::cons(pmt::PMT_NIL, msg_binary_blob);
diff --git a/lib/flow_control/uplink_downlink_splitter_impl.cc b/lib/flow_control/uplink_downlink_splitter_impl.cc
index b98102c..e98c668 100644
--- a/lib/flow_control/uplink_downlink_splitter_impl.cc
+++ b/lib/flow_control/uplink_downlink_splitter_impl.cc
@@ -27,6 +27,7 @@
 #include <gnuradio/io_signature.h>
 #include "uplink_downlink_splitter_impl.h"
 #include <grgsm/gsmtap.h>
+#include <grgsm/endian.h>
 #define BURST_SIZE 148
 namespace gr {
   namespace grgsm {
diff --git a/lib/misc_utils/extract_system_info_impl.cc b/lib/misc_utils/extract_system_info_impl.cc
index bb7fada..6f745a0 100644
--- a/lib/misc_utils/extract_system_info_impl.cc
+++ b/lib/misc_utils/extract_system_info_impl.cc
@@ -76,6 +76,12 @@
             info.lac = (msg_elements[8]<<8)+msg_elements[9];             //take lac
             info.mcc =  ((msg_elements[5] & 0xF)  * 100) + (((msg_elements[5] & 0xF0) >> 4) * 10) + ((msg_elements[6] & 0xF)); // take mcc
             info.mnc = (msg_elements[7] & 0xF) * 10 + (msg_elements[7]>>4); //take mnc
+            if (((msg_elements[6] & 0xF0) >> 4) < 10) // we have a 3 digit mnc, see figure 10.5.3 of 3GPP TS 24.008
+            {
+                info.mnc *= 10;
+                info.mnc += (msg_elements[6] & 0xF0) >> 4;
+            }
+
             info.ccch_conf = (msg_elements[10] & 0x7); // ccch_conf
             
             boost::mutex::scoped_lock lock(extract_mutex);
@@ -92,6 +98,11 @@
             info.lac = (msg_elements[6]<<8)+msg_elements[7];            //take lac
             info.mcc =  ((msg_elements[3] & 0xF) * 100) + (((msg_elements[3] & 0xF0) >> 4) * 10) + ((msg_elements[4] & 0xF)); // take mcc
             info.mnc = (msg_elements[5] & 0xF) * 10 + (msg_elements[5]>>4); //take mnc
+            if (((msg_elements[4] & 0xF0) >> 4) < 10) // we have a 3 digit mnc, see figure 10.5.3 of 3GPP TS 24.008
+            {
+                info.mnc *= 10;
+                info.mnc += (msg_elements[4] & 0xF0) >> 4;
+            }
             
             boost::mutex::scoped_lock lock(extract_mutex);
             if(d_c0_channels.find(info.id) != d_c0_channels.end()){