Merge branch 'master' of github.com:Jakotako/gr-gsm
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9e3b274..0ce77ab 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -140,6 +140,7 @@
 # Add subdirectories
 ########################################################################
 add_subdirectory(include/gsm)
+add_subdirectory(include/plotting)
 add_subdirectory(lib)
 add_subdirectory(swig)
 add_subdirectory(python)
diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt
index f2f4b75..5c0ee65 100644
--- a/grc/CMakeLists.txt
+++ b/grc/CMakeLists.txt
@@ -19,5 +19,6 @@
 
 install(FILES
     gsm_receiver_hier.xml
+    gsm_get_ccch_bursts.xml
     gsm_bursts_printer.xml DESTINATION share/gnuradio/grc/blocks
 )
diff --git a/grc/gsm_get_ccch_bursts.xml b/grc/gsm_get_ccch_bursts.xml
new file mode 100644
index 0000000..4c917b2
--- /dev/null
+++ b/grc/gsm_get_ccch_bursts.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<block>
+  <name>get_ccch_bursts</name>
+  <key>gsm_get_ccch_bursts</key>
+  <category>gsm</category>
+  <import>import gsm</import>
+  <make>gsm.get_ccch_bursts()</make>
+  <sink>
+    <name>bursts_in</name>
+    <type>message</type>
+  </sink>
+  <source>
+    <name>bursts_out</name>
+    <type>message</type>
+  </source>
+</block>
diff --git a/include/gsm/CMakeLists.txt b/include/gsm/CMakeLists.txt
index c7f4fb3..746f718 100644
--- a/include/gsm/CMakeLists.txt
+++ b/include/gsm/CMakeLists.txt
@@ -23,5 +23,6 @@
 install(FILES
     api.h
     receiver.h
+    get_ccch_bursts.h
     bursts_printer.h DESTINATION include/gsm
 )
diff --git a/include/gsm/get_ccch_bursts.h b/include/gsm/get_ccch_bursts.h
new file mode 100644
index 0000000..e0bbb1d
--- /dev/null
+++ b/include/gsm/get_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_CCCH_BURSTS_H
+#define INCLUDED_GSM_GET_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_ccch_bursts : virtual public gr::block
+    {
+     public:
+      typedef boost::shared_ptr<get_ccch_bursts> sptr;
+
+      /*!
+       * \brief Return a shared_ptr to a new instance of gsm::get_ccch_bursts.
+       *
+       * To avoid accidental use of raw pointers, gsm::get_ccch_bursts's
+       * constructor is in a private implementation
+       * class. gsm::get_ccch_bursts::make is the public interface for
+       * creating new instances.
+       */
+      static sptr make();
+    };
+
+  } // namespace gsm
+} // namespace gr
+
+#endif /* INCLUDED_GSM_GET_CCCH_BURSTS_H */
+
diff --git a/include/plotting/CMakeLists.txt b/include/plotting/CMakeLists.txt
new file mode 100644
index 0000000..569c462
--- /dev/null
+++ b/include/plotting/CMakeLists.txt
@@ -0,0 +1,25 @@
+# Copyright 2011,2012 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 3, 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., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+########################################################################
+# Install public header files
+########################################################################
+install(FILES
+    plotting.hpp DESTINATION include/plotting
+)
diff --git a/include/plotting/plotting.hpp b/include/plotting/plotting.hpp
new file mode 100644
index 0000000..9f8fcd3
--- /dev/null
+++ b/include/plotting/plotting.hpp
@@ -0,0 +1,79 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Piotr Krysik <pkrysik@elka.pw.edu.pl>.
+ *
+ * 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.
+ */
+
+#define USE_CXX (__cplusplus >= 201103)
+
+#include <vector>
+#include <armadillo>
+#include <string>
+#include <boost/make_shared.hpp>
+
+#include "gnuplot-iostream.h"
+
+boost::shared_ptr<Gnuplot> current_figure;
+
+void imagesc(arma::mat & x){
+    Gnuplot gp;
+	gp << "set palette rgb 3,2,2;";
+   gp << "plot ";
+ 	gp << gp.file1d(x) << "matrix with image";
+	gp << std::endl;
+}
+
+void plot(arma::cx_mat & x, std::string title){
+   arma::mat y = arma::abs(x);
+   if(current_figure.get()==NULL){
+      current_figure = boost::make_shared<Gnuplot>();
+   }
+   (*current_figure) << "plot ";
+   
+   (*current_figure) << current_figure->file1d(y) <<"title \'"  << titl
+   e << "\' with lines ";
+   (*current_figure) << std::endl; 
+}
+
+void replot(arma::cx_mat & x, std::string title){
+   arma::mat y = arma::abs(x);
+   if(current_figure.get()==NULL){
+      current_figure = boost::make_shared<Gnuplot>();
+   }
+   (*current_figure) << "replot ";
+   (*current_figure) << current_figure->file1d(y) <<"title \'"  << title << "\' with lines ";
+   (*current_figure) << std::endl; 
+}
+
+template<typename T>
+void plot(std::vector<T> & x){
+   arma::cx_mat y = arma::conv_to<arma::cx_mat>::from(x);
+   plot(y,"");
+}
+
+template<typename T>
+void plot(std::vector<T> & x, std::string title){
+   arma::cx_mat y = arma::conv_to<arma::cx_mat>::from(x);
+   plot(y,title);
+}
+
+template<typename T>
+void replot(std::vector<T> & x, std::string title){
+   arma::cx_mat y = arma::conv_to<arma::cx_mat>::from(x);
+   replot(y,title);
+}
+
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 1139353..38539da 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -31,10 +31,15 @@
     viterbi_detector.cc 
     sch.c
     bursts_printer_impl.cc
