commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] [gnuradio] 39/57: digital: modified tagged stream corr


From: git
Subject: [Commit-gnuradio] [gnuradio] 39/57: digital: modified tagged stream correlate access code.
Date: Wed, 21 May 2014 03:10:29 +0000 (UTC)

This is an automated email from the git hooks/post-receive script.

trondeau pushed a commit to branch master
in repository gnuradio.

commit 0e28a39e8e821f5bdd721b783ce939d480266c08
Author: Tom Rondeau <address@hidden>
Date:   Thu May 15 12:04:41 2014 -0400

    digital: modified tagged stream correlate access code.
    
    Decodes the header of a packet to get the frame length (in bytes). Uses 
this, fec rate, and fec extra parameter to set the tag stream output size in 
bits (or soft decision floats)
---
 .../grc/digital_correlate_access_code_xx_ts.xml    |  17 +-
 .../gnuradio/digital/correlate_access_code_ff_ts.h |  36 +++-
 gr-digital/lib/correlate_access_code_ff_ts_impl.cc | 191 +++++++++++++++------
 gr-digital/lib/correlate_access_code_ff_ts_impl.h  |  30 +++-
 4 files changed, 216 insertions(+), 58 deletions(-)

diff --git a/gr-digital/grc/digital_correlate_access_code_xx_ts.xml 
b/gr-digital/grc/digital_correlate_access_code_xx_ts.xml
index 5b6dda0..547bbb7 100644
--- a/gr-digital/grc/digital_correlate_access_code_xx_ts.xml
+++ b/gr-digital/grc/digital_correlate_access_code_xx_ts.xml
@@ -8,7 +8,8 @@
   <name>Correlate Access Code - Tag Stream</name>
   <key>digital_correlate_access_code_xx_ts</key>
   <import>from gnuradio import digital</import>
-  <make>digital.correlate_access_code_$(type.fcn)_ts($access_code, $threshold, 
$tagname)</make>
+  <make>digital.correlate_access_code_$(type.fcn)_ts($access_code,
+  $threshold, $tagname, $fec_rate, $fec_extra)</make>
 
   <param>
     <name>IO Type</name>
@@ -45,6 +46,20 @@
     <type>string</type>
   </param>
 
+  <param>
+    <name>FEC Rate</name>
+    <key>fec_rate</key>
+    <value>1</value>
+    <type>float</type>
+  </param>
+
+  <param>
+    <name>FEC Extras</name>
+    <key>fec_extra</key>
+    <value>0</value>
+    <type>int</type>
+  </param>
+
   <sink>
     <name>in</name>
     <type>$type</type>
diff --git a/gr-digital/include/gnuradio/digital/correlate_access_code_ff_ts.h 
b/gr-digital/include/gnuradio/digital/correlate_access_code_ff_ts.h
index d7ba653..5d05c89 100644
--- a/gr-digital/include/gnuradio/digital/correlate_access_code_ff_ts.h
+++ b/gr-digital/include/gnuradio/digital/correlate_access_code_ff_ts.h
@@ -35,12 +35,25 @@ namespace gr {
      * \ingroup packet_operators_blk
      *
      * \details
-     * input:  stream of bits, 1 bit per input byte (data in LSB)
-     * output: unaltered stream of bits (plus tags)
+     * input:  stream of floats (generally, soft decisions)
+     * output: unaltered stream of floats in a tagged stream
      *
-     * This block annotates the input stream with tags. The tags have
-     * key name [tag_name], specified in the constructor. Used for
-     * searching an input data stream for preambles, etc.
+     * This block searches for the given access code by slicing the
+     * soft decision symbol inputs. Once found, it expects the
+     * following 32 samples to contain a header that includes the
+     * frame length. It decodes the header to get the frame length in
+     * order to set up the the tagged stream key information.
+     *
+     * If the block is given a \p fec_rate and/or \p fec_extra, this
+     * information is used to adjust the tagged stream information
+     * based on the follow-on FEC decoding. The header provides
+     * information about the uncoded frame size (in bytes), so the
+     * actual frame length based on the FEC code used will be:
+     *
+     * pkt_len = fec_rate*8*frame_size + fec_extra
+     *
+     * The output of this block is appropriate for use with tagged
+     * stream blocks.
      */
     class DIGITAL_API correlate_access_code_ff_ts : virtual public block
     {
@@ -53,16 +66,27 @@ namespace gr {
        *                    e.g., "010101010111000100"
        * \param threshold maximum number of bits that may be wrong
        * \param tag_name key of the tag inserted into the tag stream
+       * \param fec_rate Rate of the FEC used to adjust the frame length info
+       * \param fec_extra Any extra samples added by the FEC
+       *        (e.g., the 2(K-1) tail used in the terminated CC codes).
        */
       static sptr make(const std::string &access_code,
                       int threshold,
-                      const std::string &tag_name);
+                      const std::string &tag_name,
+                       float fec_rate=1,
+                       int fec_extra=0);
 
       /*!
        * \param access_code is represented with 1 byte per bit,
        *                    e.g., "010101010111000100"
        */
       virtual bool set_access_code(const std::string &access_code) = 0;
+      virtual void set_fec_rate(float rate) = 0;
+      virtual void set_fec_extra(int extra) = 0;
+
+      virtual unsigned long long access_code() const = 0;
+      virtual float fec_rate() const = 0;
+      virtual int fec_extra() const = 0;
     };
 
   } /* namespace digital */
