Improved synchronization, added message output with bursts
diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt
index c3f7dea..f2f4b75 100644
--- a/grc/CMakeLists.txt
+++ b/grc/CMakeLists.txt
@@ -18,6 +18,6 @@
 # Boston, MA 02110-1301, USA.
 
 install(FILES
-    gsm_receiver.xml
-    gsm_receiver_hier.xml DESTINATION share/gnuradio/grc/blocks
+    gsm_receiver_hier.xml
+    gsm_bursts_printer.xml DESTINATION share/gnuradio/grc/blocks
 )
diff --git a/grc/gsm_receiver.xml b/grc/gsm_receiver.xml
deleted file mode 100644
index 7a0e3aa..0000000
--- a/grc/gsm_receiver.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0"?>
-<block>
-  <name>receiver</name>
-  <key>gsm_receiver</key>
-  <category>gsm</category>
-  <import>import gsm</import>
-  <make>gsm.receiver($tuner, $osr)</make>
-  <!-- Make one 'param' node for every Parameter you want settable from the GUI.
-       Sub-nodes:
-       * name
-       * key (makes the value accessible as $keyname, e.g. in the make node)
-       * type -->
-  <param>
-    <name>...</name>
-    <key>...</key>
-    <type>...</type>
-  </param>
-
-  <!-- Make one 'sink' node per input. Sub-nodes:
-       * name (an identifier for the GUI)
-       * type
-       * vlen
-       * optional (set to 1 for optional inputs) -->
-  <sink>
-    <name>in</name>
-    <type><!-- e.g. int, float, complex, byte, short, xxx_vector, ...--></type>
-  </sink>
-
-  <!-- Make one 'source' node per output. Sub-nodes:
-       * name (an identifier for the GUI)
-       * type
-       * vlen
-       * optional (set to 1 for optional inputs) -->
-  <source>
-    <name>out</name>
-    <type><!-- e.g. int, float, complex, byte, short, xxx_vector, ...--></type>
-  </source>
-</block>
diff --git a/grc/gsm_receiver_hier.xml b/grc/gsm_receiver_hier.xml
index 247cfcb..23eadc9 100644
--- a/grc/gsm_receiver_hier.xml
+++ b/grc/gsm_receiver_hier.xml
@@ -13,7 +13,7 @@
   </param>
 
   <param>
-    <name>Oversampling ration</name>
+    <name>Oversampling ratio</name>
     <key>osr</key>
     <value>4</value>
     <type>int</type>
@@ -23,10 +23,9 @@
     <name>in</name>
     <type>complex</type>
   </sink>
-
   <source>
-    <name>out</name>
-    <type>float</type>
-    <vlen>142</vlen>
+    <name>bursts</name>
+    <type>message</type>
+    <optional>1</optional>
   </source>
-</block>
\ No newline at end of file
+</block>
diff --git a/include/gsm/CMakeLists.txt b/include/gsm/CMakeLists.txt
index aad938f..c7f4fb3 100644
--- a/include/gsm/CMakeLists.txt
+++ b/include/gsm/CMakeLists.txt
@@ -22,5 +22,6 @@
 ########################################################################
 install(FILES
     api.h
-    receiver.h DESTINATION include/gsm
+    receiver.h
+    bursts_printer.h DESTINATION include/gsm
 )
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 8d4c721..1139353 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -30,6 +30,7 @@
     receiver_config.cc 
     viterbi_detector.cc 
     sch.c
+    bursts_printer_impl.cc
 )
 
 add_library(gnuradio-gsm SHARED ${gsm_sources})
diff --git a/lib/gsm_constants.h b/lib/gsm_constants.h
index 11913f1..964c1cf 100644
--- a/lib/gsm_constants.h
+++ b/lib/gsm_constants.h
@@ -34,7 +34,7 @@
 
 #define CHAN_IMP_RESP_LENGTH  5
 
-#define MAX_SCH_ERRORS    5  //maximum number of subsequent sch errors after which gsm receiver goes to find_next_fcch state
+#define MAX_SCH_ERRORS    10  //maximum number of subsequent sch errors after which gsm receiver goes to find_next_fcch state
 
 typedef enum {empty, fcch_burst, sch_burst, normal_burst, rach_burst, dummy, dummy_or_normal} burst_type;
 typedef enum {unknown, multiframe_26, multiframe_51} multiframe_type;
