[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] [gnuradio] 09/17: Add matching HDLC framer. Fix defram
From: |
git |
Subject: |
[Commit-gnuradio] [gnuradio] 09/17: Add matching HDLC framer. Fix deframer max/min. |
Date: |
Mon, 31 Mar 2014 20:15:53 +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 655646c7bb84a14341dc1e06f955103aa28464c5
Author: Nick Foster <address@hidden>
Date: Thu Mar 27 15:45:42 2014 -0700
Add matching HDLC framer. Fix deframer max/min.
---
gr-digital/grc/digital_hdlc_framer_pb.xml | 21 +++
gr-digital/include/gnuradio/digital/CMakeLists.txt | 1 +
.../gnuradio/digital/hdlc_framer_pb.h} | 48 +++---
gr-digital/lib/CMakeLists.txt | 1 +
gr-digital/lib/hdlc_deframer_bp_impl.cc | 10 +-
gr-digital/lib/hdlc_deframer_bp_impl.h | 2 +
gr-digital/lib/hdlc_framer_pb_impl.cc | 184 +++++++++++++++++++++
...lc_deframer_bp_impl.h => hdlc_framer_pb_impl.h} | 23 +--
gr-digital/swig/digital_swig.i | 3 +
9 files changed, 258 insertions(+), 35 deletions(-)
diff --git a/gr-digital/grc/digital_hdlc_framer_pb.xml
b/gr-digital/grc/digital_hdlc_framer_pb.xml
new file mode 100644
index 0000000..540764c
--- /dev/null
+++ b/gr-digital/grc/digital_hdlc_framer_pb.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<block>
+ <name>hdlc_framer_pb</name>
+ <key>digital_hdlc_framer_pb</key>
+ <category>digital</category>
+ <import>from gnuradio import digital</import>
+ <make>digital.hdlc_framer_pb($frame_tag_name)</make>
+ <param>
+ <name>Frame tag name</name>
+ <key>frame_tag_name</key>
+ <type>string</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>message</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>byte</type>
+ </source>
+</block>
diff --git a/gr-digital/include/gnuradio/digital/CMakeLists.txt
b/gr-digital/include/gnuradio/digital/CMakeLists.txt
index 84a7cee..63b65b9 100644
--- a/gr-digital/include/gnuradio/digital/CMakeLists.txt
+++ b/gr-digital/include/gnuradio/digital/CMakeLists.txt
@@ -102,6 +102,7 @@ install(FILES
glfsr_source_b.h
glfsr_source_f.h
hdlc_deframer_bp.h
+ hdlc_framer_pb.h
header_payload_demux.h
kurtotic_equalizer_cc.h
lfsr.h
diff --git a/gr-digital/lib/hdlc_deframer_bp_impl.h
b/gr-digital/include/gnuradio/digital/hdlc_framer_pb.h
similarity index 50%
copy from gr-digital/lib/hdlc_deframer_bp_impl.h
copy to gr-digital/include/gnuradio/digital/hdlc_framer_pb.h
index a8baf81..f516628 100644
--- a/gr-digital/lib/hdlc_deframer_bp_impl.h
+++ b/gr-digital/include/gnuradio/digital/hdlc_framer_pb.h
@@ -1,52 +1,58 @@
/* -*- 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
+#ifndef INCLUDED_DIGITAL_HDLC_FRAMER_PB_H
+#define INCLUDED_DIGITAL_HDLC_FRAMER_PB_H
-#include <gnuradio/digital/hdlc_deframer_bp.h>
+#include <gnuradio/digital/api.h>
+#include <gnuradio/sync_block.h>
namespace gr {
namespace digital {
- class hdlc_deframer_bp_impl : public hdlc_deframer_bp
+ /*!
+ * \brief HDLC framer which takes in PDU blobs (char data) and outputs HDLC
+ * frames as unpacked bits, with CRC and bit stuffing added. The first
sample
+ * of the frame is tagged with the tag frame_tag_name and includes a
+ * length field for tagged_stream use.
+ *
+ * \ingroup digital
+ *
+ */
+ class DIGITAL_API hdlc_framer_pb : virtual public gr::sync_block
{
- 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);
+ typedef boost::shared_ptr<hdlc_framer_pb> sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of digital::hdlc_framer.
+ *
+ * \param frame_tag_name: The tag to add to the first sample of each
frame.
+ */
+ static sptr make(const std::string frame_tag_name);
};
} // namespace digital
} // namespace gr
-#endif /* INCLUDED_DIGITAL_HDLC_DEFRAMER_BP_IMPL_H */
+#endif /* INCLUDED_DIGITAL_HDLC_FRAMER_PB_H */
diff --git a/gr-digital/lib/CMakeLists.txt b/gr-digital/lib/CMakeLists.txt
index 709c74c..00200d1 100644
--- a/gr-digital/lib/CMakeLists.txt
+++ b/gr-digital/lib/CMakeLists.txt
@@ -138,6 +138,7 @@ list(APPEND digital_sources
glfsr_source_b_impl.cc
glfsr_source_f_impl.cc
hdlc_deframer_bp_impl.cc
+ hdlc_framer_pb_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
index d5fd203..c0e52cb 100644
--- a/gr-digital/lib/hdlc_deframer_bp_impl.cc
+++ b/gr-digital/lib/hdlc_deframer_bp_impl.cc
@@ -82,7 +82,8 @@ namespace gr {
//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>
+ hdlc_deframer_bp_impl::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++) {
@@ -91,7 +92,8 @@ namespace gr {
return output;
}
- unsigned int crc_ccitt(std::vector<unsigned char> &data) {
+ unsigned int
+ hdlc_deframer_bp_impl::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++) {
@@ -121,8 +123,8 @@ namespace gr {
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;
+ if(pkt_len > d_length_max) return end_pos; //arbitrary, too long for a
real pkt
+ if(pkt_len <= d_length_min) return end_pos;
//get bit array
std::vector<unsigned char> pkt_bits(pkt_len);
diff --git a/gr-digital/lib/hdlc_deframer_bp_impl.h
b/gr-digital/lib/hdlc_deframer_bp_impl.h
index a8baf81..de8f6b3 100644
--- a/gr-digital/lib/hdlc_deframer_bp_impl.h
+++ b/gr-digital/lib/hdlc_deframer_bp_impl.h
@@ -34,6 +34,8 @@ namespace gr {
std::string d_frame_tag_name;
int d_length_min;
int d_length_max;
+ unsigned int crc_ccitt(std::vector<unsigned char> &data);
+ std::vector<unsigned char> pack(std::vector<unsigned char> &pkt);
public:
hdlc_deframer_bp_impl(const std::string frame_tag_name, int length_min,
int length_max);
diff --git a/gr-digital/lib/hdlc_framer_pb_impl.cc
b/gr-digital/lib/hdlc_framer_pb_impl.cc
new file mode 100644
index 0000000..0111f60
--- /dev/null
+++ b/gr-digital/lib/hdlc_framer_pb_impl.cc
@@ -0,0 +1,184 @@
+/* -*- 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_framer_pb_impl.h"
+#include <iostream>
+
+namespace gr {
+ namespace digital {
+
+ hdlc_framer_pb::sptr
+ hdlc_framer_pb::make(const std::string frame_tag_name)
+ {
+ return gnuradio::get_initial_sptr
+ (new hdlc_framer_pb_impl(frame_tag_name));
+ }
+
+ /*
+ * The private constructor
+ */
+ hdlc_framer_pb_impl::hdlc_framer_pb_impl(const std::string frame_tag_name)
+ : gr::sync_block("hdlc_framer_pb",
+ gr::io_signature::make(0, 0, 0),
+ gr::io_signature::make(1, 1, sizeof(unsigned char)))
+ {
+ message_port_register_in(pmt::mp("in"));
+ d_frame_tag = pmt::string_to_symbol(frame_tag_name);
+ std::stringstream str;
+ str << name() << unique_id();
+ d_me = pmt::string_to_symbol(str.str());
+ }
+
+ /*
+ * Our virtual destructor.
+ */
+ hdlc_framer_pb_impl::~hdlc_framer_pb_impl()
+ {
+ }
+
+ //bit stuff
+ void
+ hdlc_framer_pb_impl::stuff(std::vector<unsigned char> &pkt) {
+ int consec = 0;
+ for(size_t i=0; i < pkt.size(); i++) {
+ if(consec == 5) {
+ pkt.insert(pkt.begin()+i, 0);
+ consec = 0;
+ }
+ if(pkt[i]==1) consec++;
+ else consec=0;
+ }
+ }
+
+ //unpack packed (8 bits per byte) into bits, in LSbit order.
+ //TODO: handle non-multiple-of-8 bit lengths (pad low)
+ std::vector<unsigned char>
+ hdlc_framer_pb_impl::unpack(std::vector<unsigned char> &data) {
+ std::vector<unsigned char> output(data.size()*8, 0);
+ for(size_t i=0; i<data.size(); i++) {
+ for(size_t j=0; j<8; j++) {
+ output[i*8+j] = (data[i] >> j) & 1;
+ }
+ }
+ return output;
+ }
+
+ unsigned int
+ hdlc_framer_pb_impl::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_framer_pb_impl::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ unsigned char *out = (unsigned char *) output_items[0];
+
+ //send leftovers one chunk at a time.
+ //it'd be more efficient to send as much as possible, i.e.
+ //partial packets., but if we're to preserve tag boundaries
+ //this is much, much simpler.
+ int oidx = 0;
+ while(d_leftovers.size() > 0) {
+ if(noutput_items < (oidx+d_leftovers[0].size())) return oidx;
+ memcpy(out+oidx, &d_leftovers[0][0], d_leftovers[0].size());
+ //start tag
+ add_item_tag(0,
+ nitems_written(0)+oidx,
+ d_frame_tag,
+ pmt::from_long(d_leftovers[0].size()),
+ d_me);
+ oidx += d_leftovers[0].size();
+ d_leftovers.erase(d_leftovers.begin());
+ }
+
+ //get PDU
+ pmt::pmt_t msg(delete_head_nowait(pmt::string_to_symbol("in")));
+ if(msg.get() == NULL) return 0;
+
+ pmt::pmt_t len(pmt::car(msg)); //TODO for non-mult-8 nbits
+ pmt::pmt_t blob(pmt::cdr(msg));
+ if(!pmt::is_blob(blob))
+ throw std::runtime_error("HDLC framer: PMT must be blob");
+ std::vector<unsigned char> pkt(pmt::blob_length(blob));
+ memcpy(&pkt[0], (const unsigned char *) pmt::blob_data(blob),
pkt.size());
+
+ //calc CRC
+ unsigned int crc = crc_ccitt(pkt);
+
+ //append CRC
+ pkt.insert(pkt.end(), crc & 0xFF);
+ pkt.insert(pkt.end(), (crc >> 8) & 0xFF);
+
+ //unpack to LSb bits
+ std::vector<unsigned char> pkt_bits = unpack(pkt);
+
+ //bitstuff
+ stuff(pkt_bits);
+
+ //add framing
+ const unsigned char framing[] = {0,1,1,1,1,1,1,0};
+ std::vector<unsigned char> framing_vec(framing,
framing+sizeof(framing));
+ pkt_bits.insert(pkt_bits.begin(), framing_vec.begin(),
framing_vec.end());
+ pkt_bits.insert(pkt_bits.end(), framing_vec.begin(),
framing_vec.end());
+
+ //make sure we have the space. unfortunately, we didn't know
+ //until now, since the stuffing must be calculated. we'll just
+ //save it for next time.
+ if(noutput_items < (oidx+pkt_bits.size())) {
+ d_leftovers.insert(d_leftovers.end(), pkt_bits);
+ return oidx;
+ }
+
+ //produce
+ memcpy(out+oidx, &pkt_bits[0], pkt_bits.size());
+ //start tag
+ add_item_tag(0,
+ nitems_written(0)+oidx,
+ d_frame_tag,
+ pmt::from_long(pkt_bits.size()),
+ d_me);
+ oidx += pkt_bits.size();
+
+ //return # output bits
+ return oidx;
+ }
+
+ } /* namespace digital */
+} /* namespace gr */
+
diff --git a/gr-digital/lib/hdlc_deframer_bp_impl.h
b/gr-digital/lib/hdlc_framer_pb_impl.h
similarity index 63%
copy from gr-digital/lib/hdlc_deframer_bp_impl.h
copy to gr-digital/lib/hdlc_framer_pb_impl.h
index a8baf81..90d51a9 100644
--- a/gr-digital/lib/hdlc_deframer_bp_impl.h
+++ b/gr-digital/lib/hdlc_framer_pb_impl.h
@@ -20,24 +20,27 @@
* Boston, MA 02110-1301, USA.
*/
-#ifndef INCLUDED_DIGITAL_HDLC_DEFRAMER_BP_IMPL_H
-#define INCLUDED_DIGITAL_HDLC_DEFRAMER_BP_IMPL_H
+#ifndef INCLUDED_DIGITAL_HDLC_FRAMER_PB_IMPL_H
+#define INCLUDED_DIGITAL_HDLC_FRAMER_PB_IMPL_H
-#include <gnuradio/digital/hdlc_deframer_bp.h>
+#include <gnuradio/digital/hdlc_framer_pb.h>
+#include <pmt/pmt.h>
namespace gr {
namespace digital {
- class hdlc_deframer_bp_impl : public hdlc_deframer_bp
+ class hdlc_framer_pb_impl : public hdlc_framer_pb
{
private:
- std::string d_frame_tag_name;
- int d_length_min;
- int d_length_max;
+ std::vector<std::vector<unsigned char> > d_leftovers;
+ pmt::pmt_t d_frame_tag, d_me;
+ unsigned int crc_ccitt(std::vector<unsigned char> &data);
+ std::vector<unsigned char> unpack(std::vector<unsigned char> &pkt);
+ void stuff(std::vector<unsigned char> &pkt);
public:
- hdlc_deframer_bp_impl(const std::string frame_tag_name, int length_min,
int length_max);
- ~hdlc_deframer_bp_impl();
+ hdlc_framer_pb_impl(const std::string frame_tag_name);
+ ~hdlc_framer_pb_impl();
// Where all the action really happens
int work(int noutput_items,
@@ -48,5 +51,5 @@ namespace gr {
} // namespace digital
} // namespace gr
-#endif /* INCLUDED_DIGITAL_HDLC_DEFRAMER_BP_IMPL_H */
+#endif /* INCLUDED_DIGITAL_HDLC_FRAMER_PB_IMPL_H */
diff --git a/gr-digital/swig/digital_swig.i b/gr-digital/swig/digital_swig.i
index 729450e..ab9794a 100644
--- a/gr-digital/swig/digital_swig.i
+++ b/gr-digital/swig/digital_swig.i
@@ -68,6 +68,7 @@
#include "gnuradio/digital/glfsr_source_b.h"
#include "gnuradio/digital/glfsr_source_f.h"
#include "gnuradio/digital/hdlc_deframer_bp.h"
+#include "gnuradio/digital/hdlc_framer_pb.h"
#include "gnuradio/digital/header_payload_demux.h"
#include "gnuradio/digital/kurtotic_equalizer_cc.h"
#include "gnuradio/digital/lfsr.h"
@@ -140,6 +141,7 @@
%include "gnuradio/digital/glfsr_source_b.h"
%include "gnuradio/digital/glfsr_source_f.h"
%include "gnuradio/digital/hdlc_deframer_bp.h"
+%include "gnuradio/digital/hdlc_framer_pb.h"
%include "gnuradio/digital/header_payload_demux.h"
%include "gnuradio/digital/kurtotic_equalizer_cc.h"
%include "gnuradio/digital/lfsr.h"
@@ -206,6 +208,7 @@ 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, hdlc_framer_pb);
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);
- [Commit-gnuradio] [gnuradio] branch master updated (a8f73d8 -> 7390c25), git, 2014/03/31
- [Commit-gnuradio] [gnuradio] 01/17: runtime: restoring sanity to pmt.is_blob(), git, 2014/03/31
- [Commit-gnuradio] [gnuradio] 09/17: Add matching HDLC framer. Fix deframer max/min.,
git <=
- [Commit-gnuradio] [gnuradio] 04/17: blocks: hide 'ignore tag' param for 'throttle' block in GRC if it's the default value (i.e. old look before param was added), git, 2014/03/31
- [Commit-gnuradio] [gnuradio] 11/17: Merge remote-tracking branch 'osh/pmt_fix', git, 2014/03/31
- [Commit-gnuradio] [gnuradio] 02/17: Add HDLC deframer to gr-digital. Input unpacked bits, output PDU binary blobs., git, 2014/03/31
- [Commit-gnuradio] [gnuradio] 07/17: blocks: added 'MTU' and 'tcp_no_delay' params for 'socket_pdu' (and GRC option), applied MTU (buffer size) to TCP/UDP send, separate TCP/UDP server endpoint resolvers for empty/0.0.0.0 Host param (listen on all interfaces) Whitespace clean-up., git, 2014/03/31
- [Commit-gnuradio] [gnuradio] 06/17: blocks: added 'MTU' (buffer size) & 'no_delay' params to 'tcp_connection' (no longer uses fixed buffer), git, 2014/03/31
- [Commit-gnuradio] [gnuradio] 16/17: Merge remote-tracking branch 'balint/3.7-1/socket_pdu_improvements', git, 2014/03/31
- [Commit-gnuradio] [gnuradio] 05/17: digital: added 'byte' IO format, git, 2014/03/31
- [Commit-gnuradio] [gnuradio] 08/17: cmake: updated max ver for FindQwt to 6.2.0 (Qwt compiled direct from their source tree worked with trondeau's qt_number_sink test FG), git, 2014/03/31
- [Commit-gnuradio] [gnuradio] 10/17: Add QA code to HDLC framer/deframer., git, 2014/03/31
- [Commit-gnuradio] [gnuradio] 17/17: Merge remote-tracking branch 'balint/3.7-1/findqwt_max_ver_6.2.0', git, 2014/03/31