[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] [gnuradio] 17/24: docs: Adding documentation for packe
From: |
git |
Subject: |
[Commit-gnuradio] [gnuradio] 17/24: docs: Adding documentation for packet comms |
Date: |
Tue, 14 Jun 2016 00:41:01 +0000 (UTC) |
This is an automated email from the git hooks/post-receive script.
jcorgan pushed a commit to branch packet2
in repository gnuradio.
commit 0b15f62e6eeb1dfe3f234f88aaead21ab3d75ca2
Author: Tom Rondeau <address@hidden>
Date: Tue Apr 12 16:24:16 2016 -0400
docs: Adding documentation for packet comms
docs: Added manual page "Packet Communications" to explain blocks and
some of our examples.
Adds README file to examples/packet
---
docs/doxygen/other/components.dox | 1 +
gr-digital/doc/packet_comms.dox | 653 ++++++++++++++++++++++++++++++++++++++
gr-digital/examples/packet/README | 3 +
3 files changed, 657 insertions(+)
diff --git a/docs/doxygen/other/components.dox
b/docs/doxygen/other/components.dox
index 1e98beb..564085f 100644
--- a/docs/doxygen/other/components.dox
+++ b/docs/doxygen/other/components.dox
@@ -22,6 +22,7 @@ All our in-tree components have their own top-level
documentation:
\li \subpage page_channels
\li \subpage page_ctrlport
\li \subpage page_digital
+\li \subpage page_packet_comms
\li \subpage page_fcd
\li \subpage page_fec
\li \subpage page_fft
diff --git a/gr-digital/doc/packet_comms.dox b/gr-digital/doc/packet_comms.dox
new file mode 100644
index 0000000..30a5073
--- /dev/null
+++ b/gr-digital/doc/packet_comms.dox
@@ -0,0 +1,653 @@
+/*! \page page_packet_comms Packet Communications
+
+\section packet_introduction Introduction
+
+This page describes...
+
+The point of these examples and the work is to provide a canonical
+tool for exploring burst digital communications. Providing the entire
+PHY chain in GRC is to help us more easily explore and extract
+portions of the transmit and receive chains to better understand,
+tweak, and optimize the system.
+
+
+\section packet_tx Understanding the Transmitter
+
+The transmitter PHY layer defines the following properties of the
+transmitted frame:
+
+- Data integrity check, generally a \ref gr::digital::crc32_async_bb
+ "CRC". Standard practice would be to calculate a CRC32 of the
+ payload and append this to the end of the frame.
+
+- \ref page_fec "Forward Error Correction (FEC)". For correcting bit
+ errors during reception, we use FEC codes, which have different
+ properties for complexity, correcting capabilities, and amounts of
+ added redundancy. See our \ref page_fec "FEC-API page" in the manual
+ for more on how to use these and what types of codes are already
+ available.
+
+- Frame formatting. We expect the data to have been delivered to the
+ transmitter from some higher layer (MAC/Network), which we treat as
+ the payload. The PHY layer then puts on a bit of its own framing in
+ order to properly transmit it for other radios to receive
+ correctly. This often involves some information about the payload
+ format, such as the length, the type of FEC code used, and the type
+ of modulation or modulation parameters. The PHY layer frame will
+ also often add a known word to the front to help with
+ synchronization and identification. We use the Packet Header
+ Formatter block for this, which is completely defined by a packet
+ formatter object. See the gr::digital::packet_formatter_base class
+ to understand more about how these formatters are created and used.
+
+ The \ref gr::digital::packet_format_async "Packet Header Formatter"
+ has two output paths, both emitted as PDUs from message ports. The
+ first message port is "header" that emits the header created for the
+ payload based on the formatter object. The second message port is
+ "payload" which is just the input payload PDU re-emitted. This
+ creates two paths, which allows us to separately modulate the header
+ and payload differently as well as encode the header with a
+ different FEC code. We often want to do this to provide a much
+ simpler and more robust modulation and FEC structure to the header
+ to ensure that it is correctly received and then use a different
+ modulation and code for the payload to maximize throughput.
+
+ NOTE: If the header formatter adds the known word / access code
+ here, and then we apply an FEC code to the header, then we have the
+ problem that the known word is also encoded. The receiver must be
+ made aware of this and correctly look for the encoded known
+ word. The packet_tx hier block example is a case where this
+ happens. If we use a repetition encoder, the access code is now
+ three bits out for every bit in. The packet_rx receiver example has
+ to account for this in the Correlation Estimator block that is
+ correlating against the known word.
+
+- Modulators. We create a modulator path for both the header and
+ payload. We define the operations of these two paths completely
+ using a \ref gr::digital::constellation "Constellation Object" (see
+ the \ref digital_constellations "Digital Modulation" manual page for
+ more information). The constellation objects define the mapping from
+ bits to complex symbols. You can use these objects in various ways,
+ but the packet_tx.grc example provides one way. After moving from
+ the PDU to tagged stream mode, the \ref gr::blocks::repack_bits_bb
+ "Repack Bits block" takes the packed 8-bits/byte data and converts
+ this into "chunks" of the number of bits per symbol of the
+ modulation (using the \ref
+ gr::digital::constellation::bits_per_symbol() "bits_per_symbol()"
+ property of the constellation object). We then map these chunks into
+ some known mapping function, most often a form of Gray Coding, using
+ the \ref gr::digital::map_bb "Map block" and the constellation object's \ref
+ gr::digital::constellation::pre_diff_code() "pre_diff_code()"
+ function. We then move these remapped chunks to complex symbols,
+ again as defined by the constellation object through the \ref
+ gr::digital::constellation::points() "points()" function in the
+ \ref gr::digital::chunks_to_symbols_bc "Chunks to Symbols block".
+
+- Combine the header and payload. We need to take both the header and
+ payload paths back together into a single stream. In packet_tx.grc,
+ we are working with tagged streams, so both paths keep track of the
+ size of their segments. Using the Tagged Stream Mux block, we
+ recombine these two paths into one.
+
+- Burst Shaping and Filtering. The next stage shapes the packet for
+ burst transmission. We apply two blocks to shape the burst
+ appropriately.
+
+ First, the \ref gr::digital::burst_shaper_cc "Burst Shaping block"
+ handles the structure of the burst by applying two different forms
+ of padding. First, there is a window that is applied to the time
+ domain of the burst. This involves a ramping up stage from 0 and a
+ ramping down stage back to 0. We define a window as a vector, and
+ the \ref gr::fft::window "fft.window" set of window functions is
+ useful here, such as using a Hann or Kaiser window. The size of the
+ window is split in half to apply the left half of the window for the
+ ramp-up and the right half of the window for the ramp-down. The
+ window has two different modes: to insert or not insert phasing
+ symbols. When inserting phasing symbols, a sequence of 1's and -1's
+ is inserted for the duration of the ramp-up and ramp-down
+ periods. So a window size of 20 will produce 10 alternative 1's and
+ -1's on the front of the burst and another 10 alternating symbols on
+ the rear of the burst. The window is then applied to these phasing
+ symbols and does not affect the burst symbols directly. If we are
+ not using the phasing symbols, the the window is applied to the
+ front and back of the burst directly.
+
+ The Burst Shaper can also add padded 0's to the front or back of the
+ burst. This allows us to provide some extra control over the
+ structure of the burst. In particular, it can be useful to add
+ post-padding 0's that is the length of the delay of the pulse
+ shaping filter that will come next. This makes sure that the full
+ burst of samples is pushed through the filter and transmitted
+ completely.
+
+
+\verbatim
+ ____________________
+ / \
+ / \
+ / \
+ ______/ \____
+ | E | D | C | B | A |
+
+ A: Pre-padding 0's
+ B: Ramp-up window
+ C: Frame
+ D: Ramp-down window
+ E: Post-padding 0's
+\endverbatim
+
+
+ When using phasing symbols, C is the entire frame and sections B
+ and D are filled with alternative 1's and -1's.
+
+ When not using phase symbols, the frame extends B through C to D.
+
+ After creating this burst shape, we then put the burst through a
+ pulse shaping filter. This filter both shapes the complex samples
+ into appropriate symbols for transmission based on a spectral mask
+ as well as up-samples the burst to the specified number of samples
+ per symbol. In packet_tx, we are using a Polyphase Arbitrary
+ Resampler to perform this task for us, which means that we can
+ specify and real value for the number of samples/symbol, as long as
+ it is greater than or equal to 2.0.
+
+ Typical pulse shape filters are \ref
+ gr::filter::firdes::root_raised_cosine "Root Raised Cosine (RRC)"
+ filters and \ref gr::filter::firdes::gaussian "Gaussian" filters.
+
+ Because the pulse shape filter up-samples, in packet_tx, we use a
+ \ref gr::blocks::tagged_stream_multiply_length "Tagged Stream Multiply
Length Tag block".
+ The resampler block knows nothing about
+ tagged streams, so when it up-samples, the \ref
+ page_tagged_stream_blocks "tagged stream block (TSB)" tag value does
+ not change. We need to change this tag's value, too, and so we use
+ the multiply length tag block for this purpose. This is helpful when
+ working with UHD devices, like in uhd_packet_tx.grc, because we can
+ explicitly tell the UHD USRP Sink block to expect a tagged stream to
+ manage the transmission of the burst.
+
+\subsection packet_tx_params Parameters of the packet_tx Example
+
+The canonical example for handling narrowband M-PSK or M-QAM is the
+packet_tx.grc hierarchical block.
+
+- Header FEC Code (hdr_enc)
+- Payload FEC Code (pld_enc)
+- Header Constellation Object (hdr_const)
+- Payload Constellation Object (pld_const)
+- Protocol Formatter Object (formatter)
+- Samples per symbol (sps as a float)
+- Pulse shaping filter (psf_taps, designed for the polyphase arbitrary
+ resampler)
+
+We can see all of these objects and settings in the
+packet_loopback_hier.grc example and uhd_packet_tx.grc if using a
+UHD-compatibly radio front end.
+
+\subsection packet_tx_examples Examples
+
+The following examples exist to showcase how to control each stage of
+the transmit processing.
+
+- tx_stage0.grc: simple creation of PDUs to input into the
+ transmitter. By default, this generates \ref gr::blocks::random_pdu
+ "random PDUs" for testing. However, we can switch in the \ref
+ gr::blocks::tuntap_pdu "TUNTAP PDU" block to create a tun or tap
+ device as the input of samples from some OS application. Note that
+ you will need root privileges to create a tun/tap device and
+ configure it.
+
+
+- tx_stage1.grc: Adding a CRC to the frame. The Message Debug prints
+ the before and after adding the \ref gr::digital::crc32_async_bb
+ "CRC32", so we can see the original PDU and then the PDU with the
+ added 4 bytes of check.
+
+
+- tx_stage2.grc: Adding \ref page_fec "forward error correction". This
+ adds an \ref gr::fec::async_encoder "FEC Async Encoder" block to
+ compare pre- and post-encoding. Three different FEC encoders are
+ available immediately in this example with the repetition encoder
+ enabled by default. This encoder just repeats every bit 3 times, so
+ it is easy to see the behavior before and after encoding. Simply
+ disable this FEC code and enabling one of the others will change the
+ encoding behavior.
+
+
+- tx_stage3.grc: takes the payload with the CRC32 check and creates
+ the packet structure. Both the header and payload are printed out,
+ where the payload is the input payload+CRC and the header is defined
+ by the 'formatter' object. The default formatter just applies an
+ access code (using the default 64-bit
+ digital.packet_utils.default_access_code code) and then it
+ calculates the payload length (in bytes) as a 16-bit value. This
+ 16-bit length field is duplicated, so in the receiver it can check
+ both 16-bit fields to make sure they agree. This formatter also
+ takes a threshold value. The transmitter does not use this
+ threshold. That parameter is used in the receiver to know how many
+ bits can be wrong in the access code and still pass.
+
+ Disabling the \ref gr::digital::packet_formatter_default
+ "default header definition" and enabling the other 'formatter' to
+ change the protocol. This other protocol definition is the \ref
+ gr::digital::packet_formatter_counter "counter header". It adds the
+ access code and payload length fields as the header like the default
+ formatter. This formatter includes two other fields as well: the
+ number of bits/symbol used in the payload modulator (as a 16-bit
+ field) and a 16-bit counter. Each packet transmitted increments this
+ counter by 1, which means we can keep track of how many packets we
+ have sent and/or received.
+
+- tx_stage4.grc: Here we add the modulation to both the header and
+ payload paths, defined by the hdr_const and pld_const objects,
+ respectively. Both are defined as BPSK constellations by
+ default. The output is shown in two \ref page_qtgui "QTGUI display"
+ graphs. We see the samples in time first, and this is triggering off
+ the TSB tag "packet_len". When the time display updates, we can see
+ the same pattern right after the tag, which is the header, and then
+ the changing samples are the random values in the payload.
+
+ When we look at this Freq tab of this example, we just see a mostly
+ flat frequency response over the entire frequency range. This
+ response is due to the samples just being +1's and -1's with no
+ transition between them and sampled at 1 sampler per symbol. This is
+ not something that we can just transmit as a burst. The square
+ pulses we use provide horrible out-of-band (OOB) emissions if we put
+ this over the air directly, and each burst would go from 0 to +/-1
+ within the coarse of a single sample, which again provides large OOB
+ emissions. We need to shape the bursts properly from here.
+
+- tx_stage5.grc: Adds the \ref gr::digital::burst_shaper_cc "Burst Shaper"
+ block. The default parameters are to use a Hann window of 50 symbols
+ and to add 10 0's as pre- and post-padding. We can adjust any of
+ these values to explore what the output burst looks like. We can
+ stop the time sink from updating and turn on the markers for the
+ Re{Data 0} channel to easily count the samples and observe the
+ effect of the window.
+
+ As an aside, the window of 50 produces 25 phasing samples on either
+ side. This is a lot, but we did this to help show off the way the
+ window looks a bit more clearly.
+
+- tx_stage6.grc: We then need to up-sample the signal by the number of
+ samples/symbol (sps) and apply our pulse-shaping filter. Again, we
+ are using some larger numbers than we really would in an actual
+ scenario to make it visually clear what is happening. The psf_taps
+ filter creates an RRC filter designed for the 32-arm (set by nfilts)
+ polyphase filterbank resampler. In this RRC Filter Taps object, we
+ set the number of taps to be 15*sps*nfilts. The sps and nfilts are
+ properties of the sample stream and upsampling factor. The value 15
+ is the number of symbols to represent in this filter; basically that
+ we are going to look over the history effects of 15 samples to
+ manage the inter-symbol interference (ISI). That is a long RRC filter
+ but done so to make the simulation look better. Five or seven is a
+ more realistic value. Similarly, we set sps=4 here to make the time
+ and frequency plots look better. Normally, we would want this closer
+ to 2.
+
+ Now looking at the time domain plot, we see the filtered samples,
+ which are not as pretty as before. They have over- and under-shoots,
+ and if we turned on the line markers, we would not see the original
+ bits easily through this. That is the effect of the RRC filter,
+ which introduces ISI into the transmitted stream. However, when we
+ look at the frequency domain, we see a much better shape, which we
+ can transmit as part of our channel assignment.
+
+- tx_stage6a.grc: An aside here to study the RRC filters more. This
+ example adds a second RRC filter (without any resampling) that
+ matches the transmitter's RRC filter. The matched filter means that
+ the samples are filtered by two RRC filters, which together make a
+ raised cosine (RC) filter. This RC filter is what is known as a
+ Nyquist filter and has the properties of 0 (or very close to 0)
+ ISI. Though we introduced ISI in the transmit RRC filter, the second
+ stage at the receiver undoes that ISI making for a clean, filtered
+ signal. Turning on marker in the time domain shows two clean lines
+ at +1 and -1. The receiver just needs to know which of the sps
+ samples to grad to get the original symbol that was transmitted. But
+ that is the job of the receiver.
+
+At this point, we have an encoded, modulated, and shaped burst ready
+to be transmitted out of a radio. The uhd_packet_tx.grc example puts
+all this together, where we have packaged up most of the transmitter
+behavior into packet_tx.grc. We then generate random PDU's, put them
+through the packet_tx block, and then through a Multiply Const block
+and into a USRP sink. The Multiply Const block is used for digital
+scaling of the signal to allow us power control on top of the
+transmitter gain inside the USRP radio itself.
+
+
+\section packet_rx Understanding the Receiver
+
+The receiver is far more complicated. The work involved here is
+largely in the detection and synchronization of the received
+frames. We must assume that frames are coming in as bursts with
+potentially random time intervals.
+
+It is important to understand that it is very difficult to make a
+simple protocol work in all scenarios. We have to assume that some
+packets will be lost through either a missed detection at the start or
+poor synchronization statistics during processing of the burst.
+
+The generic receiver example can be found in packet_rx.grc. This hier
+block provides the main detection, synchronization, header/payload
+management, demodulation, and decoding of the PHY frames. The input to
+this hier block should be not be too far off in frequency. The GNU
+Radio block \ref gr::digital::fll_band_edge_cc "FLL Band-Edge" tends
+to work well enough, though this is unnecessary if the radio are
+synchronized in frequency some other way (e.g., with a GPSDO such as
+is available on USRPs).
+
+The main flow of samples here is to detect a frame by discovering its
+known word, which also provides initial estimates on timing and phase
+offsets of the received frame. We then go through a clock sync block
+to perform matched filtering and sample time correction to produce
+resampled symbols at 1 sample/symbol. Now we have samples that are
+split between the header and payload. We might have information inside
+of the header that helps the receiver understand the payload. For
+instance, the length of the payload is generally encoded in the
+header. So we have to demux the header and payload.
+
+We assume that we know the length of the header in symbols, which we
+pass on to the header demodulator chain. Knowing the header
+modulation, we synchronize the phase and frequency, demodulate the
+symbols into soft bits, decode those soft bits based on the known
+header's FEC code, and then parse the header information. The header
+parser extracts information about the payload, such as the number of
+symbols in the payload and possibly the number of bits/symbol used in
+the payload modulation.
+
+The \ref gr::digital::header_payload_demux "Header/Payload Demux"
+block sends the appropriate number of samples to the payload demod
+chain. This chain does its own phase/freq synchronization for the
+appropriate constellation used in the payload, decodes the samples to
+soft bits, performs the FEC decoding, and then does the CRC32
+check. If this passes, the payload is sent out of the hier block as a
+PDU with the PHY layer framing stripped.
+
+When looking at the packet_rx.grc example, notice that we have
+instrumented a number of debug ports along the way. These ports are
+designed to make it possible for us to externally hook up graphing and
+debug blocks in whatever way we are comfortable with to see the signal
+along the path and more easily debug.
+
+
+\subsection packet_rx_correst Correlation Estimator
+
+The first stage of the receiver searches for the known word prepended
+to every burst from the transmitter. The known word has gone through
+two stages of processing: encoding with the header's FEC (optional)
+and modulated by the header's modulator. The correlation of the known
+word is done at the input sample stage, so we have to recreate the
+modulated and possible encoded known word at the receiver.
+
+To simplify dealing with the encoding process, in packet_rx.grc, we
+assume one of two types of codes: dummy code (or not coded) and a 3x
+repetition code. We then just simply calculated the preamble's bits
+for both cases. Depending on the header decoder (hdr_dec) used, the
+hier block knows which preamble to use.
+
+Next, we need to take the known, encoded word and modulate it with the
+header's modulator and pulse shaping filter. We create a simple
+modulator in the variable 'rxmod' that takes the header \ref
+gr::digital::constellation "constellation object" (hdr_const), the
+number of samples per symbol, and the pulse shape filter's bandwidth
+parameter (eb). The \ref gr::digital::modulate_vector_bc "Modulate Vector"
+block than combines this 'rxmod' modulator with the 'preamble'
+known word into a vector of complex symbols, here called
+'modulated_sync_word'. This variable is then passed to the \ref
+gr::digital::corr_est_cc "Correlation Estimator" block.
+
+One tricky thing about burst communications and network setups is the
+power of the received samples is unknown and time varying. It is
+preferential to try to auto-detect the burst and scale the signal to
++/-1 before coming in to packet_rx. There is still a lot of work to be
+done for AGC loops in the hardware and automatic scaling in
+software. The Correlation Estimator tries to deal with this. We use a
+threshold as an approximate probability of detection. This value
+should be set very high; the default here is 99.9%. The correlation
+tends to scale well as the amplitudes change and for relatively low
+SNR conditions. Still, it is always possible to miss a detection event
+or have a false positive.
+
+Another thing that the Correlation Estimator can do for us is provide
+information for digital scaling the samples. When received over
+hardware, the signals tend to be very small, but most of our follow-on
+processing assumes they are about +/-1. The Correlation Estimator
+finds the amplitude of the sample where the correlation peak was
+found, inverts it, and sends it as a tag with the key 'amp_est'. We
+can use this down stream to adjust the amplitude by rescaling the
+samples from this value. For our packet_rx example, we use the \ref
+gr::blocks::multiply_by_tag_value_cc "Multiply by Tag Value" block,
+which updates its multiplicitive factor based on the tag. Much of this
+could be handled by a good AGC routine in the hardware.
+
+Finally, the main purpose of the Correlation Estimator block is to
+provide the down-stream synchronization blocks with initial estimates
+of the timing and phase offset. The peak of the magnitude of the
+correlation event corresponds to the sampling timing of the data
+stream.
+
+\verbatim
+ 1. /\ 2. _
+ / \ / \
+ __/ \__ __/ \__
+\endverbatim
+
+The above two drawings show two different correlation scenarios. In
+scenario 1, the timing is exact and the sample at the peak of that
+curve is the proper sample time of the last symbol of the known
+word. In scenario 2, there is a timing offset where the correct timing
+offset is half-way between two samples. This would be a timing offset
+of 0.5 (or -0.5). Knowing where that estimated offset is helps our
+timing recover blocks start near the correct sample offset and then
+track from there.
+
+The magnitude of the correlation helps us discover the timing
+offset. The correlation itself is a complex vector. So where the peak
+of the magnitude happens, we can look to the complex value of the
+correlation at the same point and the phase difference between the
+real and imaginary parts is the phase offset of the signal.
+
+The Correlation Estimator block calculates the time and phase offsets
+and creates stream tags for "time_est" and "phase_est". It also
+creates two other tags: "corr_start" and "corr_est," both of which
+contain the value of the peak of the magnitude of the
+correlation. Because there is a delay in the correlation algorithm
+that is affected by the size of the correlation, we need to adjust
+where the correlation event occurs to where the tags are actually
+placed on the output stream. The block places the "corr_start" tag on
+the sample where the correlation actually occurred. It then places the
+other three tags offset by some "Tag marking delay," which is a
+user-calculated value to place the tags at the correct spot in the
+data stream for the actual start of the known word's first symbol.
+
+In packet_rx, we empirically discovered the tag marking delay for
+different values of the samples/symbol ('sps') variable and made a
+list 'mark_delays' that is index by 'sps' to properly set 'mark_delay'
+for the start of the known word. Getting is correct has a huge effect
+on the timing recover loop, which can take a while to converge if it
+starts offset in time by a sample.
+
+See the example example_corr_est.grc to explore the Correlation
+Estimator blocks more.
+
+
+\subsection packet_rx_timing Timing Recovery
+
+After detecting the frame and estimating the time and phase estimates,
+we have to actually perform the timing synchronization step. The
+packet_rx example uses the
+\ref gr::digital::pfb_clock_sync_ccf "Polyphase Clock Sync" block to
+do this. This PFB clock sync (PCS) block typically performs blind
+timing recovery on a series of samples. It is composed of 'nfilt'
+filters in a filterbank where each filter represents a different phase
+from [0, 2pi) in steps of 2pi/nfilts. The algorithm finds the correct
+arm of the filterbank that corresponds to the time shift of the
+samples. It also knows to look for a "time_est" stream tag and use
+that information to set its phase arm estimate. If we have a time
+estimate like scenario 1 above, we have perfect timing and so would
+select the 0th arm of the filterbank. In scenario 2, we are off by
+half a sample, so we select arm nfilts/2. The PCS is a tracking loop,
+so it will start with the initial estimate and then keep track of the
+timing as well as hone-in on actual timing information of the symbol
+stream.
+
+The PCS block uses a filterbank concept to perform its tracking
+operation. The filters within the filterbank operate best when they
+are phase offsets of the matched filter. So not only does the
+block recover the timing, it also performs the matched filtering and
+produces the optimal 1 sample/symbol output. These are then optimally
+sampled symbols in the complex constellation space. They need to be
+mapped back to bits and decoded. But first, we need to parse the
+header in order to discover information about the payload.
+
+See the example example_corr_est_and_clock_sync.grc to play with the
+parameters of time synchronization.
+
+
+\subsection packet_rx_hpd Header/Payload Demux
+
+Because the header and payload can be modulated differently, the rest
+of the symbol processing has to be split into two chains. We do this
+using the \ref gr::digital::header_payload_demux "Header/Payload Demux"
+block (HPD). We assume that we know the protocol, and so the format,
+coding, and modulation of the header. Generally speaking, these are
+all controlled through three different objects:
+
+- formatter: An object that described the header structure, derived
+ from gr::digital::packet_formatter_base.
+
+- hdr_const: An object that describes the bit and symbol mapping,
+ derived from gr::digital::constellation.
+
+- hdr_dec: An object that describes the FEC code, derived from
+ gr::fec::generic_decoder.
+
+Through these, we can ask for any parameter to set up the following
+stages of processing.
+
+The HPD block is fairly complicated and we will only use it in one
+kind of configuration here. See the manual page for the \ref
+gr::digital::header_payload_demux "HPD" block itself for more
+details. In our use of the HPD block, it receives the data stream and
+looks for a Trigger Tag Key. We will use 'time_est', one of the tags
+produced by the Correlation Estimator to indicate the sample that
+starts the header. When the HPD block sees this trigger key, it passes
+along a known number of symbols out of the 'header' stream port. We
+know the number of symbols based on the formatter, constellation, and
+FEC decoder objects. The formatter objects knows the number of bits in
+the header via the header_nbits() function, the constellation knows
+how many bits per symbol (via bits_per_symbol()), and the FEC decoder
+knows the encoding rate (via 1/rate()). The number of symbols in the
+header is therefore:
+
+ (header_nbits() * 1/rate()) / bits_per_symbol()
+
+The HPD then sends this many symbols on to be processed. It holds up
+any more processing until triggered to do so with information through
+the 'header_data' input message port. The header processing chain will
+end with the Packet Parser producing the message here.
+
+When the 'header_data' input message port receives valid information,
+it releases the payload out of the 'payload' stream port. The main
+thing that the 'header_data' input message port receives is
+information about the length of the payload. The HPD parameter 'Length
+tag key' is matched to the message received in 'header_data', which is
+then used to gate the output of samples as the payload. In our case,
+we specify the length as the number of symbols through the message key
+'payload symbols'. This tag then becomes the tagged stream key for the
+payload chain.
+
+
+\subsection packet_rx_hdr_chain Header Processing Chain
+
+The header processing chain is kicked off when the HPD block receives
+the trigger stream tag (i.e., 'time_est'). We must first correct the
+phase and fine frequency offset of the received samples. The
+Correlation Estimator block will help us with this through the
+'phase_est' tag. The \ref gr::digital::costas_loop_cc "Costas Loop"
+looks for this tag, and, when found, it will take this estimate and
+reset its own internal phase value, which greatly speed up
+acquisition. The Costas loop will then track the phase and frequency
+over the course of the header.
+
+With the constellation locked in time, phase, and frequency, we can
+not decode the complex symbols. We use a \ref
+gr::digital::constellation_soft_decoder_cf "Constellation Soft Decoder"
+block for this, which uses the 'hdr_const' object to know the mappings
+from complex space to bits. Specifically, it performs a soft decoding,
+so the outputs are soft decision bits, which is useful for FEC
+decoding that is performed next.
+
+The \ref gr::fec::decoder "FEC decoder" operates on the soft decisions
+based on the hdr_dec object. Because of the bounded nature of the
+header, we would expect simple block codes used here as well as a
+fairly robust and easy to process code. In the current examples, we
+only provide no code (via the \ref gr::fec::code::dummy_encoder
+"Dummy Encoder" / \ref gr::fec::code::dummy_decoder "Dummy Decoder"
+classes) or a repetition code (via the
+\ref gr::fec::code::repetition_encoder "Repetition Encoder" / \ref
+gr::fec::code::repetition_decoder "Repetition Decoder" classes). The
+output of the FEC decoder block is a bit stream where each item is
+either a 1 or a 0.
+
+The last step in the header processing stage is to parse that bit
+stream back into the header. The \ref gr::digital::packet_parse_b
+"Packet Parser" block does this by receiving a bit stream, passing it
+to the \ref gr::digital::packet_formatter_base::parse "parse" function
+of the packet formatter object, and emitting a message with the
+information about the parsed data.
+
+The packet parsing is explained in detail in the \ref
+gr::digital::packet_formatter_base "Packet Formatter Base" class. The
+parse function packs together the received bits into the different
+header fields, checks that the header is correct, and the constructs a
+PMT dictionary of the header information, such as the payload length
+and other possible information like the type of constellation or FEC
+coding used on the payload bits. This is the message that gets passed
+back to the HPD block to guide the payload processing.
+
+If the packet formatter parsing operation fails by not getting enough
+data or if the data is corrupted, it will return false. When the
+Packet Parser sees this, it emits a message that just contains a \ref
+page_pmt "PMT" False (pmt::PMT_F), which resets the HPD block to start
+looking for another header trigger event.
+
+If the header parsing completes successfully, the HPD block gets a
+message with information about the payload. Most importantly, it gets
+information about how many symbols make up the payload. It then sends
+a tagged stream to the payload processing chain with this many
+symbols.
+
+
+\subsection packet_rx_pld_chain Payload Processing Chain
+
+The payload processing chain behaves very similarly to the header
+processing chain for the first few blocks. It starts by locking the
+phase and frequency in another \ref gr::digital::costas_loop_cc
+"Costas loop", and then perform \ref
+gr::digital::constellation_soft_decoder_cf "soft decoding" on the
+symbols using the 'pld_const' object. Because we come in as symbols
+and out as soft decisions, the constellation soft decoder will produce
+\ref gr::digital::constellation::bits_per_symbol() "bits_per_symbol()"
+times as many outputs as inputs, but the soft decoder will not change
+the tag stream information. To compensate for this, we use a \ref
+gr::blocks::tagged_stream_multiply_length
+"Tagged Stream Multiply Length" block to update the tagged stream tag
+"payload symbols". We then move from the tagged stream mode into PDU
+mode and perform the FEC decoding through the \ref
+gr::fec::async_decoder "asynchronous FEC decoder". This decoder is
+nice in that it comes in with soft bits and produces packed
+bytes. These packed bytes are now the full payload with the CRC32
+appended. The \ref gr::digital::crc32_async_bb "Async CRC32" block in
+"Check CRC" mode will take this PDU of packed bytes, calculate the CRC
+and check it against the final four bytes of the payload. If they
+match, the PDU is stripped of the CRC bytes and the frame is passed
+out of the hier block. This PDU frame is now ready for use in higher
+layers of processing.
+
+This takes us through the entire processing chain on the
+receiver. From here, it is a matter of tweaking parameters and playing
+with options and other setups to improve behavior.
+
+*/
diff --git a/gr-digital/examples/packet/README
b/gr-digital/examples/packet/README
new file mode 100644
index 0000000..6051c11
--- /dev/null
+++ b/gr-digital/examples/packet/README
@@ -0,0 +1,3 @@
+See the Packet Communications page in the GNU Radio manual.
+
+http://gnuradio.org/doc/doxygen
- [Commit-gnuradio] [gnuradio] 12/24: blocks: Adds a multiple (complex only) block that responds to tags., (continued)
- [Commit-gnuradio] [gnuradio] 12/24: blocks: Adds a multiple (complex only) block that responds to tags., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 13/24: digital: Dealing with scaling issues with corr_est., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 09/24: digital: Removed parse_soft and packet_parse_f., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 15/24: digital: wip: packet formatters specify payload in symbols, not bits., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 03/24: Adding new test block to adjust the sample rate of a stream and make sure tags are being placed in the correct locations., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 06/24: digital: updates to packet_formatter classes and parsing blocks., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 08/24: digital: fixing PFB clock sync block handling of tags., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 23/24: digital: Fixing QA code for testing header formatter/parsers., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 14/24: digital: wip: pfb_clock_sync_ccf tag offset update., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 18/24: digital: fixing up some of the packet formatters since the new base class., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 17/24: docs: Adding documentation for packet comms,
git <=
- [Commit-gnuradio] [gnuradio] 07/24: digital: Updates to corr_est block., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 20/24: digital: fixed packet_parse from using default formatter to base class, git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 24/24: digital: fixed up some header_buffer issues and added QA., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 19/24: digital: adding more support for packet formatters., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 10/24: digital: Redid packet formatter class hierarchy., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 01/24: digital: New packet management classes., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 21/24: digital: adding packet_formatter_ofdm to replace packet_header_ofdm., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 22/24: digital: refactoring formatting/parsing code., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 02/24: digital: adding examples for using packet utilities., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 16/24: digital: Examples for dealing with packet comms, git, 2016/06/13