diff --git a/lib/receiver_impl.cc b/lib/receiver_impl.cc
index f11290c..90eccc2 100644
--- a/lib/receiver_impl.cc
+++ b/lib/receiver_impl.cc
@@ -64,7 +64,7 @@
 receiver_impl::receiver_impl(feval_dd * tuner, int osr)
     : gr::block("receiver",
                 gr::io_signature::make(1, 1, sizeof(gr_complex)),
-                gr::io_signature::make(0, 1, 142 * sizeof(float))),
+                gr::io_signature::make(0, 0, 0)),
     d_OSR(osr),
     d_chan_imp_length(CHAN_IMP_RESP_LENGTH),
     d_tuner(tuner),
@@ -75,6 +75,7 @@
     d_burst_nr(osr),
     d_failed_sch(0)
 {
+
     int i;
     gmsk_mapper(SYNC_BITS, N_SYNC_BITS, d_sch_training_seq, gr_complex(0.0, -1.0));
     for (i = 0; i < TRAIN_SEQ_NUM; i++)
@@ -92,6 +93,7 @@
 
         gmsk_mapper(train_seq[i], N_TRAIN_BITS, d_norm_training_seq[i], startpoint);
     }
+    message_port_register_out(pmt::mp("bursts"));
 }
 
 /*
@@ -117,6 +119,7 @@
     //float *out = (float *) output_items[0];
     int produced_out = 0;  //how many output elements were produced - this isn't used yet
     //probably the gsm receiver will be changed into sink so this variable won't be necessary
+
     switch (d_state)
     {
         //bootstrapping
@@ -145,7 +148,7 @@
             if (abs(prev_freq_offset - d_freq_offset) > FCCH_MAX_FREQ_OFFSET)
             {
                 //set_frequency(d_freq_offset);              //call set_frequncy only frequency offset change is greater than some value
-                DCOUT("Freq offset " << d_freq_offset);
+                COUT("Freq offset " << d_freq_offset);
             }
             //produced_out = 0;
             d_state = sch_search;
@@ -161,7 +164,7 @@
 
     case sch_search:
     {
-        DCOUT("SCH search")    ;    
+        DCOUT("SCH search");
         vector_complex channel_imp_resp(CHAN_IMP_RESP_LENGTH*d_OSR);
         int t1, t2, t3;
         int burst_start = 0;
@@ -220,17 +223,17 @@
             double freq_offset = compute_freq_offset(input, first_sample, last_sample);       //extract frequency offset from it
 
             d_freq_offset_vals.push_front(freq_offset);
-            //process_normal_burst(d_burst_nr, fc_fb);
+            send_burst(d_burst_nr, fc_fb);
             if (d_freq_offset_vals.size() >= 10)
             {
                 double sum = std::accumulate(d_freq_offset_vals.begin(), d_freq_offset_vals.end(), 0);
                 double mean_offset = sum / d_freq_offset_vals.size();                           //compute mean
                 d_freq_offset_vals.clear();
+                DCOUT("mean offset" << mean_offset);
                 if (abs(mean_offset) > FCCH_MAX_FREQ_OFFSET)
                 {
-                    d_freq_offset -= mean_offset;                                                 //and adjust frequency if it have changed beyond
+                    //d_freq_offset -= mean_offset;                                                 //and adjust frequency if it have changed beyond
                     //set_frequency(d_freq_offset);                                                 //some limit
-                    DCOUT("mean_offset: " << mean_offset);
                     DCOUT("Adjusting frequency, new frequency offset: " << d_freq_offset << "\n");
                 }
             }
@@ -241,14 +244,14 @@
             int t1, t2, t3, d_ncc, d_bcc;
             burst_start = get_sch_chan_imp_resp(input, &channel_imp_resp[0]);                //get channel impulse response
             detect_burst(input, &channel_imp_resp[0], burst_start, output_binary);           //MLSE detection of bits
-            //process_normal_burst(d_burst_nr, output_binary);
+            send_burst(d_burst_nr, output_binary);
             if (decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc) == 0)           //and decode SCH data
             {
                 // d_burst_nr.set(t1, t2, t3, 0);                                              //but only to check if burst_start value is correct
                 d_failed_sch = 0;
                 DCOUT("bcc: " << d_bcc << " ncc: " << d_ncc << " t1: " << t1 << " t2: " << t2 << " t3: " << t3);
                 offset =  burst_start - floor((GUARD_PERIOD) * d_OSR);                         //compute offset from burst_start - burst should start after a guard period
-                DCOUT(offset);
+                DCOUT("offset: "<<offset);
                 to_consume += offset;                                                          //adjust with offset number of samples to be consumed
             }
             else
@@ -259,8 +262,8 @@
                     d_state = first_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);
-                    DCOUT("many sch decoding errors");
+                    //set_frequency(0);
+                    DCOUT("Re-Synchronization");
                 }
             }
         }
@@ -271,34 +274,33 @@
             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
-            process_normal_burst(d_burst_nr, output_binary); //TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready
+            send_burst(d_burst_nr, output_binary); //TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready
             break;
         }
         case dummy_or_normal:
         {
             unsigned int normal_burst_start;
             float dummy_corr_max, normal_corr_max;
+            DCOUT("Dummy");
             get_norm_chan_imp_resp(input, &channel_imp_resp[0], &dummy_corr_max, TS_DUMMY);
+            DCOUT("Normal");
             normal_burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], &normal_corr_max, d_bcc);
                         
-            //COUT("normal_corr_max: " << normal_corr_max <<  " dummy_corr_max:" << dummy_corr_max);
+            DCOUT("normal_corr_max: " << normal_corr_max <<  " dummy_corr_max:" << dummy_corr_max);
             if (normal_corr_max > dummy_corr_max)
             {
                 detect_burst(input, &channel_imp_resp[0], normal_burst_start, output_binary);
-                //if (!output_binary[0] && !output_binary[1] && !output_binary[2]) {
-                //  COUT("Normal burst");
-                process_normal_burst(d_burst_nr, output_binary); //TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready
-                //}
+                send_burst(d_burst_nr, output_binary); //TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready
             }
             else
             {
-                //process_normal_burst(d_burst_nr, dummy_burst);
+                send_burst(d_burst_nr, dummy_burst);
             }
         }
         case rach_burst:
             break;
         case dummy:
-            //process_normal_burst(d_burst_nr, dummy_burst);
+            send_burst(d_burst_nr, dummy_burst);
             break;
         case empty:   //if it's empty burst
             break;      //do nothing
@@ -367,14 +369,14 @@
 
             break;
 
-        case search: // search for positive samples
+        case search:                                                // search for positive samples
             sample_number++;
 
             if (sample_number > nitems - FCCH_HITS_NEEDED * d_OSR)   //if it isn't possible to find FCCH because
             {
-                //there's too few samples left to look into,
+                                                                       //there's too few samples left to look into,
                 to_consume = sample_number;                            //don't do anything with those samples which are left
-                //and consume only those which were checked
+                                                                       //and consume only those which were checked
                 fcch_search_state = search_fail;
             }
             else
@@ -725,7 +727,7 @@
     float energy = 0;
 
     int search_center = (int)((TRAIN_POS + GUARD_PERIOD) * d_OSR);
-    int search_start_pos = search_center + 1;
+    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;
 
@@ -764,7 +766,7 @@
     }
     //!why doesn't this work
     int strongest_window_nr_new = max_element(window_energy_buffer.begin(), window_energy_buffer.end()) - window_energy_buffer.begin();
-    strongest_window_nr = 3; //! so I have to override it here
+    strongest_window_nr = strongest_window_nr_new-d_OSR; //! so I have to override it here
 
     max_correlation = 0;
     for (int ii = 0; ii < (d_chan_imp_length)*d_OSR; ii++)
@@ -778,7 +780,7 @@
         //     d_channel_imp_resp.push_back(correlation);
         chan_imp_resp[ii] = correlation;
     }
-    
+
     *corr_max = max_correlation;
     // We want to use the first sample of the impulse response, and the
     // corresponding samples of the received signal.
@@ -796,20 +798,26 @@
     //COUT("Poczatek ###############################");
     //std::cout << " burst_start: " << burst_start << " center: " << ((float)(search_start_pos + strongest_window_nr + chan_imp_resp_center)) / d_OSR << " stronegest window nr: " <<  strongest_window_nr << "\n";
     //COUT("burst_start_new: " << (search_start_pos + strongest_window_nr_new - TRAIN_POS * d_OSR));
-    burst_start=(search_start_pos + strongest_window_nr_new - TRAIN_POS * d_OSR);
+    DCOUT("strongest_window_nr_new: " << strongest_window_nr);
+    burst_start=(search_start_pos + strongest_window_nr - TRAIN_POS * d_OSR);
+
+    DCOUT("burst_start: " << burst_start);
     return burst_start;
 }
 
 
-void receiver_impl::process_normal_burst(burst_counter burst_nr, const unsigned char * burst_binary)
+void receiver_impl::send_burst(burst_counter burst_nr, const unsigned char * burst_binary)
 {
     int ii;
-    //std::cout << "fn:" <<burst_nr.get_frame_nr() << " ts" << burst_nr.get_timeslot_nr() << " ";
-    for(ii=0; ii<148; ii++)
-    {
-        std::cout << std::setprecision(1) << static_cast<int>(burst_binary[ii]) << "";
-    }
-    std::cout << std::endl;
+    
+    static const int nelements = 148;
+    pmt::pmt_t burst = pmt::make_s8vector(nelements, 0);  // Initializes all 64 elements to 0
+
+    size_t vec_size;
+    int8_t *burst_elements = pmt::s8vector_writable_elements(burst, vec_size);  // Returns pointer, vec_size is set to 64
+  
+    memcpy(burst_elements, burst_binary, nelements);
+    message_port_pub(pmt::mp("bursts"), burst);
 }
 //TODO: this shouldn't be here also - the same reason
 void receiver_impl::configure_receiver()
diff --git a/lib/receiver_impl.h b/lib/receiver_impl.h
index 6fb1778..40ce91d 100644
--- a/lib/receiver_impl.h
+++ b/lib/receiver_impl.h
@@ -189,7 +189,7 @@
         /**
          *
          */
