receiver: add public API for multiframe configuration

Change-Id: I3a4621852baad254f2bd626251fb7958492f0f32
diff --git a/include/grgsm/receiver/receiver.h b/include/grgsm/receiver/receiver.h
index dbbe327..6c306bf 100644
--- a/include/grgsm/receiver/receiver.h
+++ b/include/grgsm/receiver/receiver.h
@@ -29,6 +29,8 @@
 #include <gnuradio/sync_block.h>
 #include <vector>
 
+#include <grgsm/gsm_constants.h>
+
 namespace gr {
   namespace gsm {
 
@@ -55,6 +57,19 @@
       virtual void set_cell_allocation(const std::vector<int> &cell_allocation) = 0;
       virtual void set_tseq_nums(const std::vector<int> & tseq_nums) = 0;
       virtual void reset() = 0;
+
+      /* Reset multiframe configuration for all timeslots */
+      virtual void reset_mf_config(void) = 0;
+      /* Get multiframe type for a given timeslot */
+      virtual multiframe_type get_mf_type(int tn) = 0;
+      /* Set multiframe type for a given timeslot */
+      virtual void set_mf_type(int tn, multiframe_type type) = 0;
+      /* Get burst type for a given pair of timeslot and frame number */
+      virtual burst_type get_mf_burst_type(int tn, unsigned fn) = 0;
+      /* Set burst type for a given pair of timeslot and frame number */
+      virtual void set_mf_burst_type(int tn, unsigned fn, burst_type type) = 0;
+      /* Set burst type for every frame number within a given modulo */
+      virtual void set_mf_burst_type_mod(int tn, int mod, unsigned fn, burst_type type) = 0;
     };
    
   } // namespace gsm
diff --git a/lib/receiver/receiver_config.h b/lib/receiver/receiver_config.h
index e6ca267..181132a 100644
--- a/lib/receiver/receiver_config.h
+++ b/lib/receiver/receiver_config.h
@@ -58,6 +58,12 @@
       }
     }
 
+    void reset(void) {
+      fill(d_burst_types.begin(), d_burst_types.end(), empty);
+      d_burst_types.resize(0);
+      d_type = unknown;
+    }
+
     void set_burst_type(int nr, burst_type type) {
       d_burst_types[nr] = type;
     }
@@ -146,6 +152,10 @@
       }
     }
 
+    multiframe_type get_multiframe_type(int timeslot_nr) {
+      return d_timeslots_descriptions[timeslot_nr].get_type();
+    }
+
     void set_multiframe_type(int timeslot_nr, multiframe_type type) {
       d_timeslots_descriptions[timeslot_nr].set_type(type);
     }
@@ -157,13 +167,17 @@
       }
     }
 
+    burst_type get_single_burst_type(int timeslot_nr, int burst_nr) {
+      return d_timeslots_descriptions[timeslot_nr].get_burst_type(burst_nr);
+    }
+
     void set_single_burst_type(int timeslot_nr, int burst_nr, burst_type b_type) {
       d_timeslots_descriptions[timeslot_nr].set_burst_type(burst_nr, b_type);
     }
 
     void reset_all(void) {
       for (int i = 0; i < TS_PER_FRAME; i++)
-        set_multiframe_type(i, unknown);
+        d_timeslots_descriptions[i].reset();
     }
 
     burst_type get_burst_type(burst_counter burst_nr);
diff --git a/lib/receiver/receiver_impl.cc b/lib/receiver/receiver_impl.cc
index ffaf9ee..94ad422 100644
--- a/lib/receiver/receiver_impl.cc
+++ b/lib/receiver/receiver_impl.cc
@@ -1132,5 +1132,59 @@
     {
       d_state = fcch_search;
     }
+
+    void
+    receiver_impl::reset_mf_config(void)
+    {
+      d_channel_conf.reset_all();
+    }
+
+    multiframe_type
+    receiver_impl::get_mf_type(int tn)
+    {
+      return d_channel_conf.get_multiframe_type(tn);
+    }
+
+    void
+    receiver_impl::set_mf_type(int tn, multiframe_type type)
+    {
+      d_channel_conf.set_multiframe_type(tn, type);
+    }
+
+    burst_type
+    receiver_impl::get_mf_burst_type(int tn, unsigned fn)
+    {
+      return d_channel_conf.get_single_burst_type(tn, fn);
+    }
+
+    void
+    receiver_impl::set_mf_burst_type(int tn, unsigned fn, burst_type type)
+    {
+      d_channel_conf.set_single_burst_type(tn, fn, type);
+    }
+
+    void
+    receiver_impl::set_mf_burst_type_mod(int tn, int mod, unsigned fn, burst_type type)
+    {
+      multiframe_type mf_type;
+      unsigned i, mf_len;
+
+      mf_type = d_channel_conf.get_multiframe_type(tn);
+      switch (mf_type) {
+      case multiframe_51:
+        mf_len = 51; break;
+      case multiframe_26:
+        mf_len = 26; break;
+      case unknown:
+      default:
+        mf_len = 0; break;
+      }
+
+      for (i = 0; i < mf_len; i++) {
+        if (i % mod == fn)
+          d_channel_conf.set_single_burst_type(tn, i, type);
+      }
+    }
+
   } /* namespace gsm */
 } /* namespace gr */
diff --git a/lib/receiver/receiver_impl.h b/lib/receiver/receiver_impl.h
index a7d7bc2..db3fdab 100644
--- a/lib/receiver/receiver_impl.h
+++ b/lib/receiver/receiver_impl.h
@@ -222,6 +222,19 @@
         virtual void set_cell_allocation(const std::vector<int> &cell_allocation);
         virtual void set_tseq_nums(const std::vector<int> & tseq_nums);
         virtual void reset();
+
+        /* Reset multiframe configuration for all timeslots */
+        virtual void reset_mf_config(void);
+        /* Get multiframe type for a given timeslot */
+        virtual multiframe_type get_mf_type(int tn);
+        /* Set multiframe type for a given timeslot */
+        virtual void set_mf_type(int tn, multiframe_type type);
+        /* Get burst type for a given pair of timeslot and frame number */
+        virtual burst_type get_mf_burst_type(int tn, unsigned fn);
+        /* Set burst type for a given pair of timeslot and frame number */
+        virtual void set_mf_burst_type(int tn, unsigned fn, burst_type type);
+        /* Set burst type for every frame number within a given modulo */
+        virtual void set_mf_burst_type_mod(int tn, int mod, unsigned fn, burst_type type);
     };
   } // namespace gsm
 } // namespace gr
diff --git a/swig/grgsm_swig.i b/swig/grgsm_swig.i
index ec1eea7..7b00ee8 100644
--- a/swig/grgsm_swig.i
+++ b/swig/grgsm_swig.i
@@ -33,6 +33,7 @@
 
 %{
 #include "grgsm/constants.h"
+#include "grgsm/gsm_constants.h"
 #include "grgsm/receiver/receiver.h"
 #include "grgsm/receiver/clock_offset_control.h"
 #include "grgsm/receiver/cx_channel_hopper.h"
@@ -80,6 +81,7 @@
 %}
 
 %include "constants.i"
+%include "grgsm/gsm_constants.h"
 
 %include "grgsm/receiver/receiver.h"
 GR_SWIG_BLOCK_MAGIC2(gsm, receiver);