Added block for doing hopping for mobile station transceiver
diff --git a/grc/gsm_block_tree.xml b/grc/gsm_block_tree.xml
index 2e502d0..a16f4c0 100644
--- a/grc/gsm_block_tree.xml
+++ b/grc/gsm_block_tree.xml
@@ -32,6 +32,7 @@
     <cat>
       <name>Transceiver</name>
       <block>gsm_trx_burst_if</block>
+      <block>gsm_freq_hopping</block>
     </cat>
     <cat>
       <name>Logical channels demapping</name>
diff --git a/grc/trx/CMakeLists.txt b/grc/trx/CMakeLists.txt
index ac4ae13..0c7a636 100644
--- a/grc/trx/CMakeLists.txt
+++ b/grc/trx/CMakeLists.txt
@@ -19,5 +19,6 @@
 
 install(FILES
     gsm_trx_burst_if.xml
+    gsm_freq_hopping.xml
     DESTINATION share/gnuradio/grc/blocks
 )
diff --git a/grc/trx/gsm_freq_hopping.xml b/grc/trx/gsm_freq_hopping.xml
new file mode 100644
index 0000000..9e71e53
--- /dev/null
+++ b/grc/trx/gsm_freq_hopping.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<block>
+  <name>freq_hopping</name>
+  <key>gsm_freq_hopping</key>
+  <import>import grgsm</import>
+  <make>grgsm.freq_hopping($hopping_cmd)</make>
+<!--  <callback>set_fn_time_reference($init_fn, $init_time_secs, $init_time_fracs)</callback>-->
+  <param>
+    <name>Initial hopping command</name>
+    <key>hopping_cmd</key>
+    <value>pmt.to_pmt({'cmd': 'start', 'hopping_params': {'hsn': 1, 'maio': 0, 'ma': [1,2,3,4]} })</value>
+    <type>raw</type>
+    <hide>part</hide>
+  </param>
+
+  <sink>
+    <name>hopping_cmd</name>
+    <type>message</type>
+    <optional>1</optional>
+  </sink>
+
+  <sink>
+    <name>bursts_in</name>
+    <type>message</type>
+    <optional>1</optional>
+  </sink>
+
+  <source>
+    <name>bursts_out</name>
+    <type>message</type>
+    <optional>1</optional>
+  </source>
+</block>
diff --git a/include/grgsm/trx/CMakeLists.txt b/include/grgsm/trx/CMakeLists.txt
index a9847dd..0addc79 100644
--- a/include/grgsm/trx/CMakeLists.txt
+++ b/include/grgsm/trx/CMakeLists.txt
@@ -21,6 +21,7 @@
 # Install public header files
 ########################################################################
 install(FILES
+    freq_hopping.h
     trx_burst_if.h
     DESTINATION include/grgsm/trx
 )
diff --git a/include/grgsm/trx/freq_hopping.h b/include/grgsm/trx/freq_hopping.h
new file mode 100644
index 0000000..eeb3a53
--- /dev/null
+++ b/include/grgsm/trx/freq_hopping.h
@@ -0,0 +1,68 @@
+/* -*- c++ -*- */
+/* @file
+ * @author Piotr Krysik <ptrkrysik@gmail.com>
+ * @section LICENSE
+ * 
+ * Gr-gsm 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.
+ * 
+ * Gr-gsm 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 gr-gsm; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ * 
+ */
+
+
+#ifndef INCLUDED_GSM_FREQ_HOPPING_H
+#define INCLUDED_GSM_FREQ_HOPPING_H
+
+#include <grgsm/api.h>
+#include <gnuradio/block.h>
+
+namespace gr {
+  namespace gsm {
+
+    /*!
+     * \brief <+description of block+>
+     * \ingroup gsm
+     *
+     */
+    class GRGSM_API freq_hopping : virtual public gr::block
+    {
+     public:
+      typedef boost::shared_ptr<freq_hopping> sptr;
+
+      /*!
+       * hopping_cmd is a pmt dictionary with following fields:
+       * "cmd": string with type of command, possible values:
+       *     -"start" - immediately start hopping or if there is "fn" 
+       *                field defined start from frame number defined 
+       *                by that field
+       *     -"stop"  - immediately stop hopping or if there is "fn" 
+       *                field defined start from frame number defined 
+       *                by that field
+       *     -"discard" - discard all queued "start_fn" and "stop_fn" 
+       *                (this command doesn't require hopping parameters or frame number)
+       * "hopping_params": dictionary with hopping parameters in following form:
+       *     {"hsn": hopping_sequence_number(uint64),
+       *      "ma":   mobile_allocation(list of arfcns),
+       *      "maio": mobile_allocation_index_offset(uint64),
+       *      "n_arfcn": number_of_arfcns_in_ma}
+       *  "fn": frame number when to start or stop hopping
+       */
+      static sptr make(pmt::pmt_t hopping_cmd);
+      virtual void add_hopping_cmd(pmt::pmt_t hopping_cmd=pmt::PMT_NIL) = 0;
+    };
+  } // namespace gsm
+} // namespace gr
+
+#endif /* INCLUDED_GSM_FREQ_HOPPING_H */
+
diff --git a/lib/trx/CMakeLists.txt b/lib/trx/CMakeLists.txt
index 32694b2..0bfbe34 100644
--- a/lib/trx/CMakeLists.txt
+++ b/lib/trx/CMakeLists.txt
@@ -19,5 +19,6 @@
 
 add_sources(
     trx_burst_if_impl.cc
+    freq_hopping_impl.cc
 )
 
