commit-gnuradio
[Top][All Lists]
Advanced

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

[Commit-gnuradio] [gnuradio] 02/17: Add HDLC deframer to gr-digital. Inp


From: git
Subject: [Commit-gnuradio] [gnuradio] 02/17: Add HDLC deframer to gr-digital. Input unpacked bits, output PDU binary blobs.
Date: Mon, 31 Mar 2014 20:15:52 +0000 (UTC)

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

jcorgan pushed a commit to branch master
in repository gnuradio.

commit aacdf167e5c21e62e36c9d3088ec207e177b212a
Author: Nick Foster <address@hidden>
Date:   Wed Mar 26 18:11:15 2014 -0700

    Add HDLC deframer to gr-digital. Input unpacked bits, output PDU binary
    blobs.
---
 gr-digital/grc/digital_hdlc_deframer_bp.xml        |  33 +++++
 gr-digital/include/gnuradio/digital/CMakeLists.txt |   1 +
 .../include/gnuradio/digital/hdlc_deframer_bp.h    |  62 ++++++++
 gr-digital/lib/CMakeLists.txt                      |   1 +
 gr-digital/lib/hdlc_deframer_bp_impl.cc            | 156 +++++++++++++++++++++
 gr-digital/lib/hdlc_deframer_bp_impl.h             |  52 +++++++
 gr-digital/swig/digital_swig.i                     |   3 +
 7 files changed, 308 insertions(+)

