From d0b41f0780ad1c3cdf61211b1ab32439eae8289f Mon Sep 17 00:00:00 2001 From: Sylvain Munaut Date: Fri, 30 Jan 2015 10:07:22 +0100 Subject: gr-gmr1: Import new burst_to_tagged_stream logic Note that this cheats a little since I use the output buffer as temporary storage (i.e. writing samples to it and not telling GR until later ...) Signed-off-by: Sylvain Munaut --- gr-gmr1/grc/CMakeLists.txt | 1 + gr-gmr1/grc/burst_to_tagged_stream.xml | 27 +++ gr-gmr1/include/gnuradio/gmr1/CMakeLists.txt | 1 + .../include/gnuradio/gmr1/burst_to_tagged_stream.h | 46 +++++ gr-gmr1/lib/CMakeLists.txt | 1 + gr-gmr1/lib/burst_to_tagged_stream_impl.cc | 192 +++++++++++++++++++++ gr-gmr1/lib/burst_to_tagged_stream_impl.h | 58 +++++++ gr-gmr1/swig/gmr1_swig.i | 4 + 8 files changed, 330 insertions(+) create mode 100644 gr-gmr1/grc/burst_to_tagged_stream.xml create mode 100644 gr-gmr1/include/gnuradio/gmr1/burst_to_tagged_stream.h create mode 100644 gr-gmr1/lib/burst_to_tagged_stream_impl.cc create mode 100644 gr-gmr1/lib/burst_to_tagged_stream_impl.h diff --git a/gr-gmr1/grc/CMakeLists.txt b/gr-gmr1/grc/CMakeLists.txt index dd67872..850d049 100644 --- a/gr-gmr1/grc/CMakeLists.txt +++ b/gr-gmr1/grc/CMakeLists.txt @@ -18,6 +18,7 @@ # Boston, MA 02110-1301, USA. install(FILES + burst_to_tagged_stream.xml gsmtap_sink.xml rach_demod.xml rach_detect_fft.xml diff --git a/gr-gmr1/grc/burst_to_tagged_stream.xml b/gr-gmr1/grc/burst_to_tagged_stream.xml new file mode 100644 index 0000000..fc96128 --- /dev/null +++ b/gr-gmr1/grc/burst_to_tagged_stream.xml @@ -0,0 +1,27 @@ + + + Burst to Tagged Stream + burst_to_tagged_stream + GMR-1 + from gnuradio import gmr1 + gmr1.burst_to_tagged_stream($max_length, $len_tag_key) + + Maximum burst length + max_length + int + + + Length Tag Name + len_tag_key + packet_len + string + + + in + complex + + + out + complex + + diff --git a/gr-gmr1/include/gnuradio/gmr1/CMakeLists.txt b/gr-gmr1/include/gnuradio/gmr1/CMakeLists.txt index 6aaaaa6..a05f79e 100644 --- a/gr-gmr1/include/gnuradio/gmr1/CMakeLists.txt +++ b/gr-gmr1/include/gnuradio/gmr1/CMakeLists.txt @@ -22,6 +22,7 @@ ######################################################################## install(FILES api.h + burst_to_tagged_stream.h gsmtap_sink.h rach_demod.h rach_detect_fft.h diff --git a/gr-gmr1/include/gnuradio/gmr1/burst_to_tagged_stream.h b/gr-gmr1/include/gnuradio/gmr1/burst_to_tagged_stream.h new file mode 100644 index 0000000..2556ded --- /dev/null +++ b/gr-gmr1/include/gnuradio/gmr1/burst_to_tagged_stream.h @@ -0,0 +1,46 @@ +/* -*- c++ -*- */ +/* + * Copyright 2015 Sylvain Munaut + * + * 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. + */ + +#ifndef INCLUDED_GR_GMR1_BURST_TO_TAGGED_STREAM_H +#define INCLUDED_GR_GMR1_BURST_TO_TAGGED_STREAM_H + +#include + +#include + +namespace gr { + namespace gmr1 { + + /*! + * \brief + * \ingroup + */ + class GR_GMR1_API burst_to_tagged_stream : virtual public block + { + public: + typedef boost::shared_ptr sptr; + + static sptr make(int max_length, const std::string& len_tag_key); + }; + + } // namespace gmr1 +} // namespace gr + +#endif /* INCLUDED_GR_GMR1_BURST_TO_TAGGED_STREAM_H */ diff --git a/gr-gmr1/lib/CMakeLists.txt b/gr-gmr1/lib/CMakeLists.txt index 9f7573a..10b9475 100644 --- a/gr-gmr1/lib/CMakeLists.txt +++ b/gr-gmr1/lib/CMakeLists.txt @@ -42,6 +42,7 @@ list(APPEND gmr1_sources ../../src/l1/tch3.c ../../src/l1/tch9.c ../../src/gsmtap.c + burst_to_tagged_stream_impl.cc gsmtap_sink_impl.cc rach_demod_impl.cc rach_detect_fft_impl.cc diff --git a/gr-gmr1/lib/burst_to_tagged_stream_impl.cc b/gr-gmr1/lib/burst_to_tagged_stream_impl.cc new file mode 100644 index 0000000..b37258e --- /dev/null +++ b/gr-gmr1/lib/burst_to_tagged_stream_impl.cc @@ -0,0 +1,192 @@ +/* -*- c++ -*- */ +/* + * Copyright 2015 Sylvain Munaut + * + * 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 "burst_to_tagged_stream_impl.h" + + +namespace gr { + namespace gmr1 { + + /* FIXME: Those should be in a common include */ +static const pmt::pmt_t SOB_KEY = pmt::string_to_symbol("sob"); +static const pmt::pmt_t EOB_KEY = pmt::string_to_symbol("eob"); + + +burst_to_tagged_stream::sptr +burst_to_tagged_stream::make(int max_length, const std::string& len_tag_key) +{ + return gnuradio::get_initial_sptr( + new burst_to_tagged_stream_impl(max_length, len_tag_key) + ); +} + +burst_to_tagged_stream_impl::burst_to_tagged_stream_impl(int max_length, const std::string& len_tag_key) + : gr::block("burst_to_tagged_stream", + io_signature::make(1, 1, sizeof(gr_complex)), + io_signature::make(1, 1, sizeof(gr_complex))), + d_active(false), d_offset(0), + d_len_tag_key(pmt::string_to_symbol(len_tag_key)) +{ + /* Ensure our output buffer size */ + set_min_output_buffer(max_length * sizeof(gr_complex)); + + /* We'll take care of tags ourselves */ + set_tag_propagation_policy(TPP_DONT); +} + +burst_to_tagged_stream_impl::~burst_to_tagged_stream_impl() +{ + /* Nothing to do */ +} + + +void +burst_to_tagged_stream_impl::forecast( + int noutput_items, + gr_vector_int &ninput_items_required) +{ + ninput_items_required[0] = 1; +} + +int +burst_to_tagged_stream_impl::general_work( + int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const gr_complex *in = reinterpret_cast(input_items[0]); + gr_complex *out = reinterpret_cast< gr_complex *>(output_items[0]); + std::vector tags, tags_to_copy; + std::vector::iterator it; + int avail, n; + + /* If we're not active, drop samples until we are */ + if (!this->d_active) + { + get_tags_in_range(tags, 0, + nitems_read(0), + nitems_read(0) + ninput_items[0], + SOB_KEY + ); + + if (tags.empty()) { + consume_each(ninput_items[0]); + } else { + this->d_active = true; + this->d_offset = 0; + + consume_each(tags[0].offset - nitems_read(0)); + } + + return 0; + } + + /* We're active ! Look for EOB */ + get_tags_in_range(tags, 0, + nitems_read(0) + ((this->d_offset == 0) ? 1 : 0), + nitems_read(0) + ninput_items[0], + EOB_KEY + ); + + /* Decide how much to copy */ + avail = noutput_items - this->d_offset; + + if (tags.empty()) + /* Copy all we can */ + n = ninput_items[0]; + else + /* Only until the end of burst */ + n = tags[0].offset - nitems_read(0) + 1; + + /* Are we screwed */ + if (avail < n) + { + fprintf(stderr, "SOB without EOB in time ...\n"); + return WORK_DONE; + } + + /* Copy tags */ + /* If we have the EOB, we exclude tags on it */ + get_tags_in_range(tags_to_copy, 0, + nitems_read(0), + nitems_read(0) + n - (tags.empty() ? 0 : 1) + ); + + for (it=tags_to_copy.begin(); it!=tags_to_copy.end(); it++) + { + tag_t new_tag = *it; + + /* Exclude some tags */ + if (pmt::eqv(it->key, SOB_KEY) || + pmt::eqv(it->key, EOB_KEY) || + pmt::eqv(it->key, this->d_len_tag_key)) + continue; + + new_tag.offset = + nitems_written(0) + + this->d_offset + + (new_tag.offset - nitems_read(0)); + + add_item_tag(0, new_tag); + } + + /* Copy data */ + memcpy(out + this->d_offset, in, n * sizeof(gr_complex)); + this->d_offset += n; + + /* Was it the end */ + if (tags.empty()) + { + /* No, don't produce yet */ + consume_each(n); + return 0; + } + else + { + /* Yes !, we need to add the length tag */ + add_item_tag( + 0, + this->nitems_written(0), + this->d_len_tag_key, + pmt::from_long(this->d_offset) + ); + + /* Note: Because we may have EOB and next SOB on the same sample, we + * leave the last sample in the input buffer */ + consume_each(n - 1); + + /* Prepare for next */ + this->d_active = false; + + return this->d_offset; + } +} + + } // namespace gmr1 +} // namespace gr diff --git a/gr-gmr1/lib/burst_to_tagged_stream_impl.h b/gr-gmr1/lib/burst_to_tagged_stream_impl.h new file mode 100644 index 0000000..240cfe3 --- /dev/null +++ b/gr-gmr1/lib/burst_to_tagged_stream_impl.h @@ -0,0 +1,58 @@ +/* -*- c++ -*- */ +/* + * Copyright 2015 Sylvain Munaut + * + * 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. + */ + + +#ifndef INCLUDED_GR_GMR1_BURST_TO_TAGGED_STREAM_IMPL_H +#define INCLUDED_GR_GMR1_BURST_TO_TAGGED_STREAM_IMPL_H + +#include + +namespace gr { + namespace gmr1 { + + /*! + * \brief + * \ingroup gmr1 + */ + class burst_to_tagged_stream_impl : public burst_to_tagged_stream + { + private: + pmt::pmt_t d_len_tag_key; + + bool d_active; + int d_offset; + + public: + burst_to_tagged_stream_impl(int max_length, const std::string& len_tag_key); + virtual ~burst_to_tagged_stream_impl(); + + void forecast(int noutput_items, + gr_vector_int &ninput_items_required); + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } // namespace gmr1 +} // namespace gr + +#endif /* INCLUDED_GR_GMR1_BURST_TO_TAGGED_STREAM_IMPL_H */ diff --git a/gr-gmr1/swig/gmr1_swig.i b/gr-gmr1/swig/gmr1_swig.i index d467397..0f427d5 100644 --- a/gr-gmr1/swig/gmr1_swig.i +++ b/gr-gmr1/swig/gmr1_swig.i @@ -9,11 +9,15 @@ %{ +#include "gnuradio/gmr1/burst_to_tagged_stream.h" #include "gnuradio/gmr1/gsmtap_sink.h" #include "gnuradio/gmr1/rach_demod.h" #include "gnuradio/gmr1/rach_detect_fft.h" %} +%include "gnuradio/gmr1/burst_to_tagged_stream.h" +GR_SWIG_BLOCK_MAGIC2(gmr1, burst_to_tagged_stream); + %include "gnuradio/gmr1/gsmtap_sink.h" GR_SWIG_BLOCK_MAGIC2(gmr1, gsmtap_sink); -- cgit v1.2.3