+    get_ccch_bursts_impl.cc
 )
 
 add_library(gnuradio-gsm SHARED ${gsm_sources})
-target_link_libraries(gnuradio-gsm ${Boost_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES})
+target_link_libraries(gnuradio-gsm ${Boost_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES}  
+    boost_iostreams
+    boost_system
+    boost_filesystem
+)
 set_target_properties(gnuradio-gsm PROPERTIES DEFINE_SYMBOL "gnuradio_gsm_EXPORTS")
 
 ########################################################################
diff --git a/lib/get_ccch_bursts_impl.cc b/lib/get_ccch_bursts_impl.cc
new file mode 100644
index 0000000..249c271
--- /dev/null
+++ b/lib/get_ccch_bursts_impl.cc
@@ -0,0 +1,101 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2014 <perper@o2.pl>.
+ * 
+ * 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 "get_ccch_bursts_impl.h"
+#include <gsmtap.h>
+
+namespace gr {
+  namespace gsm {
+
+    void get_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;
+        pmt::pmt_t msgs[4];
+        uint32_t frame_numbers[4];
+        
+        if(header->timeslot==0){
+            std::cout << (header->frame_number % 51) << std::endl;
+            if((header->frame_number % 51)>=2 & (header->frame_number % 51)<=5){
+                uint32_t ii = header->frame_number-2;
+                frame_numbers[ii]=header->frame_number;
+                msgs[ii] = msg;
+//                std::cout << "Hura, pierwszy if" << std::endl;
+            }
+            
+            if((header->frame_number % 51)==5){
+                //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((frame_numbers[jj]-frame_numbers[jj-1])!=1){
+                        frames_are_consecutive = false;
+                    }
+                }
+                std::cout << "Hura, durgi if" << std::endl;                
+                if(frames_are_consecutive){
+                    //send bursts to the output
+                    std::cout << "Hura, trzeci if" << std::endl;                
+
+                    for(int jj=1;jj<4;jj++){
+//                        message_port_pub(pmt::mp("bursts_out"), msgs[jj]);
+                    }                 
+                }
+            }
+        }
+    }
+
+    get_ccch_bursts::sptr
+    get_ccch_bursts::make()
+    {
+      return gnuradio::get_initial_sptr
+        (new get_ccch_bursts_impl());
+    }
+
+    /*
+     * The private constructor
+     */
+    get_ccch_bursts_impl::get_ccch_bursts_impl()
+      : gr::block("get_ccch_bursts",
+              gr::io_signature::make(0, 0, 0),
+              gr::io_signature::make(0, 0, 0))
+    {
+        message_port_register_in(pmt::mp("bursts_in"));
+        set_msg_handler(pmt::mp("bursts_in"), boost::bind(&get_ccch_bursts_impl::filter_ccch, this, _1));
+        message_port_register_out(pmt::mp("bursts_out"));
+    }
+
+    /*
+     * Our virtual destructor.
+     */
+    get_ccch_bursts_impl::~get_ccch_bursts_impl()
+    {
+    }
+    
+  } /* namespace gsm */
+} /* namespace gr */
+
diff --git a/lib/get_ccch_bursts_impl.h b/lib/get_ccch_bursts_impl.h
new file mode 100644
index 0000000..992b181
--- /dev/null
+++ b/lib/get_ccch_bursts_impl.h
@@ -0,0 +1,42 @@
+/* -*- 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_CCCH_BURSTS_IMPL_H
+#define INCLUDED_GSM_GET_CCCH_BURSTS_IMPL_H
+
+#include <gsm/get_ccch_bursts.h>
+#include <receiver_config.h>
+
+namespace gr {
+  namespace gsm {
+
+    class get_ccch_bursts_impl : public get_ccch_bursts
+    {                
+     public:
+        get_ccch_bursts_impl();
+        ~get_ccch_bursts_impl();
+        void filter_ccch(pmt::pmt_t msg);
+    };
+
+  } // namespace gsm
+} // namespace gr
+
+#endif /* INCLUDED_GSM_GET_CCCH_BURSTS_IMPL_H */
+
diff --git a/lib/receiver_impl.cc b/lib/receiver_impl.cc
index 09461c6..d56d1f3 100644
--- a/lib/receiver_impl.cc
+++ b/lib/receiver_impl.cc
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2014 <+YOU OR YOUR COMPANY+>.
+ * Copyright 2014 Piotr Krysik <pkrysik@elka.pw.edu.pl>.
  *
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -95,6 +95,7 @@
         gmsk_mapper(train_seq[i], N_TRAIN_BITS, d_norm_training_seq[i], startpoint);
     }
     message_port_register_out(pmt::mp("bursts"));
