/* -*- c++ -*- */ /* * Copyright 2014 <+YOU OR YOUR COMPANY+>. * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, * Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include "tx_tagging_impl.h" using namespace std; namespace gr { namespace tx_tagging { tx_tagging::sptr tx_tagging::make(const double samp_rate, const double idle_duration, const double burst_duration, const std::string &length_tag_name) { return gnuradio::get_initial_sptr (new tx_tagging_impl(samp_rate, idle_duration, burst_duration, length_tag_name)); } /* * The private constructor */ tx_tagging_impl::tx_tagging_impl(const double samp_rate, const double idle_duration, const double burst_duration, const std::string &length_tag_name) : gr::sync_block("tx_tagging", gr::io_signature::make(1, 1, sizeof(std::complex)), gr::io_signature::make(1, 1, sizeof(std::complex)) ), //_time_secs(start_secs), //_time_fracs(start_fracs), _samp_rate(samp_rate), _samps_per_burst(samp_rate*burst_duration), _cycle_duration(idle_duration + burst_duration), _samps_left_in_burst(1), //immediate EOB _do_new_burst(false), _firstrun(not length_tag_name.empty()), _length_tag_key(length_tag_name.empty() ? pmt::PMT_NIL : pmt::string_to_symbol(length_tag_name)) { //NOP } /* * Our virtual destructor. */ tx_tagging_impl::~tx_tagging_impl() { } void tx_tagging_impl::make_time_tag(const uint64_t tag_count) { const pmt::pmt_t key = pmt::string_to_symbol("tx_time"); const pmt::pmt_t value = pmt::make_tuple( pmt::from_uint64(_time_secs), pmt::from_double(_time_fracs) ); const pmt::pmt_t srcid = pmt::string_to_symbol(this->name()); this->add_item_tag(0/*chan0*/, tag_count, key, value, srcid); } void tx_tagging_impl::make_sob_tag(const uint64_t tag_count) { const pmt::pmt_t key = pmt::string_to_symbol("tx_sob"); const pmt::pmt_t value = pmt::PMT_T; const pmt::pmt_t srcid = pmt::string_to_symbol(this->name()); this->add_item_tag(0/*chan0*/, tag_count, key, value, srcid); } void tx_tagging_impl::make_eob_tag(const uint64_t tag_count) { const pmt::pmt_t key = pmt::string_to_symbol("tx_eob"); const pmt::pmt_t value = pmt::PMT_T; const pmt::pmt_t srcid = pmt::string_to_symbol(this->name()); this->add_item_tag(0/*chan0*/, tag_count, key, value, srcid); } void tx_tagging_impl::make_length_tag(const uint64_t tag_count, const uint64_t burst_len) { if (pmt::is_null(_length_tag_key)) { //no length_tag was specified at initialization; make a tx_sob tag instead this->make_sob_tag(tag_count); return; } const pmt::pmt_t key = _length_tag_key; const pmt::pmt_t value = pmt::from_long((long)burst_len); const pmt::pmt_t srcid = pmt::string_to_symbol(this->name()); this->add_item_tag(0/*chan0*/, tag_count, key, value, srcid); } int tx_tagging_impl::work( int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { //Read RX tags --- Initially found in block tag-sink demo.h std::vector rx_time_tags; const uint64_t samp0_count = this->nitems_read(0); get_tags_in_range(rx_time_tags, 0, samp0_count, samp0_count + noutput_items, pmt::string_to_symbol("rx_time")); //Extracting time stamps from rx-tag BOOST_FOREACH(const gr::tag_t &rx_time_tag, rx_time_tags){ const uint64_t offset = rx_time_tag.offset; const pmt::pmt_t &value = rx_time_tag.value; _time_secs = pmt::to_uint64(pmt::tuple_ref(value,0)); _time_fracs = pmt::to_double(pmt::tuple_ref(value,1)); cout << offset < *output = reinterpret_cast *>(output_items[0]); const std::complex *input = (const std::complex *)(input_items[0]); for (size_t i = 0; i < size_t(noutput_items); i++) { //output[i] = std::complex(0.7, 0.7); output[i] = input[i]; } //Handle the start of burst condition. //Tag a start of burst and timestamp. //Increment the time for the next burst. if (_do_new_burst) { cout << "Condition for New Burst" << endl; _do_new_burst = false; _samps_left_in_burst = _samps_per_burst; if (pmt::is_null(_length_tag_key)){ this->make_sob_tag(this->nitems_written(0)); cout << "Making SOB Tag" << endl; } else #if 1 this->make_length_tag(this->nitems_written(0), _samps_left_in_burst); #else //Test usrp_sink's ability to cancel remainder of burst if new length_tag is found early //sets burst time to 10% greater than the cycle duration to guarantee early length_tag //In a real implementation the user should guard against this so that the number of //samples promised by the length_tag are actually processed by the usrp_sink. this->make_length_tag(this->nitems_written(0), uint64_t(1.1 * _samp_rate * _cycle_duration)); #endif this->make_time_tag(this->nitems_written(0)); cout << "Time Tag w/ Time stamp: " << _time_secs << "+" << _time_fracs << endl; _time_fracs += _cycle_duration; double intpart; //normalize _time_fracs = std::modf(_time_fracs, &intpart); _time_secs += uint64_t(intpart); } //Handle the end of burst condition. //Tag an end of burst and return early. //the next work call will be a start of burst. if (_samps_left_in_burst < size_t(noutput_items)){ if (pmt::is_null(_length_tag_key)){ //this->make_eob_tag(this->nitems_written(0) + _samps_left_in_burst - 1); cout << "Making EOB tag" << endl; } else if (_firstrun){ _firstrun = false; this->make_length_tag(this->nitems_written(0), 1); } _do_new_burst = true; noutput_items = _samps_left_in_burst; } _samps_left_in_burst -= noutput_items; return noutput_items; } } /* namespace tx_tagging */ } /* namespace gr */