diff --git a/gr-digital/grc/digital_hdlc_deframer_bp.xml 
b/gr-digital/grc/digital_hdlc_deframer_bp.xml
new file mode 100644
index 0000000..4609d21
--- /dev/null
+++ b/gr-digital/grc/digital_hdlc_deframer_bp.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<block>
+  <name>hdlc_deframer_bp</name>
+  <key>digital_hdlc_deframer_bp</key>
+  <category>digital</category>
+  <import>from gnuradio import digital</import>
+  <make>digital.hdlc_deframer_bp($frame_tag_name, $min, $max)</make>
+  <param>
+    <name>Frame tag name</name>
+    <key>frame_tag_name</key>
+    <type>string</type>
+  </param>
+  <param>
+    <name>Min length</name>
+    <key>min</key>
+    <value>32</value>
+    <type>int</type>
+  </param>
+  <param>
+    <name>Max length</name>
+    <key>max</key>
+    <value>500</value>
+    <type>int</type>
+  </param>
+  <sink>
+    <name>in</name>
+    <type>byte</type>
+  </sink>
+  <source>
+    <name>out</name>
+    <type>message</type>
+  </source>
+</block>
diff --git a/gr-digital/include/gnuradio/digital/CMakeLists.txt 
b/gr-digital/include/gnuradio/digital/CMakeLists.txt
index 4d50f42..84a7cee 100644
--- a/gr-digital/include/gnuradio/digital/CMakeLists.txt
+++ b/gr-digital/include/gnuradio/digital/CMakeLists.txt
@@ -101,6 +101,7 @@ install(FILES
     glfsr.h
     glfsr_source_b.h
     glfsr_source_f.h
+    hdlc_deframer_bp.h
     header_payload_demux.h
     kurtotic_equalizer_cc.h
     lfsr.h
diff --git a/gr-digital/include/gnuradio/digital/hdlc_deframer_bp.h 
b/gr-digital/include/gnuradio/digital/hdlc_deframer_bp.h
new file mode 100644
index 0000000..191f294
--- /dev/null
+++ b/gr-digital/include/gnuradio/digital/hdlc_deframer_bp.h
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 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_DIGITAL_HDLC_DEFRAMER_BP_H
+#define INCLUDED_DIGITAL_HDLC_DEFRAMER_BP_H
+
+#include <gnuradio/digital/api.h>
+#include <gnuradio/sync_block.h>
+
+namespace gr {
+  namespace digital {
+
+    /*!
+     * \brief HDLC deframer which takes in unpacked bits, and outputs PDU 
+     * binary blobs. This is intended for use with the 
+     * correlate_access_code_tag_bb block, which should have an access code
+     * of "01111110" for use with HDLC frames. Frames which do not pass CRC are
+     * rejected.
+     *
+     * \ingroup digital
+     *
+     */
+    class DIGITAL_API hdlc_deframer_bp : virtual public gr::sync_block
+    {
+     public:
+      typedef boost::shared_ptr<hdlc_deframer_bp> sptr;
+
+      /*!
+       * \brief Return a shared_ptr to a new instance of 
digital::hdlc_deframer.
+       *
+       * \param frame_tag_name: The tag name from an upstream 
+       * correlate_access_code_tag_bb block.
+       * \param length_min: Minimum frame size (default: 32)
+       * \param length_max: Maximum frame size (default: 500)
+       */
+      static sptr make(const std::string frame_tag_name, int length_min, int 
length_max);
+    };
+
+  } // namespace digital
+} // namespace gr
+
+#endif /* INCLUDED_DIGITAL_HDLC_DEFRAMER_BP_H */
+
diff --git a/gr-digital/lib/CMakeLists.txt b/gr-digital/lib/CMakeLists.txt
index 509a9a5..709c74c 100644
--- a/gr-digital/lib/CMakeLists.txt
+++ b/gr-digital/lib/CMakeLists.txt
@@ -137,6 +137,7 @@ list(APPEND digital_sources
     glfsr.cc
     glfsr_source_b_impl.cc
     glfsr_source_f_impl.cc
+    hdlc_deframer_bp_impl.cc
     header_payload_demux_impl.cc
     kurtotic_equalizer_cc_impl.cc
     lms_dd_equalizer_cc_impl.cc
diff --git a/gr-digital/lib/hdlc_deframer_bp_impl.cc 
b/gr-digital/lib/hdlc_deframer_bp_impl.cc
new file mode 100644
index 0000000..d5fd203
--- /dev/null
+++ b/gr-digital/lib/hdlc_deframer_bp_impl.cc
@@ -0,0 +1,156 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 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/io_signature.h>
+#include <gnuradio/tags.h>
+#include "hdlc_deframer_bp_impl.h"
+
+namespace gr {
+  namespace digital {
+
+    hdlc_deframer_bp::sptr
+    hdlc_deframer_bp::make(const std::string frame_tag_name,
+                           int length_min=32,
+                           int length_max=500)
+    {
+      return gnuradio::get_initial_sptr
+        (new hdlc_deframer_bp_impl(frame_tag_name, length_min, length_max));
+    }
+
+    /*
+     * The private constructor
+     */
+    hdlc_deframer_bp_impl::hdlc_deframer_bp_impl(const std::string 
frame_tag_name,
+                                                 int length_min,
+                                                 int length_max)
+      : gr::sync_block("hdlc_deframer_bp",
+              gr::io_signature::make(1, 1, sizeof(unsigned char)),
+              gr::io_signature::make(0, 0, 0)),
+        d_frame_tag_name(frame_tag_name),
+        d_length_min(length_min),
+        d_length_max(length_max)
+    {
+        set_output_multiple(length_max*2);
+        message_port_register_out(pmt::mp("out"));
+    }
+
+    /*
+     * Our virtual destructor.
+     */
+    hdlc_deframer_bp_impl::~hdlc_deframer_bp_impl()
+    {
+    }
+
+    //undo HDLC bit stuffing operation.
+    static void unstuff(std::vector<unsigned char> &pkt) {
+        int consec = 0;
+        for(size_t i=0; i<pkt.size(); i++) {
+            if(pkt[i]) {
+                consec++;
+            } else {
+                if(consec == 5) {
+                    pkt.erase(pkt.begin()+i);
+                    i--;
+                }
+                consec = 0;
+            }
+        }
+    }
+
+    //pack unpacked (1 bit per byte) data into bytes, in reverse bit order
+    //we reverse the bit order because HDLC uses LSbit format.
+    std::vector<unsigned char> pack(std::vector<unsigned char> &data)
+    {
+        std::vector<unsigned char> output(std::ceil(data.size()/8.0f), 0);
+        for(size_t i=0; i<data.size(); i++) {
+            output[i/8] |= (data[i]<<(i%8));
+        }
+        return output;
+    }
+
+    unsigned int crc_ccitt(std::vector<unsigned char> &data) {
+        unsigned int POLY=0x8408; //reflected 0x1021
+        unsigned short crc=0xFFFF;
+        for(size_t i=0; i<data.size(); i++) {
+            crc ^= data[i];
+            for(size_t j=0; j<8; j++) {
+                if(crc&0x01) crc = (crc >> 1) ^ POLY;
+                else         crc = (crc >> 1);
+            }
+        }
+        return crc ^ 0xFFFF;
+    }
+
+    int
+    hdlc_deframer_bp_impl::work(int noutput_items,
+                                gr_vector_const_void_star &input_items,
+                                gr_vector_void_star &output_items)
+    {
+        const unsigned char *in = (const unsigned char *) input_items[0];
+
+        //look for frame delimiter tags
+        std::vector<gr::tag_t> frame_tags;
+        uint64_t abs_sample_cnt = nitems_read(0);
+        get_tags_in_range(frame_tags, 0, abs_sample_cnt, abs_sample_cnt + 
noutput_items, pmt::string_to_symbol(d_frame_tag_name));
+
+        if(frame_tags.size() == 0) return noutput_items;
+        int start_pos = frame_tags[0].offset - abs_sample_cnt;
+        if(frame_tags.size() == 1) return start_pos; //start here next time
+        int end_pos   = frame_tags[1].offset - abs_sample_cnt;
+        int pkt_len   = frame_tags[1].offset - frame_tags[0].offset - 8; 
//omit EOF delim
+        if(pkt_len > 500) return end_pos; //arbitrary, too long for a real pkt
+        if(pkt_len <= 32)  return end_pos;
+
+        //get bit array
+        std::vector<unsigned char> pkt_bits(pkt_len);
+        memcpy(&pkt_bits[0], &in[start_pos], pkt_bits.size());
+
+        unstuff(pkt_bits);
+
+        //pack into bytes (and correct bit order)
+        std::vector<unsigned char> pkt_bytes = pack(pkt_bits);
+
+        //strip off the CRC
+        unsigned int crc = (int(pkt_bytes[pkt_bytes.size()-1]) << 8)
+                         + pkt_bytes[pkt_bytes.size()-2];
+        pkt_bytes.erase(pkt_bytes.end()-2, pkt_bytes.end());
+        unsigned int calc_crc = crc_ccitt(pkt_bytes);
+
+        if(crc == calc_crc) {
+            //publish
+            //TODO manage padding
+            pmt::pmt_t pdu(pmt::cons(pmt::PMT_NIL,
+                                     pmt::make_blob(&pkt_bytes[0], 
pkt_bytes.size())));
+            message_port_pub(pmt::mp("out"), pdu);
+        }
+
+        // Tell runtime system how many output items we produced.
+        return end_pos;
+    }
+
+  } /* namespace digital */
+} /* namespace gr */
+
diff --git a/gr-digital/lib/hdlc_deframer_bp_impl.h 
b/gr-digital/lib/hdlc_deframer_bp_impl.h
new file mode 100644
index 0000000..a8baf81
--- /dev/null
+++ b/gr-digital/lib/hdlc_deframer_bp_impl.h
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 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_DIGITAL_HDLC_DEFRAMER_BP_IMPL_H
+#define INCLUDED_DIGITAL_HDLC_DEFRAMER_BP_IMPL_H
+
+#include <gnuradio/digital/hdlc_deframer_bp.h>
+
+namespace gr {
+  namespace digital {
+
+    class hdlc_deframer_bp_impl : public hdlc_deframer_bp
+    {
+     private:
+        std::string d_frame_tag_name;
+        int d_length_min;
+        int d_length_max;
+
+     public:
+      hdlc_deframer_bp_impl(const std::string frame_tag_name, int length_min, 
int length_max);
+      ~hdlc_deframer_bp_impl();
+
+      // Where all the action really happens
+      int work(int noutput_items,
+              gr_vector_const_void_star &input_items,
+              gr_vector_void_star &output_items);
+    };
+
+  } // namespace digital
+} // namespace gr
+
+#endif /* INCLUDED_DIGITAL_HDLC_DEFRAMER_BP_IMPL_H */
+
diff --git a/gr-digital/swig/digital_swig.i b/gr-digital/swig/digital_swig.i
index 5a0cb4f..729450e 100644
--- a/gr-digital/swig/digital_swig.i
+++ b/gr-digital/swig/digital_swig.i
@@ -67,6 +67,7 @@
 #include "gnuradio/digital/framer_sink_1.h"
 #include "gnuradio/digital/glfsr_source_b.h"
 #include "gnuradio/digital/glfsr_source_f.h"
+#include "gnuradio/digital/hdlc_deframer_bp.h"
 #include "gnuradio/digital/header_payload_demux.h"
 #include "gnuradio/digital/kurtotic_equalizer_cc.h"
 #include "gnuradio/digital/lfsr.h"
@@ -138,6 +139,7 @@
 %include "gnuradio/digital/framer_sink_1.h"
 %include "gnuradio/digital/glfsr_source_b.h"
 %include "gnuradio/digital/glfsr_source_f.h"
+%include "gnuradio/digital/hdlc_deframer_bp.h"
 %include "gnuradio/digital/header_payload_demux.h"
 %include "gnuradio/digital/kurtotic_equalizer_cc.h"
 %include "gnuradio/digital/lfsr.h"
@@ -203,6 +205,7 @@ GR_SWIG_BLOCK_MAGIC2(digital, fll_band_edge_cc);
 GR_SWIG_BLOCK_MAGIC2(digital, framer_sink_1);
 GR_SWIG_BLOCK_MAGIC2(digital, glfsr_source_b);
 GR_SWIG_BLOCK_MAGIC2(digital, glfsr_source_f);
+GR_SWIG_BLOCK_MAGIC2(digital, hdlc_deframer_bp);
 GR_SWIG_BLOCK_MAGIC2(digital, header_payload_demux);
 GR_SWIG_BLOCK_MAGIC2(digital, kurtotic_equalizer_cc);
 GR_SWIG_BLOCK_MAGIC2(digital, lms_dd_equalizer_cc);



reply via email to

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