diff --git a/lib/trx/freq_hopping_impl.cc b/lib/trx/freq_hopping_impl.cc
new file mode 100644
index 0000000..4f2ba7b
--- /dev/null
+++ b/lib/trx/freq_hopping_impl.cc
@@ -0,0 +1,140 @@
+
+/* -*- c++ -*- */
+/* @file
+ * @author Piotr Krysik <ptrkrysik@gmail.com>
+ * @section LICENSE
+ * 
+ * Gr-gsm 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.
+ * 
+ * Gr-gsm 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 gr-gsm; 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 <grgsm/gsmtap.h>
+
+#include "freq_hopping_impl.h"
+#include "../misc_utils/freq_hopping_utils.h"
+
+namespace gr {
+  namespace gsm {
+    using namespace pmt;
+
+    freq_hopping::sptr
+    freq_hopping::make(
+      pmt_t hopping_cmd)
+    {
+      return gnuradio::get_initial_sptr
+        (new freq_hopping_impl(hopping_cmd));
+    }
+
+    /*
+     * The private constructor
+     */
+    freq_hopping_impl::freq_hopping_impl(
+      pmt_t hopping_cmd
+    ) : gr::block("freq_hopping",
+          gr::io_signature::make(0, 0, 0),
+          gr::io_signature::make(0, 0, 0)),
+          d_hopping_cmd(PMT_NIL),
+          d_hopping_enable(false)
+    {
+        // Register I/O ports
+        message_port_register_in(mp("hopping_cmd"));
+        message_port_register_in(mp("bursts_in"));
+        message_port_register_out(mp("bursts_out"));
+
+        // Bind message handlers
+        set_msg_handler(mp("hopping_cmd"),
+          boost::bind(&freq_hopping_impl::add_hopping_cmd,
+            this, _1));
+        
+        set_msg_handler(mp("bursts_in"),
+          boost::bind(&freq_hopping_impl::set_freq_metadata,
+            this, _1));
+        
+        add_hopping_cmd(hopping_cmd);
+    }
+
+    /*
+     * Our virtual destructor.
+     */
+    freq_hopping_impl::~freq_hopping_impl()
+    {
+    }
+    
+    void freq_hopping_impl::add_hopping_cmd(pmt_t cmd) //TODO: fn and discard not supported at the moment
+    {
+      if(dict_ref(cmd,intern("cmd"), PMT_NIL) == intern("start")) {
+        if(dict_ref(cmd,intern("fn"), PMT_NIL)  != PMT_NIL){
+          //TODO add the command to the map<int,pmt_t>
+        } else {
+          pmt_t hopping_params = dict_ref(cmd, intern("hopping_params"), PMT_NIL);
+          d_hopping_enable = set_hopping_params(hopping_params);
+        } 
+      } else if(dict_ref(cmd,intern("cmd"), PMT_NIL) == intern("stop")) {
+        if(dict_ref(cmd,intern("fn"),PMT_NIL)  != PMT_NIL){
+          //TODO add the command to the map<int,pmt_t>
+        } else {
+          d_hopping_enable = false;
+        }
+      }
+    }
+    
+    void freq_hopping_impl::set_freq_metadata(pmt_t burst)
+    {
+      if(d_hopping_enable) {
+        pmt::pmt_t header_plus_burst = pmt::cdr(burst);
+        gsmtap_hdr *header = (gsmtap_hdr *)pmt::blob_data(header_plus_burst);
+
+        uint32_t frame_nr = be32toh(header->frame_number);
+        
+        int mai = calculate_ma_sfh(d_maio, d_hsn, d_ma.size(), frame_nr);
+        uint16_t arfcn = d_ma[mai];
+        header->arfcn = htobe16(arfcn);
+        header->arfcn = header->arfcn | 0x8000; // set uplink flag
+
+        //oblicz czestotliwosc i ustaw w headerze
+
+      } else {
+        message_port_pub(pmt::mp("bursts_out"), burst);
+      }
+    }
+    
+    bool freq_hopping_impl::set_hopping_params(pmt::pmt_t hopping_params){
+      bool retval = false;
+      if(hopping_params != PMT_NIL){
+        //set hopping parameters immediately
+        pmt_t hsn = dict_ref(hopping_params, intern("hsn"), PMT_NIL);
+        pmt_t maio = dict_ref(hopping_params, intern("maio"), PMT_NIL);;
+        pmt_t ma = dict_ref(hopping_params, intern("ma"), PMT_NIL);
+        
+        if(is_vector(ma) && is_integer(hsn) && is_integer(maio)){  //TODO: checking the values
+          d_hsn = to_uint64(hsn);
+          d_maio = to_uint64(maio);
+          d_ma.resize(length(ma));
+          for(int i=0; i<length(ma); i++){
+            d_ma[i] = to_uint64(vector_ref(ma,i));
+          }
+          retval = true;
+        }
+      }
+      return retval;
+    }
+  } /* namespace gsm */
+} /* namespace gr */
diff --git a/lib/trx/freq_hopping_impl.h b/lib/trx/freq_hopping_impl.h
new file mode 100644
index 0000000..6b1d3a5
--- /dev/null
+++ b/lib/trx/freq_hopping_impl.h
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/* @file
+ * @author Piotr Krysik <ptrkrysik@gmail.com>
+ * @section LICENSE
+ * 
+ * Gr-gsm 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.
+ * 
+ * Gr-gsm 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 gr-gsm; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ * 
+ */
+
+#ifndef INCLUDED_GSM_FREQ_HOPPING_IMPL_H
+#define INCLUDED_GSM_FREQ_HOPPING_IMPL_H
+
+#include <grgsm/trx/freq_hopping.h>
+#include <grgsm/misc_utils/time_spec.h>
+#include <grgsm/misc_utils/fn_time.h>
+
+namespace gr {
+  namespace gsm {
+
+    class freq_hopping_impl : public freq_hopping
+    {
+     private:
+      bool d_hopping_enable; //if true block do the hopping, if not block just passes the bursts
+      uint64_t d_hsn; //hopping sequence number
+      uint64_t d_maio; //mobile allocation index offset
+      std::vector<uint64_t> d_ma; //mobile allocation
+     
+      pmt::pmt_t d_hopping_cmd; //TODO: change this uint64_to a std::map
+      void set_freq_metadata(pmt::pmt_t cmd);
+      bool set_hopping_params(pmt::pmt_t hopping_params);
+     public:
+      freq_hopping_impl(pmt::pmt_t hopping_cmd);
+      ~freq_hopping_impl();
+
+      void add_hopping_cmd(pmt::pmt_t hopping_cmd);
+    };
+
+  } // namespace gsm
+} // namespace gr
+
+#endif /* INCLUDED_GSM_FREQ_HOPPING_IMPL_H */
diff --git a/swig/grgsm_swig.i b/swig/grgsm_swig.i
index 83740e6..b980fc2 100644
--- a/swig/grgsm_swig.i
+++ b/swig/grgsm_swig.i
@@ -74,6 +74,7 @@
 #include "grgsm/transmitter/txtime_setter.h"
 #include "grgsm/transmitter/preprocess_tx_burst.h"
 #include "grgsm/transmitter/gen_test_ab.h"
+#include "grgsm/trx/freq_hopping.h"
 #include "grgsm/trx/trx_burst_if.h"
 %}
 
@@ -148,6 +149,8 @@
 GR_SWIG_BLOCK_MAGIC2(gsm, extract_cmc);
 %include "grgsm/misc_utils/extract_assignment_cmd.h"
 GR_SWIG_BLOCK_MAGIC2(gsm, extract_assignment_cmd);
+%include "grgsm/trx/freq_hopping.h"
+GR_SWIG_BLOCK_MAGIC2(gsm, freq_hopping);
 %include "grgsm/trx/trx_burst_if.h"
 GR_SWIG_BLOCK_MAGIC2(gsm, trx_burst_if);
 %include "grgsm/misc_utils/burst_to_fn_time.h"