aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorPiotr Krysik <ptrkrysik@gmail.com>2018-04-16 22:21:29 +0200
committerPiotr Krysik <ptrkrysik@gmail.com>2018-04-16 22:21:29 +0200
commit8a8d41a58320d5f30713a6e6362c86d5db6de1de (patch)
treed95b1badab52b83126d57d410dd8e92e7a255c8e /lib
parent8b9b88d788cc5064c0f6d7aa60a14954aee59eab (diff)
parentfe4db93e6d03e92a958664bfffcd0e2923f20e34 (diff)
Merge branch 'ptrkrysik/trx' into development
Diffstat (limited to 'lib')
-rw-r--r--lib/CMakeLists.txt1
-rw-r--r--lib/decoding/sch.c2
-rw-r--r--lib/flow_control/CMakeLists.txt1
-rw-r--r--lib/flow_control/burst_type_filter_impl.cc103
-rw-r--r--lib/flow_control/burst_type_filter_impl.h55
-rw-r--r--lib/flow_control/uplink_downlink_splitter_impl.cc4
-rw-r--r--lib/flow_control/uplink_downlink_splitter_impl.h4
-rw-r--r--lib/misc_utils/CMakeLists.txt4
-rw-r--r--lib/misc_utils/controlled_fractional_resampler_cc_impl.cc2
-rw-r--r--lib/misc_utils/controlled_fractional_resampler_cc_impl.h2
-rw-r--r--lib/misc_utils/fn_time.cc94
-rw-r--r--lib/misc_utils/msg_to_tag_impl.cc2
-rw-r--r--lib/misc_utils/msg_to_tag_impl.h2
-rw-r--r--lib/misc_utils/time_spec.cc122
-rw-r--r--lib/misc_utils/trx_burst_if_impl.cc231
-rw-r--r--lib/misc_utils/trx_burst_if_impl.h54
-rw-r--r--lib/misc_utils/udp_socket.cc119
-rw-r--r--lib/misc_utils/udp_socket.h69
-rw-r--r--lib/qa_utils/burst_sink_impl.cc8
-rw-r--r--lib/qa_utils/burst_sink_impl.h2
-rw-r--r--lib/receiver/CMakeLists.txt1
-rw-r--r--lib/receiver/clock_offset_control_impl.cc2
-rw-r--r--lib/receiver/gsm_constants.h177
-rw-r--r--lib/receiver/receiver_config.h2
-rw-r--r--lib/receiver/receiver_impl.cc77
-rw-r--r--lib/receiver/receiver_impl.h22
-rw-r--r--lib/receiver/time_sample_ref.cc60
-rw-r--r--lib/receiver/time_sample_ref.h49
-rw-r--r--lib/receiver/viterbi_detector.cc3
-rw-r--r--lib/transmitter/CMakeLists.txt24
-rw-r--r--lib/transmitter/gen_test_ab_impl.cc107
-rw-r--r--lib/transmitter/gen_test_ab_impl.h47
-rw-r--r--lib/transmitter/preprocess_tx_burst_impl.cc96
-rw-r--r--lib/transmitter/preprocess_tx_burst_impl.h47
-rw-r--r--lib/transmitter/txtime_setter_impl.cc196
-rw-r--r--lib/transmitter/txtime_setter_impl.h64
36 files changed, 1636 insertions, 219 deletions
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index db440e4..923de48 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -70,6 +70,7 @@ add_subdirectory(flow_control)
add_subdirectory(misc_utils)
add_subdirectory(qa_utils)
add_subdirectory(receiver)
+add_subdirectory(transmitter)
########################################################################
# Setup library
diff --git a/lib/decoding/sch.c b/lib/decoding/sch.c
index 9cf6ac4..fff82ea 100644
--- a/lib/decoding/sch.c
+++ b/lib/decoding/sch.c
@@ -21,7 +21,7 @@
*/
#include <string.h>
-#include "gsm_constants.h"
+#include <grgsm/gsm_constants.h>
#include <stdbool.h>
#include <osmocom/coding/gsm0503_coding.h>
diff --git a/lib/flow_control/CMakeLists.txt b/lib/flow_control/CMakeLists.txt
index 30a5f50..b8f63f7 100644
--- a/lib/flow_control/CMakeLists.txt
+++ b/lib/flow_control/CMakeLists.txt
@@ -23,6 +23,7 @@ add_sources(
burst_sdcch_subslot_splitter_impl.cc
burst_timeslot_filter_impl.cc
burst_timeslot_splitter_impl.cc
+ burst_type_filter_impl.cc
dummy_burst_filter_impl.cc
uplink_downlink_splitter_impl.cc
)
diff --git a/lib/flow_control/burst_type_filter_impl.cc b/lib/flow_control/burst_type_filter_impl.cc
new file mode 100644
index 0000000..c8bbd7e
--- /dev/null
+++ b/lib/flow_control/burst_type_filter_impl.cc
@@ -0,0 +1,103 @@
+/* -*- c++ -*- */
+/* @file
+ * @author (C) 2017 by 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 "burst_type_filter_impl.h"
+#include <stdio.h>
+#include <grgsm/endian.h>
+#include <grgsm/gsmtap.h>
+
+
+namespace gr {
+ namespace gsm {
+
+ burst_type_filter::sptr
+ burst_type_filter::make(const std::vector<uint8_t> & selected_burst_types)
+ {
+ return gnuradio::get_initial_sptr
+ (new burst_type_filter_impl(selected_burst_types));
+ }
+
+ /*
+ * The private constructor
+ */
+ burst_type_filter_impl::burst_type_filter_impl(const std::vector<uint8_t> & selected_burst_types)
+ : gr::block("burst_type_filter",
+ gr::io_signature::make(0, 0, 0),
+ gr::io_signature::make(0, 0, 0)),
+ d_filter_policy(FILTER_POLICY_DEFAULT)
+ {
+ set_selected_burst_types(selected_burst_types);
+
+ message_port_register_in(pmt::mp("bursts_in"));
+ message_port_register_out(pmt::mp("bursts_out"));
+
+ set_msg_handler(pmt::mp("bursts_in"), boost::bind(&burst_type_filter_impl::process_burst, this, _1));
+ }
+
+ /*
+ * Our virtual destructor.
+ */
+ burst_type_filter_impl::~burst_type_filter_impl() {}
+
+ void burst_type_filter_impl::process_burst(pmt::pmt_t msg)
+ {
+ if (d_filter_policy == FILTER_POLICY_DROP_ALL)
+ return;
+
+ if (d_filter_policy == FILTER_POLICY_PASS_ALL) {
+ message_port_pub(pmt::mp("bursts_out"), msg);
+ return;
+ }
+
+ gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(pmt::cdr(msg));
+ if (std::find(d_selected_burst_types.begin(), d_selected_burst_types.end(), header->sub_type) != d_selected_burst_types.end()) //check if burst type is listed in burst types to pass
+ {
+ message_port_pub(pmt::mp("bursts_out"), msg);
+ }
+ }
+
+ /* Filtering policy */
+ filter_policy
+ burst_type_filter_impl::get_policy(void)
+ {
+ return d_filter_policy;
+ }
+
+ filter_policy
+ burst_type_filter_impl::set_policy(filter_policy policy)
+ {
+ d_filter_policy = policy;
+ return d_filter_policy;
+ }
+
+ void
+ burst_type_filter_impl::set_selected_burst_types(const std::vector<uint8_t> & selected_burst_types)
+ {
+ d_selected_burst_types.assign(selected_burst_types.begin(), selected_burst_types.end());
+ }
+ } /* namespace gsm */
+} /* namespace gr */
diff --git a/lib/flow_control/burst_type_filter_impl.h b/lib/flow_control/burst_type_filter_impl.h
new file mode 100644
index 0000000..5c6ad14
--- /dev/null
+++ b/lib/flow_control/burst_type_filter_impl.h
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/* @file
+ * @author (C) 2017 by 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_BURST_TYPE_FILTER_IMPL_H
+#define INCLUDED_GSM_BURST_TYPE_FILTER_IMPL_H
+
+#define BURST_TYPE_LEN 148
+
+#include <grgsm/flow_control/burst_type_filter.h>
+
+namespace gr {
+ namespace gsm {
+
+ class burst_type_filter_impl : public burst_type_filter
+ {
+ private:
+ filter_policy d_filter_policy;
+ std::vector<uint8_t> d_selected_burst_types;
+ public:
+ burst_type_filter_impl(const std::vector<uint8_t> & selected_burst_types);
+ ~burst_type_filter_impl();
+ void process_burst(pmt::pmt_t msg);
+
+ /* External API */
+ /* Filtering policy */
+ filter_policy get_policy(void);
+ filter_policy set_policy(filter_policy policy);
+
+ void set_selected_burst_types(const std::vector<uint8_t> & selected_burst_types);
+ };
+
+ } // namespace gsm
+} // namespace gr
+
+#endif /* INCLUDED_GSM_BURST_TYPE_FILTER_IMPL_H */
+
diff --git a/lib/flow_control/uplink_downlink_splitter_impl.cc b/lib/flow_control/uplink_downlink_splitter_impl.cc
index 691feb3..de5ae30 100644
--- a/lib/flow_control/uplink_downlink_splitter_impl.cc
+++ b/lib/flow_control/uplink_downlink_splitter_impl.cc
@@ -30,7 +30,7 @@
#include <grgsm/endian.h>
#define BURST_SIZE 148
namespace gr {
- namespace grgsm {
+ namespace gsm {
uplink_downlink_splitter::sptr
uplink_downlink_splitter::make()
@@ -71,6 +71,6 @@ namespace gr {
uplink_downlink_splitter_impl::~uplink_downlink_splitter_impl()
{
}
- } /* namespace grgsm */
+ } /* namespace gsm */
} /* namespace gr */
diff --git a/lib/flow_control/uplink_downlink_splitter_impl.h b/lib/flow_control/uplink_downlink_splitter_impl.h
index fb8b2b8..5edfe5a 100644
--- a/lib/flow_control/uplink_downlink_splitter_impl.h
+++ b/lib/flow_control/uplink_downlink_splitter_impl.h
@@ -26,7 +26,7 @@
#include <grgsm/flow_control/uplink_downlink_splitter.h>
namespace gr {
- namespace grgsm {
+ namespace gsm {
class uplink_downlink_splitter_impl : public uplink_downlink_splitter
{
@@ -36,7 +36,7 @@ namespace gr {
void process_msg(pmt::pmt_t msg);
};
- } // namespace grgsm
+ } // namespace gsm
} // namespace gr
#endif /* INCLUDED_GRGSM_UPLINK_DOWNLINK_SPLITTER_IMPL_H */
diff --git a/lib/misc_utils/CMakeLists.txt b/lib/misc_utils/CMakeLists.txt
index 720eee3..e0fc818 100644
--- a/lib/misc_utils/CMakeLists.txt
+++ b/lib/misc_utils/CMakeLists.txt
@@ -33,5 +33,9 @@ add_sources(
message_printer_impl.cc
msg_to_tag_impl.cc
tmsi_dumper_impl.cc
+ time_spec.cc
+ fn_time.cc
+ udp_socket.cc
+ trx_burst_if_impl.cc
)
diff --git a/lib/misc_utils/controlled_fractional_resampler_cc_impl.cc b/lib/misc_utils/controlled_fractional_resampler_cc_impl.cc
index 3376c67..36cf170 100644
--- a/lib/misc_utils/controlled_fractional_resampler_cc_impl.cc
+++ b/lib/misc_utils/controlled_fractional_resampler_cc_impl.cc
@@ -177,6 +177,6 @@ namespace gr {
set_relative_rate(1.0 / resamp_ratio);
}
- } /* namespace grgsm */
+ } /* namespace gsm */
} /* namespace gr */
diff --git a/lib/misc_utils/controlled_fractional_resampler_cc_impl.h b/lib/misc_utils/controlled_fractional_resampler_cc_impl.h
index 24e00ed..1ca8082 100644
--- a/lib/misc_utils/controlled_fractional_resampler_cc_impl.h
+++ b/lib/misc_utils/controlled_fractional_resampler_cc_impl.h
@@ -64,7 +64,7 @@ namespace gr {
void set_resamp_ratio(float resamp_ratio);
};
- } // namespace grgsm
+ } // namespace gsm
} // namespace gr
#endif /* INCLUDED_GRGSM_CONTROLLED_FRACTIONAL_RESAMPLER_CC_IMPL_H */
diff --git a/lib/misc_utils/fn_time.cc b/lib/misc_utils/fn_time.cc
new file mode 100644
index 0000000..2773f33
--- /dev/null
+++ b/lib/misc_utils/fn_time.cc
@@ -0,0 +1,94 @@
+/* -*- c++ -*- */
+/* @file
+ * @author Piotr Krysik <ptrkrysik@gmail.com>
+ * @author Vadim Yanitskiy <axilirator@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.
+ *
+ */
+
+#include <grgsm/misc_utils/fn_time.h>
+#include <grgsm/misc_utils/time_spec.h>
+#include <math.h>
+
+#define GSM_HYPER_FRAME (26 * 51 * 2048)
+#define GSM_SYM_RATE (13.0e6 / 48.0)
+
+#define GSM_TS_PERIOD (156.25 / GSM_SYM_RATE)
+#define GSM_FN_PERIOD (8 * GSM_TS_PERIOD)
+
+namespace gr {
+ namespace gsm {
+ /**
+ * Computes difference between two frame numbers modulo
+ * GSM_HYPER_FRAME / 2. The result is correct if difference
+ * between the frame numbers is not bigger than GSM_HYPER_FRAME / 2.
+ * @param fn1 first frame number
+ * @param fn2 second frame number
+ * @return computed difference
+ */
+ static int fnmod_delta(uint32_t fn1, uint32_t fn2)
+ {
+ int delta, h2;
+
+ delta = (fn1 % GSM_HYPER_FRAME) - (fn2 % GSM_HYPER_FRAME);
+
+ h2 = GSM_HYPER_FRAME / 2;
+
+ if (delta >= h2) {
+ delta -= GSM_HYPER_FRAME;
+ } else if(delta < -h2) {
+ delta += GSM_HYPER_FRAME;
+ }
+
+ return delta;
+ }
+
+ static int fn_time_diff_delta(uint32_t fn, uint32_t fn_ref,
+ time_spec_t time_diff_hint)
+ {
+ int frames_diff, fn_delta;
+ frames_diff = int(round(time_diff_hint.get_real_secs() / GSM_FN_PERIOD));
+ fn_delta = fnmod_delta(fn, fn_ref + frames_diff) + frames_diff;
+
+ return fn_delta;
+ }
+
+ /**
+ * Computes difference between reference frame number
+ * and a second frame number.
+ * @param fn_ref reference frame number modulo GSM_HYPER_FRAME
+ * @param fn second frame number modulo GSM_HYPER_FRAME
+ * @param time_ref precise timestamp of the first sample in the fn_ref
+ * @param time_hint coarse time for fn that is used as a hint to avoid
+ * ambiguities caused by modulo operation applied to
+ * frame numbers
+ * @return difference between fn_ref and fn
+ */
+ time_format fn_time_delta_cpp(uint32_t fn_ref, time_format time_ref, uint32_t fn_x,
+ time_format time_hint, uint32_t ts_num, uint32_t ts_ref)
+ {
+ time_spec_t time_diff_hint = time_spec_t(time_hint.first, time_hint.second) - time_spec_t(time_ref.first, time_ref.second);
+ int fn_delta = fn_time_diff_delta(fn_x, fn_ref, time_diff_hint);
+ time_spec_t time_x_precise = fn_delta * GSM_FN_PERIOD + time_spec_t(time_ref.first, time_ref.second) + (static_cast<int>(ts_num) - static_cast<int>(ts_ref)) * GSM_TS_PERIOD;
+
+ return time_format(time_x_precise.get_full_secs(), time_x_precise.get_frac_secs());
+ }
+
+ } /* namespace gsm */
+} /* namespace gr */
+
diff --git a/lib/misc_utils/msg_to_tag_impl.cc b/lib/misc_utils/msg_to_tag_impl.cc
index 0ab65e7..e08c7e6 100644
--- a/lib/misc_utils/msg_to_tag_impl.cc
+++ b/lib/misc_utils/msg_to_tag_impl.cc
@@ -94,6 +94,6 @@ namespace gr {
return noutput_items;
}
- } /* namespace grgsm */
+ } /* namespace gsm */
} /* namespace gr */
diff --git a/lib/misc_utils/msg_to_tag_impl.h b/lib/misc_utils/msg_to_tag_impl.h
index 39c6ca3..55e1fae 100644
--- a/lib/misc_utils/msg_to_tag_impl.h
+++ b/lib/misc_utils/msg_to_tag_impl.h
@@ -44,7 +44,7 @@ namespace gr {
gr_vector_void_star &output_items);
};
- } // namespace grgsm
+ } // namespace gsm
} // namespace gr
#endif /* INCLUDED_GRGSM_MSG_TO_TAG_IMPL_H */
diff --git a/lib/misc_utils/time_spec.cc b/lib/misc_utils/time_spec.cc
new file mode 100644
index 0000000..5293da2
--- /dev/null
+++ b/lib/misc_utils/time_spec.cc
@@ -0,0 +1,122 @@
+//
+// Copyright 2011-2013 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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 program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include <grgsm/misc_utils/time_spec.h>
+
+namespace gr {
+ namespace gsm {
+
+ /***********************************************************************
+ * Time spec constructors
+ **********************************************************************/
+ #define time_spec_init(full, frac) { \
+ const time_t _full = time_t(full); \
+ const double _frac = double(frac); \
+ const int _frac_int = int(_frac); \
+ _full_secs = _full + _frac_int; \
+ _frac_secs = _frac - _frac_int; \
+ if (_frac_secs < 0) {\
+ _full_secs -= 1; \
+ _frac_secs += 1; \
+ } \
+ }
+
+ inline long long fast_llround(const double x){
+ return (long long)(x + 0.5); // assumption of non-negativity
+ }
+
+ time_spec_t::time_spec_t(const time_spec_t & spec){
+ time_spec_init(spec.get_full_secs(), spec.get_frac_secs());
+ }
+
+ time_spec_t::time_spec_t(double secs){
+ time_spec_init(0, secs);
+ }
+
+ time_spec_t::time_spec_t(time_t full_secs, double frac_secs){
+ time_spec_init(full_secs, frac_secs);
+ }
+
+ time_spec_t::time_spec_t(time_t full_secs, long tick_count, double tick_rate){
+ const double frac_secs = tick_count/tick_rate;
+ time_spec_init(full_secs, frac_secs);
+ }
+
+ time_spec_t time_spec_t::from_ticks(long long ticks, double tick_rate){
+ const long long rate_i = (long long)(tick_rate);
+ const double rate_f = tick_rate - rate_i;
+ const time_t secs_full = time_t(ticks/rate_i);
+ const long long ticks_error = ticks - (secs_full*rate_i);
+ const double ticks_frac = ticks_error - secs_full*rate_f;
+ return time_spec_t(secs_full, ticks_frac/tick_rate);
+ }
+
+ /***********************************************************************
+ * Time spec accessors
+ **********************************************************************/
+ long time_spec_t::get_tick_count(double tick_rate) const{
+ return long(fast_llround(this->get_frac_secs()*tick_rate));
+ }
+
+ long long time_spec_t::to_ticks(double tick_rate) const{
+ const long long rate_i = (long long)(tick_rate);
+ const double rate_f = tick_rate - rate_i;
+ const long long ticks_full = this->get_full_secs()*rate_i;
+ const double ticks_error = this->get_full_secs()*rate_f;
+ const double ticks_frac = this->get_frac_secs()*tick_rate;
+ return ticks_full + fast_llround(ticks_error + ticks_frac);
+ }
+
+ double time_spec_t::get_real_secs(void) const{
+ return this->get_full_secs() + this->get_frac_secs();
+ }
+
+ /***********************************************************************
+ * Time spec math overloads
+ **********************************************************************/
+ time_spec_t &time_spec_t::operator+=(const time_spec_t &rhs){
+ time_spec_init(
+ this->get_full_secs() + rhs.get_full_secs(),
+ this->get_frac_secs() + rhs.get_frac_secs()
+ );
+ return *this;
+ }
+
+ time_spec_t &time_spec_t::operator-=(const time_spec_t &rhs){
+ time_spec_init(
+ this->get_full_secs() - rhs.get_full_secs(),
+ this->get_frac_secs() - rhs.get_frac_secs()
+ );
+ return *this;
+ }
+
+ bool operator==(const time_spec_t &lhs, const time_spec_t &rhs){
+ return
+ lhs.get_full_secs() == rhs.get_full_secs() and
+ lhs.get_frac_secs() == rhs.get_frac_secs()
+ ;
+ }
+
+ bool operator<(const time_spec_t &lhs, const time_spec_t &rhs){
+ return (
+ (lhs.get_full_secs() < rhs.get_full_secs()) or (
+ (lhs.get_full_secs() == rhs.get_full_secs()) and
+ (lhs.get_frac_secs() < rhs.get_frac_secs())
+ ));
+ }
+ }
+}
diff --git a/lib/misc_utils/trx_burst_if_impl.cc b/lib/misc_utils/trx_burst_if_impl.cc
new file mode 100644
index 0000000..8f458b0
--- /dev/null
+++ b/lib/misc_utils/trx_burst_if_impl.cc
@@ -0,0 +1,231 @@
+/* -*- c++ -*- */
+/* @file
+ * @author Vadim Yanitskiy <axilirator@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 <boost/lexical_cast.hpp>
+
+#include "udp_socket.h"
+#include "trx_burst_if_impl.h"
+
+#define BURST_SIZE 148
+#define DATA_IF_MTU 160
+
+/**
+ * 41-bit RACH synchronization sequence
+ * GSM 05.02 Chapter 5.2.7 Access burst (AB)
+ */
+static uint8_t rach_synch_seq[] = {
+ 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0,
+ 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0,
+};
+
+namespace gr {
+ namespace gsm {
+
+ trx_burst_if::sptr
+ trx_burst_if::make(
+ const std::string &remote_addr,
+ const std::string &base_port)
+ {
+ int base_port_int = boost::lexical_cast<int> (base_port);
+
+ return gnuradio::get_initial_sptr
+ (new trx_burst_if_impl(remote_addr, base_port_int));
+ }
+
+ /*
+ * The private constructor
+ */
+ trx_burst_if_impl::trx_burst_if_impl(
+ const std::string &remote_addr,
+ int base_port
+ ) : gr::block("trx_burst_if",
+ gr::io_signature::make(0, 0, 0),
+ gr::io_signature::make(0, 0, 0))
+ {
+ message_port_register_in(pmt::mp("bursts"));
+ message_port_register_out(pmt::mp("bursts"));
+
+ // Bind a port handler
+ set_msg_handler(pmt::mp("bursts"),
+ boost::bind(&trx_burst_if_impl::handle_dl_burst, this, _1));
+
+ // Prepare port numbers
+ std::string data_src_port = boost::lexical_cast<std::string> (base_port + 2);
+ std::string data_dst_port = boost::lexical_cast<std::string> (base_port + 102);
+
+ // Init DATA interface
+ d_data_sock = new udp_socket(remote_addr,
+ data_src_port, data_dst_port, DATA_IF_MTU);
+
+ // Bind DATA interface handler
+ d_data_sock->udp_rx_handler = boost::bind(
+ &trx_burst_if_impl::handle_ul_burst, this, _1, _2);
+ }
+
+ /*
+ * Our virtual destructor.
+ */
+ trx_burst_if_impl::~trx_burst_if_impl()
+ {
+ // Release all UDP sockets and free memory
+ delete d_data_sock;
+ }
+
+ /*
+ * Check if burst is a RACH burst
+ */
+ bool trx_burst_if_impl::detect_rach(uint8_t *burst)
+ {
+ // Compare synchronization sequence
+ for (int i = 0; i < 41; i++)
+ if (burst[i + 8] != rach_synch_seq[i])
+ return false;
+
+ // Make sure TB and GP are filled by 0x00
+ for (int i = 0; i < 63; i++)
+ if (burst[i + 85] != 0x00)
+ return false;
+
+ return true;
+ }
+
+ /*
+ * Create an UDP payload with burst bits
+ * and some channel data.
+ */
+ void
+ trx_burst_if_impl::burst_pack(pmt::pmt_t msg, uint8_t *buf)
+ {
+ pmt::pmt_t header_plus_burst = pmt::cdr(msg);
+
+ // Extract GSMTAP header from message
+ gsmtap_hdr *header = (gsmtap_hdr *)
+ pmt::blob_data(header_plus_burst);
+
+ // Pack timeslot index
+ buf[0] = header->timeslot;
+
+ // Extract frame number
+ uint32_t frame_nr = be32toh(header->frame_number);
+
+ // Pack frame number
+ buf[1] = (frame_nr >> 24) & 0xff;
+ buf[2] = (frame_nr >> 16) & 0xff;
+ buf[3] = (frame_nr >> 8) & 0xff;
+ buf[4] = (frame_nr >> 0) & 0xff;
+
+ // Pack RSSI (-dBm)
+ buf[5] = -(uint8_t) header->signal_dbm;
+
+ // Pack correlator timing offset (TOA)
+ // FIXME: where to find this value?
+ buf[6] = 0;
+ buf[7] = 0;
+
+ // Extract bits {0..1} from message
+ // Despite GR-GSM uses int8_t, they are not real sbits {-127..127}
+ uint8_t *burst = (uint8_t *)
+ (pmt::blob_data(header_plus_burst)) + sizeof(gsmtap_hdr);
+
+ // Convert to transceiver interface specific bits {255..0}
+ for (int i = 0; i < 148; i++)
+ buf[8 + i] = burst[i] ? 255 : 0;
+
+ // Fill two unused bytes
+ buf[156] = 0x00;
+ buf[157] = 0x00;
+ }
+
+ void
+ trx_burst_if_impl::handle_dl_burst(pmt::pmt_t msg)
+ {
+ // 8 bytes of header + 148 bytes of burst
+ // + two unused, but required bytes
+ // otherwise bursts would be rejected
+ uint8_t buf[158];
+
+ // Compose a new UDP payload with burst
+ burst_pack(msg, buf);
+
+ // Send a burst
+ d_data_sock->udp_send(buf, 158);
+ }
+
+ void
+ trx_burst_if_impl::handle_ul_burst(uint8_t *payload, size_t len)
+ {
+ // Check length according to the protocol
+ if (len != 154)
+ return;
+
+ /* Make sure TS index is correct */
+ if (payload[0] >= 8)
+ return;
+
+ /* Unpack and check frame number */
+ uint32_t fn = (payload[1] << 24)
+ | (payload[2] << 16)
+ | (payload[3] << 8)
+ | payload[4];
+
+ if (fn >= 2715648)
+ return;
+
+ // Prepare a buffer for GSMTAP header and burst
+ uint8_t buf[sizeof(gsmtap_hdr) + BURST_SIZE];
+
+ // Set up pointer to GSMTAP header structure
+ struct gsmtap_hdr *header = (struct gsmtap_hdr *) buf;
+ memset(header, 0x00, sizeof(struct gsmtap_hdr));
+
+ // Fill in basic info
+ header->version = GSMTAP_VERSION;
+ header->hdr_len = sizeof(gsmtap_hdr) / 4;
+ header->type = GSMTAP_TYPE_UM_BURST;
+
+ // Set timeslot index and frame number
+ header->timeslot = payload[0];
+ header->frame_number = htobe32(fn);
+
+ // Check if one is a RACH burst
+ header->sub_type = detect_rach(payload + 6) ?
+ GSMTAP_BURST_ACCESS : GSMTAP_BURST_NORMAL;
+
+ // Copy burst bits (0 & 1) for source message
+ memcpy(buf + sizeof(gsmtap_hdr), payload + 6, BURST_SIZE);
+
+ // Create a pmt blob
+ pmt::pmt_t blob = pmt::make_blob(buf, sizeof(gsmtap_hdr) + BURST_SIZE);
+ pmt::pmt_t msg = pmt::cons(pmt::PMT_NIL, blob);
+
+ /* Send a message to the output */
+ message_port_pub(pmt::mp("bursts"), msg);
+ }
+
+ } /* namespace gsm */
+} /* namespace gr */
diff --git a/lib/misc_utils/trx_burst_if_impl.h b/lib/misc_utils/trx_burst_if_impl.h
new file mode 100644
index 0000000..35f939c
--- /dev/null
+++ b/lib/misc_utils/trx_burst_if_impl.h
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/* @file
+ * @author Vadim Yanitskiy <axilirator@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_GRGSM_TRX_BURST_IF_IMPL_H
+#define INCLUDED_GRGSM_TRX_BURST_IF_IMPL_H
+
+#include <stddef.h>
+
+#include <grgsm/gsmtap.h>
+#include <grgsm/misc_utils/trx_burst_if.h>
+
+namespace gr {
+ namespace gsm {
+
+ class trx_burst_if_impl : public trx_burst_if
+ {
+ private:
+ udp_socket *d_data_sock;
+
+ bool detect_rach(uint8_t *burst);
+ void burst_pack(pmt::pmt_t msg, uint8_t *buf);
+
+ public:
+ trx_burst_if_impl(const std::string &remote_addr, int base_port);
+ ~trx_burst_if_impl();
+
+ void handle_dl_burst(pmt::pmt_t msg);
+ void handle_ul_burst(uint8_t *payload, size_t len);
+ };
+
+ } // namespace gsm
+} // namespace gr
+
+#endif /* INCLUDED_GRGSM_TRX_BURST_IF_IMPL_H */
+
diff --git a/lib/misc_utils/udp_socket.cc b/lib/misc_utils/udp_socket.cc
new file mode 100644
index 0000000..5c689c7
--- /dev/null
+++ b/lib/misc_utils/udp_socket.cc
@@ -0,0 +1,119 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2013 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/thread/thread.h>
+#include <gnuradio/io_signature.h>
+#include <gnuradio/blocks/pdu.h>
+#include <pmt/pmt.h>
+
+#include <boost/lexical_cast.hpp>
+#include "udp_socket.h"
+
+using boost::asio::ip::udp;
+
+namespace gr {
+ namespace gsm {
+
+ udp_socket::udp_socket(
+ const std::string &remote_addr,
+ const std::string &src_port,
+ const std::string &dst_port,
+ size_t mtu)
+ {
+ // Resize receive buffer according to MTU value
+ d_rxbuf.resize(mtu);
+
+ // Resolve remote host address
+ udp::resolver resolver(d_io_service);
+
+ udp::resolver::query rx_query(
+ udp::v4(), remote_addr, src_port,
+ boost::asio::ip::resolver_query_base::passive);
+ udp::resolver::query tx_query(
+ udp::v4(), remote_addr, dst_port,
+ boost::asio::ip::resolver_query_base::passive);
+
+ d_udp_endpoint_rx = *resolver.resolve(rx_query);
+ d_udp_endpoint_tx = *resolver.resolve(tx_query);
+
+ // Create a socket
+ d_udp_socket.reset(new udp::socket(d_io_service, d_udp_endpoint_rx));
+
+ // Setup read handler
+ d_udp_socket->async_receive_from(
+ boost::asio::buffer(d_rxbuf), d_udp_endpoint_rx,
+ boost::bind(&udp_socket::handle_udp_read, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred));
+
+ // Start server
+ d_thread = gr::thread::thread(
+ boost::bind(&udp_socket::run_io_service, this));
+ }
+
+ udp_socket::~udp_socket()
+ {
+ // Stop server
+ d_io_service.stop();
+ d_thread.interrupt();
+ d_thread.join();
+ }
+
+ void
+ udp_socket::run_io_service(void)
+ {
+ d_io_service.run();
+ }
+
+ void
+ udp_socket::udp_send(uint8_t *data, size_t len)
+ {
+ d_udp_socket->send_to(
+ boost::asio::buffer(data, len),
+ d_udp_endpoint_tx);
+ }
+
+ void
+ udp_socket::handle_udp_read(
+ const boost::system::error_code& error,
+ size_t bytes_transferred)
+ {
+ if (error)
+ return;
+
+ // Call incoming data handler
+ if (udp_rx_handler != NULL)
+ udp_rx_handler((uint8_t *) &d_rxbuf[0], bytes_transferred);
+
+ d_udp_socket->async_receive_from(
+ boost::asio::buffer(d_rxbuf), d_udp_endpoint_rx,
+ boost::bind(&udp_socket::handle_udp_read, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred));
+ }
+
+ } /* namespace gsm */
+}/* namespace gr */
diff --git a/lib/misc_utils/udp_socket.h b/lib/misc_utils/udp_socket.h
new file mode 100644
index 0000000..15b2c66
--- /dev/null
+++ b/lib/misc_utils/udp_socket.h
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2013 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.
+ */
+
+#ifndef INCLUDED_GRGSM_TRX_UDP_SOCKET_H
+#define INCLUDED_GRGSM_TRX_UDP_SOCKET_H
+
+#include <gnuradio/thread/thread.h>
+
+#include <boost/function.hpp>
+#include <boost/array.hpp>
+#include <boost/asio.hpp>
+#include <boost/bind.hpp>
+#include <pmt/pmt.h>
+
+namespace gr {
+ namespace gsm {
+
+ class udp_socket
+ {
+ private:
+ boost::asio::io_service d_io_service;
+ std::vector<char> d_rxbuf;
+ gr::thread::thread d_thread;
+ bool d_started;
+ bool d_finished;
+
+ boost::asio::ip::udp::endpoint d_udp_endpoint_rx;
+ boost::asio::ip::udp::endpoint d_udp_endpoint_tx;
+ boost::shared_ptr<boost::asio::ip::udp::socket> d_udp_socket;
+
+ void handle_udp_read(const boost::system::error_code& error,
+ size_t bytes_transferred);
+ void run_io_service(void);
+
+ public:
+ udp_socket(
+ const std::string &remote_addr,
+ const std::string &src_port,
+ const std::string &dst_port,
+ size_t mtu);
+ ~udp_socket();
+
+ void udp_send(uint8_t *data, size_t len);
+ boost::function<void (uint8_t *, size_t)> udp_rx_handler;
+ };
+
+ } /* namespace gsm */
+} /* namespace gr */
+
+#endif /* INCLUDED_GRGSM_TRX_UDP_SOCKET_H */
diff --git a/lib/qa_utils/burst_sink_impl.cc b/lib/qa_utils/burst_sink_impl.cc
index 102c5be..bdc2192 100644
--- a/lib/qa_utils/burst_sink_impl.cc
+++ b/lib/qa_utils/burst_sink_impl.cc
@@ -47,7 +47,8 @@ namespace gr {
burst_sink_impl::burst_sink_impl()
: gr::block("burst_sink",
gr::io_signature::make(0, 0, 0),
- gr::io_signature::make(0, 0, 0))
+ gr::io_signature::make(0, 0, 0)),
+ d_bursts(pmt::PMT_NIL)
{
message_port_register_in(pmt::mp("in"));
set_msg_handler(pmt::mp("in"), boost::bind(&burst_sink_impl::process_burst, this, _1));
@@ -105,7 +106,10 @@ namespace gr {
{
return d_burst_data;
}
-
+ pmt::pmt_t burst_sink_impl::get_bursts()
+ {
+ return d_bursts;
+ }
} /* namespace gsm */
} /* namespace gr */
diff --git a/lib/qa_utils/burst_sink_impl.h b/lib/qa_utils/burst_sink_impl.h
index 1035430..e87422d 100644
--- a/lib/qa_utils/burst_sink_impl.h
+++ b/lib/qa_utils/burst_sink_impl.h
@@ -35,6 +35,7 @@ namespace gr {
std::vector<int> d_framenumbers;
std::vector<int> d_timeslots;
std::vector<std::string> d_burst_data;
+ pmt::pmt_t d_bursts;
public:
burst_sink_impl();
~burst_sink_impl();
@@ -42,6 +43,7 @@ namespace gr {
virtual std::vector<int> get_framenumbers();
virtual std::vector<int> get_timeslots();
virtual std::vector<std::string> get_burst_data();
+ virtual pmt::pmt_t get_bursts();
};
} // namespace gsm
diff --git a/lib/receiver/CMakeLists.txt b/lib/receiver/CMakeLists.txt
index 343d2f8..123eba5 100644
--- a/lib/receiver/CMakeLists.txt
+++ b/lib/receiver/CMakeLists.txt
@@ -23,4 +23,5 @@ add_sources(
receiver_config.cc
receiver_impl.cc
viterbi_detector.cc
+ time_sample_ref.cc
)
diff --git a/lib/receiver/clock_offset_control_impl.cc b/lib/receiver/clock_offset_control_impl.cc
index 868cbc2..d62c801 100644
--- a/lib/receiver/clock_offset_control_impl.cc
+++ b/lib/receiver/clock_offset_control_impl.cc
@@ -25,7 +25,7 @@
#endif
#include <sch.h>
-#include <gsm_constants.h>
+#include <grgsm/gsm_constants.h>
#include "clock_offset_control_impl.h"
namespace gr
diff --git a/lib/receiver/gsm_constants.h b/lib/receiver/gsm_constants.h
deleted file mode 100644
index 9052290..0000000
--- a/lib/receiver/gsm_constants.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/* -*- c++ -*- */
-/*
- * @file
- * @author (C) 2014 by 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_CONSTANTS_H
-#define INCLUDED_GSM_CONSTANTS_H
-
-#define GSM_SYMBOL_RATE (1625000.0/6.0) //symbols per second
-#define GSM_SYMBOL_PERIOD (1.0/GSM_SYMBOL_RATE) //seconds per symbol
-
-//Burst timing
-#define TAIL_BITS 3
-#define GUARD_BITS 8
-#define GUARD_FRACTIONAL 0.25 //fractional part of guard period
-#define GUARD_PERIOD GUARD_BITS + GUARD_FRACTIONAL
-#define DATA_BITS 57 //size of 1 data block in normal burst
-#define STEALING_BIT 1
-#define N_TRAIN_BITS 26
-#define N_SYNC_BITS 64
-#define USEFUL_BITS 142 //(2*(DATA_BITS+STEALING_BIT) + N_TRAIN_BITS )
-#define FCCH_BITS USEFUL_BITS
-#define BURST_SIZE (USEFUL_BITS+2*TAIL_BITS)
-#define PROCESSED_CHUNK BURST_SIZE+2*GUARD_PERIOD
-
-#define SCH_DATA_LEN 39
-#define TS_BITS (TAIL_BITS+USEFUL_BITS+TAIL_BITS+GUARD_BITS) //a full TS (156 bits)
-#define TS_PER_FRAME 8
-#define FRAME_BITS (TS_PER_FRAME * TS_BITS + 2) // 156.25 * 8
-#define FCCH_POS TAIL_BITS
-#define SYNC_POS 39
-#define TRAIN_POS ( TAIL_BITS + (DATA_BITS+STEALING_BIT) + 5) //first 5 bits of a training sequence
- //aren't used for channel impulse response estimation
-#define TRAIN_BEGINNING 5
-#define SAFETY_MARGIN 6 //
-
-#define FCCH_HITS_NEEDED (USEFUL_BITS - 4)
-#define FCCH_MAX_MISSES 1
-#define FCCH_MAX_FREQ_OFFSET 100
-
-#define CHAN_IMP_RESP_LENGTH 5
-
-#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, normal_or_noise} burst_type;
-typedef enum {unknown, multiframe_26, multiframe_51} multiframe_type;
-
-static const unsigned char SYNC_BITS[] = {
- 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1,
- 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1
-};
-
-const unsigned FCCH_FRAMES[] = {0, 10, 20, 30, 40};
-const unsigned SCH_FRAMES[] = {1, 11, 21, 31, 41};
-
-const unsigned BCCH_FRAMES[] = {2, 3, 4, 5}; //!!the receiver shouldn't care about logical
- //!!channels so this will be removed from this header
-const unsigned TEST_CCH_FRAMES[] = {2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 16, 17, 18, 19, 22, 23, 24, 25, 26, 27, 28, 29, 32, 33, 34, 35, 36, 37, 38, 39, 42, 43, 44, 45, 46, 47, 48, 49};
-const unsigned TRAFFIC_CHANNEL_F[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24};
-const unsigned TEST51[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50};
-
-
-#define TSC0 0
-#define TSC1 1
-#define TSC2 2
-#define TSC3 3
-#define TSC4 4
-#define TSC5 5
-#define TSC6 6
-#define TSC7 7
-#define TS_DUMMY 8
-
-#define TRAIN_SEQ_NUM 9
-
-#define TIMESLOT0 0
-#define TIMESLOT1 1
-#define TIMESLOT2 2
-#define TIMESLOT3 3
-#define TIMESLOT4 4
-#define TIMESLOT5 5
-#define TIMESLOT6 6
-#define TIMESLOT7 7
-
-
-static const unsigned char train_seq[TRAIN_SEQ_NUM][N_TRAIN_BITS] = {
- {0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1},
- {0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1},
- {0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0},
- {0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0},
- {0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1},
- {0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0},
- {1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1},
- {1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0},
- {0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1} // DUMMY
-};
-
-
-//Dummy burst 0xFB 76 0A 4E 09 10 1F 1C 5C 5C 57 4A 33 39 E9 F1 2F A8
-static const unsigned char dummy_burst[] = {
- 0, 0, 0,
- 1, 1, 1, 1, 1, 0, 1, 1, 0, 1,
- 1, 1, 0, 1, 1, 0, 0, 0, 0, 0,
- 1, 0, 1, 0, 0, 1, 0, 0, 1, 1,
- 1, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
- 0, 1, 1, 1, 1, 1, 0, 0,
-
- 0, 1, 1, 1, 0, 0, 0, 1, 0, 1,
- 1, 1, 0, 0, 0, 1, 0, 1, 1, 1,
- 0, 0, 0, 1, 0, 1,
-
- 0, 1, 1, 1, 0, 1, 0, 0, 1, 0,
- 1, 0, 0, 0, 1, 1, 0, 0, 1, 1,
- 0, 0, 1, 1, 1, 0, 0, 1, 1, 1,
- 1, 0, 1, 0, 0, 1, 1, 1, 1, 1,
- 0, 0, 0, 1, 0, 0, 1, 0, 1, 1,
- 1, 1, 1, 0, 1, 0, 1, 0,
- 0, 0, 0
-};
-
-
-/*
- * The frequency correction burst is used for frequency synchronization
- * of the mobile. This is broadcast in TS0 together with the SCH and
- * BCCH.
- *
- * Modulating the bits below causes a spike at 62.5kHz above (below for
- * COMPACT) the center frequency. One can use this spike with a narrow
- * band filter to accurately determine the center of the channel.
- */
-static const unsigned char fc_fb[] = {
- 0, 0, 0, //I don't use this tables,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //I copied this here from burst_types.h because
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //the description is very informative - p.krysik
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0
-};
-
-static const unsigned char fc_compact_fb[] = {
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0
-};
-
-
-#endif /* INCLUDED_GSM_CONSTANTS_H */
diff --git a/lib/receiver/receiver_config.h b/lib/receiver/receiver_config.h
index 6ad43a1..b3c0f49 100644
--- a/lib/receiver/receiver_config.h
+++ b/lib/receiver/receiver_config.h
@@ -25,7 +25,7 @@
#include <vector>
#include <algorithm>
#include <stdint.h>
-#include <gsm_constants.h>
+#include <grgsm/gsm_constants.h>
class multiframe_configuration
{
diff --git a/lib/receiver/receiver_impl.cc b/lib/receiver/receiver_impl.cc
index c7626b5..ffaf9ee 100644
--- a/lib/receiver/receiver_impl.cc
+++ b/lib/receiver/receiver_impl.cc
@@ -73,10 +73,13 @@ namespace gr
) : gr::sync_block("receiver",
gr::io_signature::make(1, -1, sizeof(gr_complex)),
gr::io_signature::make(0, 0, 0)),
+ d_samples_consumed(0),
+ d_rx_time_received(false),
+ d_time_samp_ref(GSM_SYMBOL_RATE * osr),
d_OSR(osr),
d_process_uplink(process_uplink),
d_chan_imp_length(CHAN_IMP_RESP_LENGTH),
- d_counter(0),
+ d_counter(0), //TODO: use nitems_read instead of d_counter
d_fcch_start_pos(0),
d_freq_offset_setting(0),
d_state(fcch_search),
@@ -174,8 +177,13 @@ namespace gr
d_freq_offset_tag_in_fcch = tag_offset < last_sample_nr;
}
}
+
+ /* Obtaining current time with use of rx_time tag provided i.e. by UHD devices */
+ /* And storing it in time_sample_ref for sample number to time conversion */
+ std::vector<tag_t> rx_time_tags;
/* Main state machine */
+ d_samples_consumed = 0;
switch (d_state) {
case fcch_search:
fcch_search_handler(input, noutput_items);
@@ -188,7 +196,20 @@ namespace gr
break;
}
- return 0;
+ get_tags_in_window(rx_time_tags, 0, 0, d_samples_consumed, pmt::string_to_symbol("rx_time"));
+ if(!rx_time_tags.empty()){
+ d_rx_time_received = true;
+ tag_t rx_time_tag = *(rx_time_tags.begin());
+
+ uint64_t rx_time_full_part = to_uint64(tuple_ref(rx_time_tag.value,0));
+ double rx_time_frac_part = to_double(tuple_ref(rx_time_tag.value,1));
+
+ time_spec_t current_rx_time = time_spec_t(rx_time_full_part, rx_time_frac_part);
+ uint64_t current_start_offset = rx_time_tag.offset;
+ d_time_samp_ref.update(current_rx_time, current_start_offset);
+ }
+
+ return d_samples_consumed;
}
void
@@ -248,7 +269,9 @@ namespace gr
d_burst_nr++;
/* Consume samples up to the next guard period */
- consume_each(burst_start + BURST_SIZE * d_OSR + 4 * d_OSR);
+ unsigned int to_consume = burst_start + BURST_SIZE * d_OSR + 4 * d_OSR;
+// consume_each(to_consume);
+ d_samples_consumed += to_consume;
/* Update current state */
d_state = synchronized;
@@ -320,7 +343,7 @@ namespace gr
case sch_burst:
{
- int d_ncc, d_bcc;
+ int ncc, bcc;
int t1, t2, t3;
int rc;
@@ -332,12 +355,8 @@ namespace gr
detect_burst(input, &channel_imp_resp[0],
d_c0_burst_start, output_binary);
- /* Compose a message with GSMTAP header and bits */
- send_burst(d_burst_nr, output_binary,
- GSMTAP_BURST_SCH, input_nr);
-
/* Attempt to decode SCH burst */
- rc = decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc);
+ rc = decode_sch(&output_binary[3], &t1, &t2, &t3, &ncc, &bcc);
if (rc) {
if (++d_failed_sch >= MAX_SCH_ERRORS) {
/* We have to resynchronize, change state */
@@ -352,6 +371,10 @@ namespace gr
break;
}
+ /* Compose a message with GSMTAP header and bits */
+ send_burst(d_burst_nr, output_binary,
+ GSMTAP_BURST_SCH, input_nr, d_c0_burst_start);
+
/**
* Decoding was successful, now
* compute offset from burst_start,
@@ -380,7 +403,7 @@ namespace gr
/* Compose a message with GSMTAP header and bits */
send_burst(d_burst_nr, output_binary,
- GSMTAP_BURST_NORMAL, input_nr);
+ GSMTAP_BURST_NORMAL, input_nr, d_c0_burst_start);
break;
}
@@ -404,13 +427,13 @@ namespace gr
/* Compose a message with GSMTAP header and bits */
send_burst(d_burst_nr, output_binary,
- GSMTAP_BURST_NORMAL, input_nr);
+ GSMTAP_BURST_NORMAL, input_nr, normal_burst_start);
} else {
d_c0_burst_start = dummy_burst_start;
/* Compose a message with GSMTAP header and bits */
send_burst(d_burst_nr, dummy_burst,
- GSMTAP_BURST_DUMMY, input_nr);
+ GSMTAP_BURST_DUMMY, input_nr, dummy_burst_start);
}
break;
@@ -462,7 +485,7 @@ namespace gr
burst_start, output_binary);
/* Compose a message with GSMTAP header and bits */
- send_burst(d_burst_nr, output_binary, GSMTAP_BURST_NORMAL, input_nr);
+ send_burst(d_burst_nr, output_binary, GSMTAP_BURST_NORMAL, input_nr, burst_start);
break;
}
@@ -483,7 +506,8 @@ namespace gr
/* Consume samples of the burst up to next guard period */
to_consume += TS_BITS * d_OSR + d_burst_nr.get_offset();
- consume_each(to_consume);
+// consume_each(to_consume);
+ d_samples_consumed += to_consume;
}
}
}
@@ -674,7 +698,8 @@ namespace gr
}
d_counter += to_consume;
- consume_each(to_consume);
+// consume_each(to_consume);
+ d_samples_consumed += to_consume;
return result;
}
@@ -725,7 +750,8 @@ namespace gr
}
d_counter += to_consume;
- consume_each(to_consume);
+// consume_each(to_consume);
+ d_samples_consumed += to_consume;
return result;
}
@@ -979,7 +1005,7 @@ namespace gr
void
receiver_impl::send_burst(burst_counter burst_nr,
const unsigned char * burst_binary, uint8_t burst_type,
- size_t input_nr)
+ size_t input_nr, unsigned int burst_start)
{
/* Buffer for GSMTAP header and burst */
uint8_t buf[sizeof(gsmtap_hdr) + BURST_SIZE];
@@ -1018,12 +1044,26 @@ namespace gr
tap_header->signal_dbm = static_cast<int8_t>(d_signal_dbm);
tap_header->snr_db = 0; /* FIXME: Can we calculate this? */
+ pmt::pmt_t pdu_header = pmt::make_dict();
+
+ /* Add timestamp of the first sample - if available */
+ if(d_rx_time_received) {
+ time_spec_t time_spec_of_first_sample = d_time_samp_ref.offset_to_time(nitems_read(0)+burst_start);
+ uint64_t full = time_spec_of_first_sample.get_full_secs();
+ double frac = time_spec_of_first_sample.get_frac_secs();
+ pdu_header =
+ pmt::dict_add(pdu_header, pmt::mp("fn_time"),
+ pmt::cons(
+ pmt::cons(pmt::from_uint64(be32toh(frame_number)), pmt::from_uint64(tn)),
+ pmt::cons(pmt::from_uint64(full), pmt::from_double(frac))));
+ }
+
/* Copy burst to the buffer */
memcpy(burst, burst_binary, BURST_SIZE);
/* Allocate a new message */
pmt::pmt_t blob = pmt::make_blob(buf, sizeof(gsmtap_hdr) + BURST_SIZE);
- pmt::pmt_t msg = pmt::cons(pmt::PMT_NIL, blob);
+ pmt::pmt_t msg = pmt::cons(pdu_header, blob);
/* Send message */
if (input_nr == 0)
@@ -1092,6 +1132,5 @@ namespace gr
{
d_state = fcch_search;
}
-
} /* namespace gsm */
} /* namespace gr */
diff --git a/lib/receiver/receiver_impl.h b/lib/receiver/receiver_impl.h
index 0b032db..b880837 100644
--- a/lib/receiver/receiver_impl.h
+++ b/lib/receiver/receiver_impl.h
@@ -25,16 +25,20 @@
#include <grgsm/receiver/receiver.h>
#include <grgsm/gsmtap.h>
-#include <gsm_constants.h>
+#include <grgsm/gsm_constants.h>
#include <receiver_config.h>
#include <vector>
+#include "time_sample_ref.h"
namespace gr {
namespace gsm {
class receiver_impl : public receiver
{
private:
- unsigned int d_c0_burst_start;
+ unsigned int d_samples_consumed;
+ bool d_rx_time_received;
+ time_sample_ref d_time_samp_ref;
+ int d_c0_burst_start;
float d_c0_signal_dbm;
/**@name Configuration of the receiver */
@@ -195,7 +199,7 @@ namespace gr {
* @param burst_binary - content of the burst
* @b_type - type of the burst
*/
- void send_burst(burst_counter burst_nr, const unsigned char * burst_binary, uint8_t burst_type, size_t input_nr);
+ void send_burst(burst_counter burst_nr, const unsigned char * burst_binary, uint8_t burst_type, size_t input_nr, unsigned int burst_start=-1);
/**
* Configures burst types in different channels
@@ -209,13 +213,13 @@ namespace gr {
gr_vector_const_void_star &input_items, int noutput_items);
public:
- receiver_impl(int osr, const std::vector<int> &cell_allocation, const std::vector<int> &tseq_nums, bool process_uplink);
- ~receiver_impl();
+ receiver_impl(int osr, const std::vector<int> &cell_allocation, const std::vector<int> &tseq_nums, bool process_uplink);
+ ~receiver_impl();
- int work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items);
- 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();
+ int work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items);
+ 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();
};
} // namespace gsm
} // namespace gr
diff --git a/lib/receiver/time_sample_ref.cc b/lib/receiver/time_sample_ref.cc
new file mode 100644
index 0000000..0cf85ed
--- /dev/null
+++ b/lib/receiver/time_sample_ref.cc
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * @file
+ * @author (C) 2017 by 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.
+ */
+
+#include <math.h>
+#include "time_sample_ref.h"
+
+namespace gr {
+ namespace gsm {
+ time_sample_ref::time_sample_ref(double samp_rate): d_samp_rate(samp_rate)
+ {
+ }
+
+ time_sample_ref::~time_sample_ref()
+ {
+ }
+
+ void time_sample_ref::update(time_spec_t last_rx_time, uint64_t current_start_offset)
+ {
+ d_last_rx_time = last_rx_time;
+ d_current_start_offset = current_start_offset;
+ }
+
+ time_spec_t time_sample_ref::offset_to_time(uint64_t offset)
+ {
+ uint64_t samples_from_last_rx_time = offset - d_current_start_offset;
+ time_spec_t time = time_spec_t(static_cast<double>(samples_from_last_rx_time)/d_samp_rate) + d_last_rx_time;
+
+ return time;
+ }
+
+ uint64_t time_sample_ref::time_to_offset(time_spec_t time)
+ {
+ double samples_since_last_rx_time_tag = (time-d_last_rx_time).get_real_secs()*d_samp_rate;
+// double fractional_part = round(samples_since_last_rx_time_tag) - samples_since_last_rx_time_tag;
+ uint64_t offset = static_cast<uint64_t>(round(samples_since_last_rx_time_tag)) + d_current_start_offset;
+
+ return offset;
+ }
+ } // namespace gsm
+} // namespace gr
+
diff --git a/lib/receiver/time_sample_ref.h b/lib/receiver/time_sample_ref.h
new file mode 100644
index 0000000..793944d
--- /dev/null
+++ b/lib/receiver/time_sample_ref.h
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * @file
+ * @author (C) 2017 by 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_TIME_SAMPLE_REF_IMPL_H
+#define INCLUDED_TIME_SAMPLE_REF_IMPL_H
+
+#include <stdint.h>
+#include <grgsm/misc_utils/time_spec.h>
+
+namespace gr {
+ namespace gsm {
+ /*
+ Class for storing time reference and for conversions time<->sample number
+ */
+ class time_sample_ref
+ {
+ private:
+ double d_samp_rate;
+ time_spec_t d_last_rx_time;
+ uint64_t d_current_start_offset;
+ public:
+ time_sample_ref(double samp_rate);
+ ~time_sample_ref();
+ void update(time_spec_t last_rx_time, uint64_t current_start_offset);
+ time_spec_t offset_to_time(uint64_t offset);
+ uint64_t time_to_offset(time_spec_t time);
+ };
+ } // namespace gsm
+} // namespace gr
+#endif// INCLUDED_TIME_SAMPLE_REF_IMPL_H
diff --git a/lib/receiver/viterbi_detector.cc b/lib/receiver/viterbi_detector.cc
index 6a64a2c..3dce379 100644
--- a/lib/receiver/viterbi_detector.cc
+++ b/lib/receiver/viterbi_detector.cc
@@ -56,7 +56,8 @@
*/
#include <gnuradio/gr_complex.h>
-#include <gsm_constants.h>
+#include <grgsm/gsm_constants.h>
+#include <cmath>
#define PATHS_NUM (1 << (CHAN_IMP_RESP_LENGTH-1))
diff --git a/lib/transmitter/CMakeLists.txt b/lib/transmitter/CMakeLists.txt
new file mode 100644
index 0000000..eb53162
--- /dev/null
+++ b/lib/transmitter/CMakeLists.txt
@@ -0,0 +1,24 @@
+# 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.
+
+add_sources(
+ txtime_setter_impl.cc
+ preprocess_tx_burst_impl.cc
+ gen_test_ab_impl
+)
diff --git a/lib/transmitter/gen_test_ab_impl.cc b/lib/transmitter/gen_test_ab_impl.cc
new file mode 100644
index 0000000..bb9c9f6
--- /dev/null
+++ b/lib/transmitter/gen_test_ab_impl.cc
@@ -0,0 +1,107 @@
+/* -*- 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 <grgsm/gsm_constants.h>
+#include "gen_test_ab_impl.h"
+
+namespace gr {
+ namespace gsm {
+
+ static uint8_t rach_synch_seq[] = {
+ 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0 ,
+ 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0,
+ };
+
+ static uint8_t AB[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+// static uint8_t AB[] = {0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1};
+// static uint8_t AB[] = { 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1};
+// static uint8_t AB[] = {1,1,1,1,1,1,1,1,1,0,1,1,0,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,1,0,1,0,1,0,1,1,1,0,0,0,0,1,1,1,0,0,1,0,0,0,1,0,1,0,1,0,0,1,0,1,0,1,1,0,1,1,0,0,1,0,1,0,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
+// ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+ gen_test_ab::sptr
+ gen_test_ab::make()
+ {
+ return gnuradio::get_initial_sptr
+ (new gen_test_ab_impl());
+ }
+
+ /*
+ * The private constructor
+ */
+ gen_test_ab_impl::gen_test_ab_impl()
+ : gr::block("gen_test_ab",
+ gr::io_signature::make(0, 0, 0),
+ gr::io_signature::make(0, 0, 0))
+ {
+ message_port_register_in(pmt::intern("bursts_in"));
+ message_port_register_out(pmt::intern("bursts_out"));
+
+ set_msg_handler(pmt::intern("bursts_in"), boost::bind(&gen_test_ab_impl::generate_ab, this, _1));
+ }
+
+ /*
+ * Our virtual destructor.
+ */
+ gen_test_ab_impl::~gen_test_ab_impl()
+ {
+ }
+
+ void gen_test_ab_impl::generate_ab(pmt::pmt_t burst)
+ {
+ uint8_t buf[sizeof(gsmtap_hdr) + 148];
+ struct gsmtap_hdr *tap_header = (struct gsmtap_hdr *) buf;
+ uint8_t *access_burst = buf + sizeof(gsmtap_hdr);
+
+// memset(access_burst, 0, 8); /* TB */
+// memcpy(access_burst + 8, rach_synch_seq, 41); /* sync seq */
+// memcpy(access_burst + 49, AB, 36); /* payload */
+// memset(access_burst + 85, 0, 63); /* TB + GP */
+
+ memcpy(access_burst, AB, 148);
+
+ gsmtap_hdr * header = (gsmtap_hdr *)(pmt::blob_data(pmt::cdr(burst)));
+ uint32_t frame_nr = be32toh(header->frame_number);
+ frame_nr = (frame_nr+51)% (26*51*2048);
+
+ tap_header->version = GSMTAP_VERSION;
+ tap_header->hdr_len = sizeof(gsmtap_hdr) / 4;
+ tap_header->type = GSMTAP_TYPE_UM_BURST;
+ tap_header->sub_type = GSMTAP_BURST_ACCESS;
+ tap_header->frame_number = htobe32(frame_nr);
+ tap_header->timeslot = header->timeslot;
+ tap_header->arfcn = 0;
+
+ pmt::pmt_t blob = pmt::make_blob(buf, sizeof(gsmtap_hdr) + BURST_SIZE);
+ pmt::pmt_t pdu_header = pmt::make_dict();
+
+ pmt::pmt_t new_msg = pmt::cons(pdu_header, blob);
+ message_port_pub(pmt::intern("bursts_out"), new_msg);
+ }
+ } /* namespace gsm */
+} /* namespace gr */
+
diff --git a/lib/transmitter/gen_test_ab_impl.h b/lib/transmitter/gen_test_ab_impl.h
new file mode 100644
index 0000000..366481e
--- /dev/null
+++ b/lib/transmitter/gen_test_ab_impl.h
@@ -0,0 +1,47 @@
+/* -*- 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_GEN_TEST_AB_IMPL_H
+#define INCLUDED_GSM_GEN_TEST_AB_IMPL_H
+
+#include <grgsm/transmitter/gen_test_ab.h>
+#include <grgsm/misc_utils/time_spec.h>
+#include <grgsm/misc_utils/fn_time.h>
+
+namespace gr {
+ namespace gsm {
+
+ class gen_test_ab_impl : public gen_test_ab
+ {
+ private:
+ void generate_ab(pmt::pmt_t burst);
+
+ public:
+ gen_test_ab_impl();
+ ~gen_test_ab_impl();
+ };
+
+ } // namespace gsm
+} // namespace gr
+
+#endif /* INCLUDED_GSM_GEN_TEST_AB_IMPL_H */
+
diff --git a/lib/transmitter/preprocess_tx_burst_impl.cc b/lib/transmitter/preprocess_tx_burst_impl.cc
new file mode 100644
index 0000000..5fbac98
--- /dev/null
+++ b/lib/transmitter/preprocess_tx_burst_impl.cc
@@ -0,0 +1,96 @@
+/* -*- c++ -*- */
+/* @file
+ * @author Piotr Krysik <ptrkrysik@gmail.com>
+ * @author Vadim Yanitskiy <axilirator@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 <assert.h>
+
+#include <gnuradio/io_signature.h>
+#include <grgsm/gsm_constants.h>
+#include <grgsm/gsmtap.h>
+
+#include "preprocess_tx_burst_impl.h"
+
+namespace gr {
+ namespace gsm {
+
+ preprocess_tx_burst::sptr
+ preprocess_tx_burst::make()
+ {
+ return gnuradio::get_initial_sptr
+ (new preprocess_tx_burst_impl());
+ }
+
+ /*
+ * The private constructor
+ */
+ preprocess_tx_burst_impl::preprocess_tx_burst_impl()
+ : gr::block("preprocess_tx_burst",
+ gr::io_signature::make(0, 0, 0),
+ gr::io_signature::make(0, 0, 0))
+ {
+ message_port_register_in(pmt::mp("bursts_in"));
+ message_port_register_out(pmt::mp("bursts_out"));
+
+ set_msg_handler(pmt::mp("bursts_in"),
+ boost::bind(&preprocess_tx_burst_impl::process_burst, this, _1));
+ }
+
+ /*
+ * Our virtual destructor.
+ */
+ preprocess_tx_burst_impl::~preprocess_tx_burst_impl()
+ {
+ }
+
+ void preprocess_tx_burst_impl::process_burst(pmt::pmt_t msg_in)
+ {
+ pmt::pmt_t blob_in = pmt::cdr(msg_in);
+
+ // Extract GSMTAP header from message
+ gsmtap_hdr *burst_hdr = (gsmtap_hdr *) pmt::blob_data(blob_in);
+
+ // Extract burst bits from message
+ uint8_t *burst_bits = (uint8_t *)
+ (pmt::blob_data(blob_in)) + sizeof(gsmtap_hdr);
+
+ // Determine and check burst length
+ size_t burst_len = pmt::blob_length(blob_in) - sizeof(gsmtap_hdr);
+ assert(burst_len == BURST_SIZE);
+
+ // The Access Burst last has reduced length
+ if (burst_hdr->sub_type == GSMTAP_BURST_ACCESS)
+ burst_len = ACCESS_BURST_SIZE;
+
+ // Prepare an output message
+ pmt::pmt_t blob_out = pmt::make_blob(burst_bits, burst_len);
+ pmt::pmt_t msg_out = pmt::cons(pmt::car(msg_in), blob_out);
+
+ /* Send a message to the output */
+ message_port_pub(pmt::mp("bursts_out"), msg_out);
+ }
+
+ } /* namespace gsm */
+} /* namespace gr */
diff --git a/lib/transmitter/preprocess_tx_burst_impl.h b/lib/transmitter/preprocess_tx_burst_impl.h
new file mode 100644
index 0000000..27fc508
--- /dev/null
+++ b/lib/transmitter/preprocess_tx_burst_impl.h
@@ -0,0 +1,47 @@
+/* -*- 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_PREPROCESS_TX_BURST_IMPL_H
+#define INCLUDED_GSM_PREPROCESS_TX_BURST_IMPL_H
+
+#include <grgsm/transmitter/preprocess_tx_burst.h>
+#include <grgsm/misc_utils/time_spec.h>
+#include <grgsm/misc_utils/fn_time.h>
+
+namespace gr {
+ namespace gsm {
+
+ class preprocess_tx_burst_impl : public preprocess_tx_burst
+ {
+ private:
+ void process_burst(pmt::pmt_t burst);
+
+ public:
+ preprocess_tx_burst_impl();
+ ~preprocess_tx_burst_impl();
+ };
+
+ } // namespace gsm
+} // namespace gr
+
+#endif /* INCLUDED_GSM_PREPROCESS_TX_BURST_IMPL_H */
+
diff --git a/lib/transmitter/txtime_setter_impl.cc b/lib/transmitter/txtime_setter_impl.cc
new file mode 100644
index 0000000..33bc994
--- /dev/null
+++ b/lib/transmitter/txtime_setter_impl.cc
@@ -0,0 +1,196 @@
+/* -*- c++ -*- */
+/* @file
+ * @author Piotr Krysik <ptrkrysik@gmail.com>
+ * @author Vadim Yanitskiy <axilirator@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 "txtime_setter_impl.h"
+
+#define UNKNOWN_FN 0xffffffff
+#define MAX_EARLY_TIME_DIFF 10.0
+
+namespace gr {
+ namespace gsm {
+
+ txtime_setter::sptr
+ txtime_setter::make(
+ uint32_t init_fn, uint64_t init_time_secs,
+ double init_time_fracs, uint64_t time_hint_secs,
+ double time_hint_fracs, double timing_advance,
+ double delay_correction)
+ {
+ return gnuradio::get_initial_sptr
+ (new txtime_setter_impl(init_fn, init_time_secs,
+ init_time_fracs, time_hint_secs, time_hint_fracs,
+ timing_advance, delay_correction));
+ }
+
+ /*
+ * The private constructor
+ */
+ txtime_setter_impl::txtime_setter_impl(
+ uint32_t init_fn, uint64_t init_time_secs,
+ double init_time_fracs, uint64_t time_hint_secs,
+ double time_hint_fracs, double timing_advance,
+ double delay_correction
+ ) : gr::block("txtime_setter",
+ gr::io_signature::make(0, 0, 0),
+ gr::io_signature::make(0, 0, 0)),
+ d_time_hint(time_hint_secs,time_hint_fracs),
+ d_time_ref(init_time_secs,init_time_fracs),
+ d_delay_correction(delay_correction),
+ d_timing_advance(timing_advance),
+ d_fn_ref(init_fn),
+ d_ts_ref(0)
+ {
+ // Register I/O ports
+ message_port_register_in(pmt::mp("fn_time"));
+ message_port_register_in(pmt::mp("bursts_in"));
+ message_port_register_out(pmt::mp("bursts_out"));
+
+ // Bind message handlers
+ set_msg_handler(pmt::mp("fn_time"),
+ boost::bind(&txtime_setter_impl::process_fn_time_reference,
+ this, _1));
+ set_msg_handler(pmt::mp("bursts_in"),
+ boost::bind(&txtime_setter_impl::process_txtime_of_burst,
+ this, _1));
+ }
+
+ /*
+ * Our virtual destructor.
+ */
+ txtime_setter_impl::~txtime_setter_impl()
+ {
+ }
+
+ void txtime_setter_impl::process_fn_time_reference(pmt::pmt_t msg)
+ {
+ pmt::pmt_t not_found = pmt::intern("not_found");
+ pmt::pmt_t fn_time, time_hint;
+
+ fn_time = pmt::dict_ref(msg,
+ pmt::intern("fn_time"), not_found);
+ time_hint = pmt::dict_ref(msg,
+ pmt::intern("fn_time"), not_found);
+
+ if (fn_time != not_found) {
+ uint32_t fn_ref = static_cast<uint32_t>
+ (pmt::to_uint64(pmt::car(pmt::car(fn_time))));
+ uint32_t ts = static_cast<uint32_t>
+ (pmt::to_uint64(pmt::cdr(pmt::car(fn_time))));
+ uint64_t time_secs = pmt::to_uint64(
+ pmt::car(pmt::cdr(fn_time)));
+ double time_fracs = pmt::to_double(
+ pmt::cdr(pmt::cdr(fn_time)));
+
+ set_fn_time_reference(fn_ref, ts, time_secs, time_fracs);
+ } else if (time_hint != not_found) {
+ set_time_hint(pmt::to_uint64(pmt::car(fn_time)),
+ pmt::to_double(pmt::cdr(fn_time)));
+ }
+ }
+
+ void txtime_setter_impl::process_txtime_of_burst(pmt::pmt_t msg_in)
+ {
+ if (d_fn_ref != UNKNOWN_FN)
+ {
+ pmt::pmt_t blob = pmt::cdr(msg_in);
+
+ // Extract GSMTAP header from message
+ gsmtap_hdr *header = (gsmtap_hdr *) pmt::blob_data(blob);
+ uint32_t frame_nr = be32toh(header->frame_number);
+ uint32_t ts_num = header->timeslot;
+
+ time_format txtime = fn_time_delta_cpp(d_fn_ref, d_time_ref,
+ frame_nr, d_time_hint, ts_num, d_ts_ref);
+
+ time_spec_t txtime_spec = time_spec_t(txtime.first, txtime.second);
+ txtime_spec -= d_delay_correction;
+ txtime_spec -= d_timing_advance;
+
+ time_spec_t current_time_estimate = time_spec_t(d_time_hint.first, d_time_hint.second);
+
+ if (txtime_spec <= current_time_estimate) { // Drop too late bursts
+ std::cout << "lB" << std::flush;
+ } else if (txtime_spec > current_time_estimate + MAX_EARLY_TIME_DIFF) { // Drop too early bursts
+ std::cout << "eB" << std::flush; //TODO: too early condition might happen when changing BTSes.
+ //Wrong fn_time is applied to new or old bursts in such situation.
+ //This solution is not perfect as MS might be blocked upto
+ //MAX_EARLY_TIME_DIFF seconds.
+ //Better solution would be to indentify fn_time and burst coming
+ //from given BTS (i.e. based on ARFCN) and dropping bursts for which
+ //the bts_id doesn't match with bts_id of fn_time.
+ } else { //process bursts that are in the right time-frame
+ pmt::pmt_t tags_dict = pmt::dict_add(
+ pmt::make_dict(),
+ pmt::intern("tx_time"),
+ pmt::make_tuple(
+ pmt::from_uint64(txtime_spec.get_full_secs()),
+ pmt::from_double(txtime_spec.get_frac_secs()))
+ );
+
+ tags_dict = pmt::dict_add(tags_dict,
+ pmt::intern("fn"), pmt::from_uint64(frame_nr));
+ tags_dict = pmt::dict_add(tags_dict,
+ pmt::intern("ts"), pmt::from_uint64(ts_num));
+
+ // Send a message to the output
+ pmt::pmt_t msg_out = pmt::cons(tags_dict, pmt::cdr(msg_in));
+ message_port_pub(pmt::mp("bursts_out"), msg_out);
+ }
+ }
+ }
+
+ void txtime_setter_impl::set_fn_time_reference(
+ uint32_t fn, uint32_t ts, uint64_t time_secs,
+ double time_fracs)
+ {
+ d_fn_ref = fn;
+ d_ts_ref = ts;
+ d_time_ref = std::make_pair(time_secs, time_fracs);
+ set_time_hint(time_secs, time_fracs);
+ }
+
+ void txtime_setter_impl::set_time_hint(
+ uint64_t time_hint_secs, double time_hint_fracs)
+ {
+ d_time_hint = std::make_pair(time_hint_secs, time_hint_fracs);
+ }
+
+ void txtime_setter_impl::set_delay_correction(double delay_correction)
+ {
+ d_delay_correction = delay_correction;
+ }
+
+ void txtime_setter_impl::set_timing_advance(double timing_advance)
+ {
+ d_timing_advance = timing_advance;
+ }
+
+ } /* namespace gsm */
+} /* namespace gr */
diff --git a/lib/transmitter/txtime_setter_impl.h b/lib/transmitter/txtime_setter_impl.h
new file mode 100644
index 0000000..62f500a
--- /dev/null
+++ b/lib/transmitter/txtime_setter_impl.h
@@ -0,0 +1,64 @@
+/* -*- 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_TXTIME_SETTER_IMPL_H
+#define INCLUDED_GSM_TXTIME_SETTER_IMPL_H
+
+#include <grgsm/transmitter/txtime_setter.h>
+#include <grgsm/misc_utils/time_spec.h>
+#include <grgsm/misc_utils/fn_time.h>
+
+namespace gr {
+ namespace gsm {
+
+ class txtime_setter_impl : public txtime_setter
+ {
+ private:
+ uint32_t d_fn_ref;
+ uint32_t d_ts_ref;
+ time_format d_time_ref;
+ time_format d_time_hint;
+ double d_timing_advance;
+ double d_delay_correction;
+
+ void process_fn_time_reference(pmt::pmt_t msg);
+ void process_txtime_of_burst(pmt::pmt_t msg);
+
+ public:
+ txtime_setter_impl(uint32_t init_fn, uint64_t init_time_secs,
+ double init_time_fracs, uint64_t time_hint_secs,
+ double time_hint_fracs, double timing_advance,
+ double delay_correction);
+ ~txtime_setter_impl();
+
+ // Where all the action really happens
+ void set_fn_time_reference(uint32_t fn, uint32_t ts,
+ uint64_t time_secs, double time_fracs);
+ void set_time_hint(uint64_t time_hint_secs, double time_hint_fracs);
+ void set_delay_correction(double delay_correction);
+ void set_timing_advance(double timing_advance);
+ };
+
+ } // namespace gsm
+} // namespace gr
+
+#endif /* INCLUDED_GSM_TXTIME_SETTER_IMPL_H */