summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Foster <bistromath@gmail.com>2014-05-07 16:41:51 -0700
committerJohnathan Corgan <johnathan@corganlabs.com>2014-05-09 13:52:29 -0700
commit5cd195341b0763b99b4e0462ee2387781bbf899d (patch)
treecdd9e409ea0cd5f88f19a1b2ca3f71e02beaa99c
parent8c97b7c379952c010c84cf8ae8a97fbfaac83bfd (diff)
gr-digital: update the HDLC blocks.
* HDLC deframer is now OVER 9000%! faster * No more correlate_access_code_tag req'd * Properly assign HDLC blocks to Packet Operators subgroup
-rw-r--r--gr-digital/grc/digital_hdlc_deframer_bp.xml7
-rw-r--r--gr-digital/include/gnuradio/digital/hdlc_deframer_bp.h11
-rw-r--r--gr-digital/include/gnuradio/digital/hdlc_framer_pb.h2
-rw-r--r--gr-digital/lib/hdlc_deframer_bp_impl.cc132
-rw-r--r--gr-digital/lib/hdlc_deframer_bp_impl.h16
-rwxr-xr-xgr-digital/python/digital/qa_hdlc_framer.py5
6 files changed, 73 insertions, 100 deletions
diff --git a/gr-digital/grc/digital_hdlc_deframer_bp.xml b/gr-digital/grc/digital_hdlc_deframer_bp.xml
index 41bd37c7ee..3e78b891df 100644
--- a/gr-digital/grc/digital_hdlc_deframer_bp.xml
+++ b/gr-digital/grc/digital_hdlc_deframer_bp.xml
@@ -3,12 +3,7 @@
<name>HDLC Deframer</name>
<key>digital_hdlc_deframer_bp</key>
<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>
+ <make>digital.hdlc_deframer_bp($min, $max)</make>
<param>
<name>Min length</name>
<key>min</key>
diff --git a/gr-digital/include/gnuradio/digital/hdlc_deframer_bp.h b/gr-digital/include/gnuradio/digital/hdlc_deframer_bp.h
index 191f294344..5a80670ddd 100644
--- a/gr-digital/include/gnuradio/digital/hdlc_deframer_bp.h
+++ b/gr-digital/include/gnuradio/digital/hdlc_deframer_bp.h
@@ -31,12 +31,9 @@ namespace gr {
/*!
* \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.
+ * binary blobs. Frames which do not pass CRC are rejected.
*
- * \ingroup digital
+ * \ingroup pkt_operators_blk
*
*/
class DIGITAL_API hdlc_deframer_bp : virtual public gr::sync_block
@@ -47,12 +44,10 @@ namespace gr {
/*!
* \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);
+ static sptr make(int length_min, int length_max);
};
} // namespace digital
diff --git a/gr-digital/include/gnuradio/digital/hdlc_framer_pb.h b/gr-digital/include/gnuradio/digital/hdlc_framer_pb.h
index d2931a9fff..9f77f61540 100644
--- a/gr-digital/include/gnuradio/digital/hdlc_framer_pb.h
+++ b/gr-digital/include/gnuradio/digital/hdlc_framer_pb.h
@@ -42,7 +42,7 @@ namespace gr {
* flowgraphs that stream continuously (anything using a USRP) this should
* not be an issue.
*
- * \ingroup digital
+ * \ingroup pkt_operators_blk
*
*/
class DIGITAL_API hdlc_framer_pb : virtual public gr::sync_block
diff --git a/gr-digital/lib/hdlc_deframer_bp_impl.cc b/gr-digital/lib/hdlc_deframer_bp_impl.cc
index 69f0f8c00d..12d7ec66bc 100644
--- a/gr-digital/lib/hdlc_deframer_bp_impl.cc
+++ b/gr-digital/lib/hdlc_deframer_bp_impl.cc
@@ -32,29 +32,31 @@ namespace gr {
namespace digital {
hdlc_deframer_bp::sptr
- hdlc_deframer_bp::make(const std::string frame_tag_name,
- int length_min=32,
+ hdlc_deframer_bp::make(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));
+ (new hdlc_deframer_bp_impl(length_min, length_max));
}
/*
* The private constructor
*/
- hdlc_deframer_bp_impl::hdlc_deframer_bp_impl(const std::string frame_tag_name,
- int length_min,
+ hdlc_deframer_bp_impl::hdlc_deframer_bp_impl(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"));
+ d_bytectr=0;
+ d_bitctr=0;
+ d_ones=0;
+ d_pktbuf = new unsigned char[length_max+2];
+ d_in_frame=false;
}
/*
@@ -64,39 +66,11 @@ namespace gr {
{
}
- //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>
- 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++) {
- output[i/8] |= (data[i]<<(i%8));
- }
- return output;
- }
-
unsigned int
- hdlc_deframer_bp_impl::crc_ccitt(std::vector<unsigned char> &data) {
+ hdlc_deframer_bp_impl::crc_ccitt(unsigned char *data, size_t len) {
unsigned int POLY=0x8408; //reflected 0x1021
unsigned short crc=0xFFFF;
- for(size_t i=0; i<data.size(); i++) {
+ for(size_t i=0; i<len; i++) {
crc ^= data[i];
for(size_t j=0; j<8; j++) {
if(crc&0x01) crc = (crc >> 1) ^ POLY;
@@ -112,49 +86,55 @@ namespace gr {
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));
-
- int end_pos = 0;
- while(frame_tags.size() > 0) {
- int start_pos = frame_tags[0].offset - abs_sample_cnt;
- if(frame_tags.size() == 1) return start_pos; //start here next time
- 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 > 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);
- 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);
+ unsigned char bit;
+ int n=0;
+ while (n < noutput_items) {
+ bit=*in;
+ if(d_ones>=5) {
+ if(bit) { //six ones is a frame delimiter
+ if(d_bytectr >= d_length_min) {
+ //check CRC, publish frame
+ unsigned short crc = d_pktbuf[d_bytectr-1] << 8
+ | d_pktbuf[d_bytectr-2];
+ unsigned short calc_crc = crc_ccitt(d_pktbuf, d_bytectr-2);
+ if (crc==calc_crc) {
+ pmt::pmt_t pdu(pmt::cons(pmt::PMT_NIL,
+ pmt::make_blob(&d_pktbuf[0], d_bytectr-2)));
+ message_port_pub(pmt::mp("out"), pdu);
+ }
+ else {
+ }
+ d_in_frame=false;
+ } else {
+ d_in_frame=true;
+ }
+ d_bitctr=0;
+ d_bytectr=0;
+ } else { //unstuff
+ }
+ } else { //not 5+ continuous ones
+ if(d_in_frame) {
+ if(d_bytectr > d_length_max) {
+ d_bytectr=0;
+ d_bitctr=0;
+ d_in_frame=false;
+ } else {
+ d_pktbuf[d_bytectr]>>=1;
+ if (bit) d_pktbuf[d_bytectr] |= 0x80;
+ d_bitctr++;
+ if (d_bitctr==8) {
+ d_bitctr=0;
+ d_bytectr++;
+ }
+ }
+ }
}
- frame_tags.erase(frame_tags.begin());
+ d_ones = (bit) ? d_ones+1 : 0;
+ in++;
+ n++;
}
- // Tell runtime system how many output items we produced.
- return end_pos;
+ return n;
}
-
} /* namespace digital */
} /* namespace gr */
diff --git a/gr-digital/lib/hdlc_deframer_bp_impl.h b/gr-digital/lib/hdlc_deframer_bp_impl.h
index de8f6b3db7..f7c4253b3d 100644
--- a/gr-digital/lib/hdlc_deframer_bp_impl.h
+++ b/gr-digital/lib/hdlc_deframer_bp_impl.h
@@ -31,14 +31,18 @@ namespace gr {
class hdlc_deframer_bp_impl : public hdlc_deframer_bp
{
private:
- 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);
+ size_t d_length_min;
+ size_t d_length_max;
+ size_t d_ones;
+ size_t d_bytectr;
+ size_t d_bitctr;
+ bool d_in_frame;
+ unsigned char *d_pktbuf;
+
+ unsigned int crc_ccitt(unsigned char *data, size_t len);
public:
- hdlc_deframer_bp_impl(const std::string frame_tag_name, int length_min, int length_max);
+ hdlc_deframer_bp_impl(int length_min, int length_max);
~hdlc_deframer_bp_impl();
// Where all the action really happens
diff --git a/gr-digital/python/digital/qa_hdlc_framer.py b/gr-digital/python/digital/qa_hdlc_framer.py
index f8d1923de1..6fed264546 100755
--- a/gr-digital/python/digital/qa_hdlc_framer.py
+++ b/gr-digital/python/digital/qa_hdlc_framer.py
@@ -39,10 +39,9 @@ class test_hdlc_framer(gr_unittest.TestCase):
npkts = 20
src_data = [0xFE, 0xDA, 0xAC, 0x29, 0x7F, 0xA2, 0x90, 0x0F, 0xF8]
frame = digital.hdlc_framer_pb("wat")
- corr = digital.correlate_access_code_tag_bb("01111110", 0, "frame")
- deframe = digital.hdlc_deframer_bp("frame", 32, 500)
+ deframe = digital.hdlc_deframer_bp(8, 500)
debug = blocks.message_debug()
- self.tb.connect(frame, corr, deframe)
+ self.tb.connect(frame, deframe)
self.tb.msg_connect(deframe, "out", debug, "store")
self.tb.start()
msg = pmt.cons(pmt.PMT_NIL, pmt.init_u8vector(len(src_data),src_data))