diff --git a/gr-digital/lib/correlate_access_code_ff_ts_impl.cc 
b/gr-digital/lib/correlate_access_code_ff_ts_impl.cc
index e062730..bdba736 100644
--- a/gr-digital/lib/correlate_access_code_ff_ts_impl.cc
+++ b/gr-digital/lib/correlate_access_code_ff_ts_impl.cc
@@ -39,17 +39,20 @@ namespace gr {
 
     correlate_access_code_ff_ts::sptr
     correlate_access_code_ff_ts::make(const std::string &access_code,
-                                      int threshold,
-                                      const std::string &tag_name)
+                                      int threshold,
+                                      const std::string &tag_name,
+                                      float fec_rate, int fec_extra)
     {
       return gnuradio::get_initial_sptr
        (new correlate_access_code_ff_ts_impl(access_code,
-                                              threshold, tag_name));
+                                              threshold, tag_name,
+                                              fec_rate, fec_extra));
     }
 
 
     correlate_access_code_ff_ts_impl::correlate_access_code_ff_ts_impl(
-        const std::string &access_code, int threshold, const std::string 
&tag_name)
+      const std::string &access_code, int threshold, const std::string 
&tag_name,
+      float fec_rate, int fec_extra)
       : block("correlate_access_code_ff_ts",
               io_signature::make(1, 1, sizeof(float)),
               io_signature::make(1, 1, sizeof(float))),
@@ -67,10 +70,14 @@ namespace gr {
       d_me = pmt::string_to_symbol(str.str());
       d_key = pmt::string_to_symbol(tag_name);
 
-      // READ IN AS ARGS; MAKE SETTERS/GETTERS
-      d_pkt_key = pmt::string_to_symbol("pkt_len");
-      d_pkt_len = 2*120*8 + 12 + 0;
+      d_state = STATE_SYNC_SEARCH;
+      d_pkt_len = 0;
       d_pkt_count = 0;
+      d_hdr_reg = 0;
+      d_hdr_count = 0;
+
+      set_fec_rate(fec_rate);
+      set_fec_extra(fec_extra);
     }
 
     correlate_access_code_ff_ts_impl::~correlate_access_code_ff_ts_impl()
@@ -78,8 +85,7 @@ namespace gr {
     }
 
     bool
