diff options
author | Nick Foster <bistromath@gmail.com> | 2014-05-07 16:41:51 -0700 |
---|---|---|
committer | Johnathan Corgan <johnathan@corganlabs.com> | 2014-05-09 13:52:29 -0700 |
commit | 5cd195341b0763b99b4e0462ee2387781bbf899d (patch) | |
tree | cdd9e409ea0cd5f88f19a1b2ca3f71e02beaa99c | |
parent | 8c97b7c379952c010c84cf8ae8a97fbfaac83bfd (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.xml | 7 | ||||
-rw-r--r-- | gr-digital/include/gnuradio/digital/hdlc_deframer_bp.h | 11 | ||||
-rw-r--r-- | gr-digital/include/gnuradio/digital/hdlc_framer_pb.h | 2 | ||||
-rw-r--r-- | gr-digital/lib/hdlc_deframer_bp_impl.cc | 132 | ||||
-rw-r--r-- | gr-digital/lib/hdlc_deframer_bp_impl.h | 16 | ||||
-rwxr-xr-x | gr-digital/python/digital/qa_hdlc_framer.py | 5 |
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)) |