+    configure_receiver();  //configure the receiver - tell it where to find which burst type
 }
 
 /*
@@ -173,13 +174,6 @@
                 DCOUT("sch burst_start: " << burst_start);
                 DCOUT("bcc: " << d_bcc << " ncc: " << d_ncc << " t1: " << t1 << " t2: " << t2 << " t3: " << t3);
                 d_burst_nr.set(t1, t2, t3, 0);                                  //set counter of bursts value
-
-                //configure the receiver - tell him where to find which burst type
-                d_channel_conf.set_multiframe_type(TIMESLOT0, multiframe_51);  //in the timeslot nr.0 bursts changes according to t3 counter
-                configure_receiver();//TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready
-                d_channel_conf.set_burst_types(TIMESLOT0, FCCH_FRAMES, sizeof(FCCH_FRAMES) / sizeof(unsigned), fcch_burst);  //tell where to find fcch bursts
-                d_channel_conf.set_burst_types(TIMESLOT0, SCH_FRAMES, sizeof(SCH_FRAMES) / sizeof(unsigned), sch_burst);     //sch bursts
-                d_channel_conf.set_burst_types(TIMESLOT0, BCCH_FRAMES, sizeof(BCCH_FRAMES) / sizeof(unsigned), normal_burst);//!and maybe normal bursts of the BCCH logical channel
                 d_burst_nr++;
 
                 consume_each(burst_start + BURST_SIZE * d_OSR);   //consume samples up to next guard period
@@ -260,7 +254,6 @@
                 d_failed_sch++;
                 if (d_failed_sch >= MAX_SCH_ERRORS)
                 {
-                    d_state = next_fcch_search;        //TODO: this isn't good, the receiver is going wild when it goes back to next_fcch_search from here
                     d_freq_offset_vals.clear();
                     d_freq_offset=0;
                     //set_frequency(0);
@@ -275,7 +268,7 @@
             float normal_corr_max;                                                    //if it's normal burst
             burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], &normal_corr_max, d_bcc); //get channel impulse response for given training sequence number - d_bcc
             detect_burst(input, &channel_imp_resp[0], burst_start, output_binary);            //MLSE detection of bits
-            send_burst(d_burst_nr, output_binary, b_type); //TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready
+            send_burst(d_burst_nr, output_binary, b_type);
             break;
         }
         case dummy_or_normal:
@@ -291,7 +284,7 @@
             if (normal_corr_max > dummy_corr_max)
             {
                 detect_burst(input, &channel_imp_resp[0], normal_burst_start, output_binary);
-                send_burst(d_burst_nr, output_binary, b_type); //TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready
+                send_burst(d_burst_nr, output_binary, b_type); 
             }
             else
             {
@@ -712,7 +705,6 @@
 }
 
 //TODO: get_norm_chan_imp_resp is similar to get_sch_chan_imp_resp - consider joining this two functions
-//TODO: this is place where most errors are introduced and can be corrected by improvements to this fuction
 //especially computations of strongest_window_nr
 int receiver_impl::get_norm_chan_imp_resp(const gr_complex *input, gr_complex * chan_imp_resp, float *corr_max, int bcc)
 {
@@ -725,11 +717,11 @@
     int chan_imp_resp_center = 0;
     float max_correlation = 0;
     float energy = 0;
-
+   
     int search_center = (int)((TRAIN_POS + GUARD_PERIOD) * d_OSR);
     int search_start_pos = search_center + 1 - 5*d_OSR;
     //   int search_start_pos = search_center -  d_chan_imp_length * d_OSR;
-    int search_stop_pos = search_center + d_chan_imp_length * d_OSR + 2 * d_OSR;
+    int search_stop_pos = search_center + d_chan_imp_length * d_OSR + 5 * d_OSR;
 
     for (int ii = search_start_pos; ii < search_stop_pos; ii++)
     {
@@ -765,8 +757,11 @@
         window_energy_buffer.push_back(energy);
     }
 
-    strongest_window_nr = max_element(window_energy_buffer.begin(), window_energy_buffer.end()) - window_energy_buffer.begin();
-    strongest_window_nr = strongest_window_nr-d_OSR; 
+    strongest_window_nr = max_element(window_energy_buffer.begin(), window_energy_buffer.end()-((d_chan_imp_length)*d_OSR)) - window_energy_buffer.begin();
+    //strongest_window_nr = strongest_window_nr-d_OSR; 
+    if(strongest_window_nr<0){
+       strongest_window_nr = 0;
+    }
     
     max_correlation = 0;
     for (int ii = 0; ii < (d_chan_imp_length)*d_OSR; ii++)
@@ -823,6 +818,7 @@
 
     d_channel_conf.set_burst_types(TSC0, TEST_CCH_FRAMES, sizeof(TEST_CCH_FRAMES) / sizeof(unsigned), dummy_or_normal);
     d_channel_conf.set_burst_types(TSC0, FCCH_FRAMES, sizeof(FCCH_FRAMES) / sizeof(unsigned), fcch_burst);
+    d_channel_conf.set_burst_types(TSC0, SCH_FRAMES, sizeof(FCCH_FRAMES) / sizeof(unsigned), fcch_burst);
 
     //  d_channel_conf.set_multiframe_type(TIMESLOT1, multiframe_26);
     //  d_channel_conf.set_burst_types(TIMESLOT1, TRAFFIC_CHANNEL_F, sizeof(TRAFFIC_CHANNEL_F) / sizeof(unsigned), dummy_or_normal);
@@ -853,7 +849,6 @@
     d_channel_conf.set_burst_types(TIMESLOT6, TEST51, sizeof(TEST51) / sizeof(unsigned), dummy_or_normal);
     d_channel_conf.set_multiframe_type(TIMESLOT7, multiframe_51);
     d_channel_conf.set_burst_types(TIMESLOT7, TEST51, sizeof(TEST51) / sizeof(unsigned), dummy_or_normal);
-
 }