GNU Radio v3.6.2-149-ga6d285d9 C++ API
digital_packet_sink.h
Go to the documentation of this file.
00001 /* -*- c++ -*- */
00002 /*
00003  * Copyright 2005,2012 Free Software Foundation, Inc.
00004  *
00005  * This file is part of GNU Radio
00006  *
00007  * GNU Radio is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 3, or (at your option)
00010  * any later version.
00011  *
00012  * GNU Radio is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with GNU Radio; see the file COPYING.  If not, write to
00019  * the Free Software Foundation, Inc., 51 Franklin Street,
00020  * Boston, MA 02110-1301, USA.
00021  */
00022 
00023 #ifndef INCLUDED_GR_PACKET_SINK_H
00024 #define INCLUDED_GR_PACKET_SINK_H
00025 
00026 #include <digital_api.h>
00027 #include <gr_sync_block.h>
00028 #include <gr_msg_queue.h>
00029 
00030 class digital_packet_sink;
00031 typedef boost::shared_ptr<digital_packet_sink> digital_packet_sink_sptr;
00032 
00033 DIGITAL_API digital_packet_sink_sptr
00034 digital_make_packet_sink(const std::vector<unsigned char>& sync_vector,
00035                          gr_msg_queue_sptr target_queue,
00036                          int threshold = -1);                   // -1 -> use default
00037 
00038 /*!
00039  * \brief process received  bits looking for packet sync, header, and process bits into packet
00040  * \ingroup sink_blk
00041  *
00042  * input: stream of symbols to be sliced.
00043  * 
00044  * output: none. Pushes assembled packet into target queue
00045  *
00046  * The packet sink takes in a stream of binary symbols that are sliced
00047  * around 0. The bits are then checked for the \p sync_vector to
00048  * determine find and decode the packet. It then expects a fixed
00049  * length header of 2 16-bit shorts containing the payload length,
00050  * followed by the payload. If the 2 16-bit shorts are not identical,
00051  * this packet is ignored. Better algs are welcome.
00052  *
00053  * This block is not very useful anymore as it only works with 2-level
00054  * modulations such as BPSK or GMSK. The block can generally be
00055  * replaced with a correlate access code and frame sink blocks.
00056  *
00057  * \param sync_vector The synchronization vector as a vector of 1's and 0's.
00058  * \param target_queue The message queue that packets are sent to.
00059  * \param threshold Number of bits that can be incorrect in the \p sync_vector.
00060  */
00061 class DIGITAL_API digital_packet_sink : public gr_sync_block
00062 {
00063   friend DIGITAL_API digital_packet_sink_sptr
00064     digital_make_packet_sink(const std::vector<unsigned char>& sync_vector,
00065                              gr_msg_queue_sptr target_queue,
00066                              int threshold);
00067 
00068  private:
00069   enum state_t {STATE_SYNC_SEARCH, STATE_HAVE_SYNC, STATE_HAVE_HEADER};
00070 
00071   static const int MAX_PKT_LEN    = 4096;
00072   static const int HEADERBITLEN   = 32;
00073 
00074   gr_msg_queue_sptr  d_target_queue;            // where to send the packet when received
00075   unsigned long long d_sync_vector;             // access code to locate start of packet
00076   unsigned int       d_threshold;               // how many bits may be wrong in sync vector
00077 
00078   state_t            d_state;
00079 
00080   unsigned long long d_shift_reg;               // used to look for sync_vector
00081 
00082   unsigned int       d_header;                  // header bits
00083   int                d_headerbitlen_cnt;        // how many so far
00084 
00085   unsigned char      d_packet[MAX_PKT_LEN];     // assembled payload
00086   unsigned char      d_packet_byte;             // byte being assembled
00087   int                d_packet_byte_index;       // which bit of d_packet_byte we're working on
00088   int                d_packetlen;               // length of packet
00089   int                d_packetlen_cnt;           // how many so far
00090 
00091  protected:
00092   digital_packet_sink(const std::vector<unsigned char>& sync_vector,
00093                       gr_msg_queue_sptr target_queue,
00094                       int threshold);
00095 
00096   void enter_search();
00097   void enter_have_sync();
00098   void enter_have_header(int payload_len);
00099 
00100   int slice(float x) { return x > 0 ? 1 : 0; }
00101 
00102   bool header_ok()
00103   {
00104     // confirm that two copies of header info are identical
00105     return ((d_header >> 16) ^ (d_header & 0xffff)) == 0;
00106   }
00107 
00108   int header_payload_len()
00109   {
00110     // header consists of two 16-bit shorts in network byte order
00111     int t = (d_header >> 16) & 0xffff;
00112     return t;
00113   }
00114 
00115  public:
00116   ~digital_packet_sink();
00117 
00118   int work(int noutput_items,
00119            gr_vector_const_void_star &input_items,
00120            gr_vector_void_star &output_items);
00121 
00122 
00123   //! return true if we detect carrier
00124   bool carrier_sensed() const
00125   {
00126     return d_state != STATE_SYNC_SEARCH;
00127   }
00128 
00129 };
00130 
00131 #endif /* INCLUDED_GR_PACKET_SINK_H */