-        void process_normal_burst(burst_counter burst_nr, const unsigned char * burst_binary);
+        void send_burst(burst_counter burst_nr, const unsigned char * burst_binary);
 
         /**
          *
diff --git a/python/receiver_hier.py b/python/receiver_hier.py
index 1737d41..2b2f9ab 100755
--- a/python/receiver_hier.py
+++ b/python/receiver_hier.py
@@ -1,5 +1,6 @@
 #!/usr/bin/env python
 
+import weakref
 import gsm
 from gnuradio.eng_option import eng_option
 from gnuradio import gr, gru, blocks
@@ -22,6 +23,9 @@
                                 gr.io_signature(1, 1, 142*gr.sizeof_float))
         #set rates
         gsm_symb_rate = 1625000/6.0
+
+        self.message_port_register_hier_in("bursts")
+
         self.input_rate = input_rate
         self.osr = osr
         self.sps = input_rate / gsm_symb_rate / osr
@@ -33,6 +37,8 @@
         self.interpolator = self._set_interpolator()
         self.receiver = self._set_receiver()
         self.connect(self, self.filtr,  self.interpolator, self.receiver,  self)
+        self.msg_connect(self.receiver, "bursts", weakref.proxy(self), "bursts")
+
 
     def _set_filter(self):
         filter_cutoff   = 125e3	
diff --git a/swig/gsm_swig.i b/swig/gsm_swig.i
index e1c3613..5aaf16d 100644
--- a/swig/gsm_swig.i
+++ b/swig/gsm_swig.i
@@ -9,8 +9,11 @@
 
 %{
 #include "gsm/receiver.h"
+#include "gsm/bursts_printer.h"
 %}
 
 
 %include "gsm/receiver.h"
 GR_SWIG_BLOCK_MAGIC2(gsm, receiver);
+%include "gsm/bursts_printer.h"
+GR_SWIG_BLOCK_MAGIC2(gsm, bursts_printer);