-    correlate_access_code_ff_ts_impl::set_access_code(
-        const std::string &access_code)
+    correlate_access_code_ff_ts_impl::set_access_code(const std::string 
&access_code)
     {
       d_len = access_code.length();    // # of bytes in string
       if(d_len > 64)
@@ -100,6 +106,77 @@ namespace gr {
       return true;
     }
 
+    void
+    correlate_access_code_ff_ts_impl::set_fec_rate(float rate)
+    {
+      if(rate <= 0) {
+        throw std::runtime_error("correlate_access_code_ff_ts: FEC rate must 
be > 0");
+      }
+      d_fec_rate = rate;
+    }
+
+    void
+    correlate_access_code_ff_ts_impl::set_fec_extra(int extra)
+    {
+      if(extra < 0) {
+        throw std::runtime_error("correlate_access_code_ff_ts: FEC extra bits 
must be >= 0");
+      }
+      d_fec_extra = extra;
+    }
+
+    unsigned long long
+    correlate_access_code_ff_ts_impl::access_code() const
+    {
+      return d_access_code;
+    }
+
+    float
+    correlate_access_code_ff_ts_impl::fec_rate() const
+    {
+      return d_fec_rate;
+    }
+
+    int
+    correlate_access_code_ff_ts_impl::fec_extra() const
+    {
+      return d_fec_extra;
+    }
+
+    inline void
+    correlate_access_code_ff_ts_impl::enter_search()
+    {
+      d_state = STATE_SYNC_SEARCH;
+    }
+
+    inline void
+    correlate_access_code_ff_ts_impl::enter_have_sync()
+    {
+      d_state = STATE_HAVE_SYNC;
+      d_hdr_reg = 0;
+      d_hdr_count = 0;
+    }
+
+    inline void
+    correlate_access_code_ff_ts_impl::enter_have_header(int payload_len)
+    {
+      d_state = STATE_HAVE_HEADER;
+      d_pkt_len = d_fec_rate*8*payload_len + d_fec_extra;
+      d_pkt_count = 0;
+    }
+
+    bool
+    correlate_access_code_ff_ts_impl::header_ok()
+    {
+      // confirm that two copies of header info are identical
+      return ((d_hdr_reg >> 16) ^ (d_hdr_reg & 0xffff)) == 0;
+    }
+
+    int
+    correlate_access_code_ff_ts_impl::header_payload()
+    {
+      return (d_hdr_reg >> 16) & 0x0fff;
+    }
+
     int
     correlate_access_code_ff_ts_impl::general_work(int noutput_items,
                                                    gr_vector_int &ninput_items,
@@ -113,57 +190,75 @@ namespace gr {
 
       int nprod = 0;
 
-      for(int i = 0; i < noutput_items; i++) {
-        if(d_pkt_count == 0) {
-          // compute hamming distance between desired access code and current 
data
-          uint64_t wrong_bits = 0;
-          uint64_t nwrong = d_threshold+1;
-
-          wrong_bits  = (d_data_reg ^ d_access_code) & d_mask;
-          volk_64u_popcnt(&nwrong, wrong_bits);
-
-          // shift in new data
-          d_data_reg = (d_data_reg << 1) | 
(gr::branchless_binary_slicer(in[i]) & 0x1);
-          if(nwrong <= d_threshold) {
-            if(VERBOSE)
-              std::cerr << "writing tag at sample " << abs_out_sample_cnt + i 
<< std::endl;
-            add_item_tag(0,                      // stream ID
-                         abs_out_sample_cnt + nprod, // sample
-                         d_key,                  // frame info
-                         pmt::from_long(nwrong), // data (number wrong)
-                         d_me);                  // block src id
+      int count = 0;
+      while(count < noutput_items) {
+        switch(d_state) {
+       case STATE_SYNC_SEARCH:    // Look for the access code correlation
 
-            // MAKE A TAG OUT OF THIS AND UPDATE OFFSET
-            add_item_tag(0,                         // stream ID
-                         abs_out_sample_cnt + nprod,    // sample
-                         d_pkt_key,                 // length key
-                         pmt::from_long(d_pkt_len), // length data
-                         d_me);                     // block src id
-            d_pkt_count = d_pkt_len;
-            d_data_reg = 0;
+         while(count < noutput_items) {
+            // shift in new data
+            d_data_reg = (d_data_reg << 1) | 
(gr::branchless_binary_slicer(in[count++]) & 0x1);
+
+            // compute hamming distance between desired access code and 
current data
+            uint64_t wrong_bits = 0;
+            uint64_t nwrong = d_threshold+1;
+
+            wrong_bits = (d_data_reg ^ d_access_code) & d_mask;
+            volk_64u_popcnt(&nwrong, wrong_bits);
+
+            if(nwrong <= d_threshold) {
+              enter_have_sync();
+              break;
+            }
           }
-        }
+          break;
+
+       case STATE_HAVE_SYNC:
+         while(count < noutput_items) {    // Shift bits one at a time into 
header
+            d_hdr_reg = (d_hdr_reg << 1) | 
(gr::branchless_binary_slicer(in[count++]) & 0x1);
+            d_hdr_count++;
 
-        if(d_pkt_count > 0) {
-          out[nprod] = in[i];
-          d_pkt_count--;
-          nprod++;
+            if(d_hdr_count == 32) {
+             // we have a full header, check to see if it has been received 
properly
+             if(header_ok()) {
+               int payload_len = header_payload();
+               enter_have_header(payload_len);
+              }
+             else {
+               enter_search();    // bad header
+              }
+              break;
+            }
+          }
+          break;
 
+       case STATE_HAVE_HEADER:
           if(d_pkt_count == 0) {
-            add_item_tag(0,
-                         abs_out_sample_cnt + i,
-                         pmt::intern("STOP"),
-                         pmt::from_long(abs_out_sample_cnt + nprod),
-                         d_me);
+            // MAKE A TAG OUT OF THIS AND UPDATE OFFSET
+            add_item_tag(0,                             // stream ID
+                         abs_out_sample_cnt + nprod,    // sample
+                         d_key,                         // length key
+                         pmt::from_long(d_pkt_len),     // length data
+                         d_me);                         // block src id
           }
+
+         while(count < noutput_items) {
+            if(d_pkt_count < d_pkt_len) {
+              out[nprod++] = in[count++];
+              d_pkt_count++;
+            }
+            else {
+              enter_search();
+              break;
+            }
+          }
+          break;
         }
       }
 
-      //std::cerr << "Producing data: " << nprod << std::endl;
       consume_each(noutput_items);
       return nprod;
     }
 
   } /* namespace digital */
 } /* namespace gr */
-
diff --git a/gr-digital/lib/correlate_access_code_ff_ts_impl.h 
b/gr-digital/lib/correlate_access_code_ff_ts_impl.h
index 861ade8..e96ab7f 100644
--- a/gr-digital/lib/correlate_access_code_ff_ts_impl.h
+++ b/gr-digital/lib/correlate_access_code_ff_ts_impl.h
@@ -32,6 +32,10 @@ namespace gr {
       public correlate_access_code_ff_ts
     {
     private:
+      enum state_t {STATE_SYNC_SEARCH, STATE_HAVE_SYNC, STATE_HAVE_HEADER};
+
+      state_t d_state;
+
       unsigned long long d_access_code;        // access code to locate start 
of packet
                                         //   access code is left justified in 
the word
       unsigned long long d_data_reg;   // used to look for access_code
@@ -40,14 +44,28 @@ namespace gr {
       unsigned int d_threshold;        // how many bits may be wrong in sync 
vector
       unsigned int d_len;               // the length of the access code
 
-      pmt::pmt_t d_key, d_me; //d_key is the tag name, d_me is the block name 
+ unique ID
-      pmt::pmt_t d_pkt_key;
+      unsigned long long d_hdr_reg;    // used to look for header
+      int d_hdr_count;
+
+      pmt::pmt_t d_key, d_me; // d_key is the tag name, d_me is the block name 
+ unique ID
       int d_pkt_len, d_pkt_count;
 
+      float d_fec_rate;
+      int   d_fec_extra;
+
+      void enter_search();
+      void enter_have_sync();
+      void enter_have_header(int payload_len);
+
+      bool header_ok();
+      int header_payload();
+
     public:
       correlate_access_code_ff_ts_impl(const std::string &access_code,
                                        int threshold,
-                                       const std::string &tag_name);
+                                       const std::string &tag_name,
+                                       float fec_rate=1,
+                                       int fec_extra=0);
       ~correlate_access_code_ff_ts_impl();
 
       int general_work(int noutput_items,
@@ -56,6 +74,12 @@ namespace gr {
                        gr_vector_void_star &output_items);
 
       bool set_access_code(const std::string &access_code);
+      void set_fec_rate(float rate);
+      void set_fec_extra(int extra);
+
+      unsigned long long access_code() const;
+      float fec_rate() const;
+      int fec_extra() const;
     };
 
   } /* namespace digital */



reply via email to

[Prev in Thread] Current Thread [Next in Thread]