Main Content

Packet Recovery

Received packets are degraded due to radio and channel impairments. Recovery of packet contents requires symbol timing and frequency offset correction, channel estimation, and demodulation and recovery of the preamble and payload. WLAN Toolbox™ functions perform these operations on VHT, HT-mixed, and non-HT PPDU fields.

VHT Packet Recovery

This example shows how to recover contents from a VHT format waveform.

Generate 80 MHz VHT Waveform

Create a VHT configuration object. Set APEPLength to 3200 and MCS to 5. Create a transmission bit stream for the data field. For a VHT waveform, the data field contains PSDULength*8 bits.

cfgVHT = wlanVHTConfig('APEPLength',3200,'MCS',5);
txBits = randi([0 1],cfgVHT.PSDULength*8,1);

Create the PPDU fields individually. Create L-STF, L-LTF, L-SIG, VHT-SIG-A, VHT-STF, VHT-LTF, and VHT-SIG-B preamble fields and the VHT-Data field.

lstf = wlanLSTF(cfgVHT);
lltf = wlanLLTF(cfgVHT);
lsig = wlanLSIG(cfgVHT);
vhtSigA = wlanVHTSIGA(cfgVHT);
vhtstf = wlanVHTSTF(cfgVHT);
vhtltf = wlanVHTLTF(cfgVHT);
vhtSigB = wlanVHTSIGB(cfgVHT);
vhtData = wlanVHTData(txBits,cfgVHT);

Concatenate the individual fields to create a single PPDU waveform.

txPPDU = [lstf; lltf; lsig; vhtSigA; vhtstf; vhtltf; vhtSigB; vhtData];

Pass VHT Waveform Through TGac SISO Channel

Create TGac SISO and AWGN channel objects.

chBW = cfgVHT.ChannelBandwidth;
fs = 80e6;
tgac = wlanTGacChannel('SampleRate',fs,'ChannelBandwidth',chBW,...
    'LargeScaleFadingEffect','Pathloss and shadowing');
awgnChan = comm.AWGNChannel('NoiseMethod','Variance','VarianceSource','Input port');

Calculate the noise variance for a receiver with a 9 dB noise figure. The noise variance, noiseVar, is equal to kTBF, where k is Boltzmann's constant, T is the ambient temperature of 290 K, B is the bandwidth (sample rate), and F is the receiver noise figure. Pass the transmitted waveform through the noisy TGac channel.

noiseVar = 10^((-228.6 + 10*log10(290) + 10*log10(fs) + 9)/10)
noiseVar = 2.5438e-12
rxPPDU = awgnChan(tgac(txPPDU),noiseVar);

Recover VHT Preamble Contents from PPDU

In general, the L-STF and L-LTF are processed to perform frequency offset estimation and correction, and symbol timing. For this example, the carrier frequency is not offset and the packet timing is 'on-time'. Therefore, for accurate demodulation, determination of carrier frequency offset and symbol timing is not required.

Find the start and stop indices for the PPDU fields.

fieldInd = wlanFieldIndices(cfgVHT)
fieldInd = struct with fields:
       LSTF: [1 640]
       LLTF: [641 1280]
       LSIG: [1281 1600]
    VHTSIGA: [1601 2240]
     VHTSTF: [2241 2560]
     VHTLTF: [2561 2880]
    VHTSIGB: [2881 3200]
    VHTData: [3201 12160]

The stop index of VHT-SIG-B indicates the preamble length in samples.

numSamples = fieldInd.VHTSIGB(2);

Plot the preamble and the beginning of the packet data. Add markers to and plot to delineate the packet field boundaries.

time = ((0:double(numSamples)-1)/fs)*1e6;
peak = 1.2*max(abs(rxPPDU(1:numSamples)));
fieldMarkers = zeros(numSamples,1);
fieldMarkers(fieldInd.LSTF(2)-1,1) = peak;
fieldMarkers(fieldInd.LLTF(2)-1,1) = peak;
fieldMarkers(fieldInd.LSIG(2)-1,1) = peak;
fieldMarkers(fieldInd.VHTSIGA(2)-1,1) = peak;
fieldMarkers(fieldInd.VHTSTF(2)-1,1) = peak;
fieldMarkers(fieldInd.VHTLTF(2)-1,1) = peak;
fieldMarkers(fieldInd.VHTSIGB(2)-1,1) = peak;
plot(time,abs(rxPPDU(1:numSamples)),time,fieldMarkers)
xlabel ('Time (microseconds)')
ylabel('Magnitude')
title('VHT Preamble')

Demodulate the L-LTF and estimate the channel.

rxLLTF = rxPPDU(fieldInd.LLTF(1):fieldInd.LLTF(2),:);
demodLLTF = wlanLLTFDemodulate(rxLLTF,cfgVHT);
chEstLLTF = wlanLLTFChannelEstimate(demodLLTF,cfgVHT);

Extract the L-SIG field from the received PPDU, recover its information bits and check the CRC.

rxLSIG = rxPPDU(fieldInd.LSIG(1):fieldInd.LSIG(2),:);
[recLSIG,failCRC] = wlanLSIGRecover(rxLSIG,chEstLLTF,noiseVar,chBW);
failCRC
failCRC = logical
   0

failCRC = 0 indicates that CRC passed.

For the VHT format, the L-SIG rate bits are constant and set to [1 1 0 1]. Inspect the L-SIG rate information and confirm that this constant sequence is recovered. For the VHT format, the MCS setting in VHT-SIG-A2 determines the actual data rate.

rate = recLSIG(1:4)'
rate = 1x4 int8 row vector

   1   1   0   1

Extract the VHT-SIG-A and confirm that the CRC check passed.

rxVHTSIGA = rxPPDU(fieldInd.VHTSIGA(1):fieldInd.VHTSIGA(2),:);
[recVHTSIGA,failCRC] = wlanVHTSIGARecover(rxVHTSIGA, ...
    chEstLLTF,noiseVar,chBW);
failCRC
failCRC = logical
   0

Extract the MCS setting from the VHT-SIG-A. For single user VHT, the MCS is located in VHT-SIG-A2 bits 4 through 7.

recMCSbits = (recVHTSIGA(29:32));
recMCS = bit2int(double(recMCSbits),4,false)
recMCS = 5
isequal(recMCS,cfgVHT.MCS)
ans = logical
   1

The recovered MCS setting matches the MCS value in the configuration object.

Extract and demodulate the VHT-LTF. Use the demodulated signal to perform channel estimation. Use the channel estimate to recover the VHT-SIG-B and VHT-Data fields.

rxVHTLTF = rxPPDU(fieldInd.VHTLTF(1):fieldInd.VHTLTF(2),:);
demodVHTLTF = wlanVHTLTFDemodulate(rxVHTLTF,cfgVHT);
chEstVHTLTF = wlanVHTLTFChannelEstimate(demodVHTLTF,cfgVHT);

Extract and recover the VHT-SIG-B.

rxVHTSIGB = rxPPDU(fieldInd.VHTSIGB(1):fieldInd.VHTSIGB(2),:);
recVHTSIGB = wlanVHTSIGBRecover(rxVHTSIGB,chEstVHTLTF,noiseVar,chBW);

As described in IEEE Std 802.11ac-2013, Table 22-1, the value in the VHT-SIG-B Length field multiplied by 4 is the recovered APEP length for packets carrying data. Verify that the APEP length, contained in the first 19 bits of the VHT-SIG-B, corresponds to the specified APEP length.

sigbAPEPbits = recVHTSIGB(1:19);
sigbAPEPlength = bit2int(double(sigbAPEPbits),19,false)*4
sigbAPEPlength = 3200
isequal(sigbAPEPlength,cfgVHT.APEPLength)
ans = logical
   1

The recovered value matches the configured APEP Length.

Recover equalized symbols using channel estimates from the VHT-LTF.

recPSDU = wlanVHTDataRecover(rxPPDU(fieldInd.VHTData(1):fieldInd.VHTData(2),:),...
    chEstVHTLTF,noiseVar,cfgVHT);

Compare transmission and receive PSDU bits.

numErr = biterr(txBits,recPSDU)
numErr = 0

The number of bit errors is zero.

HT Packet Recovery

This example shows how to recover content from an HT-format waveform.

Generate 20 MHz HT Waveform

Create an HT configuration object and transmission PSDU. Set MCS to 2. For an HT waveform, the data field is PSDULength*8 bits.

cfgHT = wlanHTConfig('MCS',2);
txPSDU = randi([0 1],cfgHT.PSDULength*8,1);

Create the PPDU fields individually. Create L-STF, L-LTF, L-SIG, HT-SIG, HT-STF, and HT-LTF preamble fields and the HT-Data field.

lstf = wlanLSTF(cfgHT);
lltf = wlanLLTF(cfgHT);
lsig = wlanLSIG(cfgHT);
htsig = wlanHTSIG(cfgHT);
htstf = wlanHTSTF(cfgHT);
htltf = wlanHTLTF(cfgHT);
htData = wlanHTData(txPSDU,cfgHT);

Concatenate the individual fields to create a single PPDU waveform.

txPPDU = [lstf; lltf; lsig; htsig; htstf; htltf; htData];

Pass HT Waveform Through TGn SISO Channel

Create TGn SISO channel and AWGN channel objects.

fs = 20e6;
tgnChan = wlanTGnChannel('SampleRate',fs,'LargeScaleFadingEffect','Pathloss and shadowing');
awgnChan = comm.AWGNChannel('NoiseMethod','Variance','VarianceSource','Input port');

Calculate the noise variance for a receiver with a 9 dB noise figure. The noise variance, noiseVar, is equal to kTBF, where k is Boltzmann's constant, T is the ambient temperature of 290 K, B is the bandwidth (sample rate), and F is the receiver noise figure. Pass the transmitted waveform through the noisy TGn channel.

noiseVar = 10^((-228.6 + 10*log10(290) + 10*log10(fs) + 9)/10);
rxPPDU = awgnChan(tgnChan(txPPDU),noiseVar);

Recover HT Preamble Contents from PPDU

In general, the L-STF and L-LTF are processed to perform frequency offset estimation and correction, and symbol timing. For this example, the carrier frequency is not offset and the packet timing is 'on-time'. Therefore, for accurate demodulation, determination of carrier frequency offset and symbol timing is not required.

Find the start and stop indices for the PPDU fields.

fieldInd = wlanFieldIndices(cfgHT)
fieldInd = struct with fields:
      LSTF: [1 160]
      LLTF: [161 320]
      LSIG: [321 400]
     HTSIG: [401 560]
     HTSTF: [561 640]
     HTLTF: [641 720]
    HTData: [721 9200]

The stop index of HT-LTF indicates the preamble length in samples.

numSamples = fieldInd.HTLTF(2);

Plot the preamble and the beginning of the packet data. Add markers to and plot to delineate the packet field boundaries.

time = ((0:double(numSamples)-1)/fs)*1e6';
peak = 1.2*max(abs(rxPPDU(1:numSamples)));
fieldMarkers = zeros(numSamples,1);
fieldMarkers(fieldInd.LSTF(2)-1,1) = peak;
fieldMarkers(fieldInd.LLTF(2)-1,1) = peak;
fieldMarkers(fieldInd.LSIG(2)-1,1) = peak;
fieldMarkers(fieldInd.HTSIG(2)-1,1) = peak;
fieldMarkers(fieldInd.HTSTF(2)-1,1) = peak;
fieldMarkers(fieldInd.HTLTF(2)-1,1) = peak;
plot(time,abs(rxPPDU(1:numSamples)),time,fieldMarkers)
xlabel ('Time (microseconds)')
ylabel('Magnitude')
title('HT Format Preamble')

Demodulate the L-LTF and estimate the channel.

rxLLTF = rxPPDU(fieldInd.LLTF(1):fieldInd.LLTF(2),:);
demodLLTF = wlanLLTFDemodulate(rxLLTF,cfgHT);
chEstLLTF = wlanLLTFChannelEstimate(demodLLTF,cfgHT);

Extract the L-SIG field from the received PPDU and recover its information bits.

rxLSIG = rxPPDU(fieldInd.LSIG(1):fieldInd.LSIG(2),:);
[recLSIG,failCRC] = wlanLSIGRecover(rxLSIG,chEstLLTF,noiseVar,cfgHT.ChannelBandwidth);
failCRC
failCRC = logical
   0

failCRC = 0 indicates that CRC passed.

For the HT format, the L-SIG rate bits are constant and set to [1 1 0 1]. Inspect the L-SIG rate information and confirm that this constant sequence is recovered. For the HT format, the MCS setting in HT-SIG determines the actual data rate.

rate = recLSIG(1:4)'
rate = 1x4 int8 row vector

   1   1   0   1

Extract the HT-SIG and confirm that the CRC check passed.

recHTSIG = rxPPDU(fieldInd.HTSIG(1):fieldInd.HTSIG(2),:);
[recHTSIG,failCRC] = wlanHTSIGRecover(recHTSIG,chEstLLTF,noiseVar,cfgHT.ChannelBandwidth);
failCRC
failCRC = logical
   0

Extract the MCS setting from the HT-SIG. For HT, the MCS is located in HT-SIG bits 0 through 6.

recMCSbits = (recHTSIG(1:7));
recMCS = bit2int(double(recMCSbits),7,false)
recMCS = 2
isequal(recMCS,cfgHT.MCS)
ans = logical
   1

The recovered MCS setting matches the MCS value in the configuration object.

Extract and demodulate the HT-LTF. Use the demodulated signal to perform channel estimation. Use the channel estimate to recover the HT-Data field.

rxHTLTF = rxPPDU(fieldInd.HTLTF(1):fieldInd.HTLTF(2),:);
demodHTLTF = wlanHTLTFDemodulate(rxHTLTF,cfgHT);
chEstHTLTF = wlanHTLTFChannelEstimate(demodHTLTF,cfgHT);

Recover HT-Data Contents from PPDU

Recover the received equalized symbols using channel estimates from the HT-LTF.

[recPSDU] = wlanHTDataRecover(rxPPDU(fieldInd.HTData(1):fieldInd.HTData(2),:),...
    chEstHTLTF,noiseVar,cfgHT);

Compare the transmitted and received PSDU bits, and confirm that the number of bit errors is zero.

numErr = biterr(txPSDU,recPSDU)
numErr = 0

Non-HT Packet Recovery

This example steps through recovery of non-HT-format waveform content.

Generate 20 MHz Non-HT Waveform

Create a non-HT configuration object and transmission PSDU. Set MCS to 4.For a non-HT waveform, the data field is PSDULength*8 bits.

cfgNonHT = wlanNonHTConfig('MCS',4);
txPSDU = randi([0 1],cfgNonHT.PSDULength*8,1);

Create the PPDU fields individually. Use the non-HT-Data contents to check the bit error rate after recovery. Create L-STF, L-LTF, and L-SIG preamble fields and non-HT data field.

lstf = wlanLSTF(cfgNonHT);
lltf = wlanLLTF(cfgNonHT);
lsig = wlanLSIG(cfgNonHT);
nhtData = wlanNonHTData(txPSDU,cfgNonHT);

Concatenate the individual fields to create a single PPDU waveform.

txPPDU = [lstf; lltf; lsig; nhtData];

Pass Non-HT Waveform Through 802.11g SISO Channel

Calculate the free-space path loss for a transmitter-to-receiver separation distance of 3 meters. Create an 802.11g channel with a 3 Hz maximum Doppler shift and an RMS path delay equal to two times the sample time. Create an AWGN channel.

dist = 3;
pathLoss = 10^(-log10(4*pi*dist*(2.4e9/3e8)));
fs = 20e6;
trms = 2/fs;
maxDoppShift = 3;
ch802 = comm.RayleighChannel('SampleRate',fs,'MaximumDopplerShift',maxDoppShift,'PathDelays',trms);
awgnChan = comm.AWGNChannel('NoiseMethod','Variance','VarianceSource','Input port');

Calculate the noise variance for a receiver with a 9 dB noise figure. The noise variance, noiseVar, is equal to kTBF, where k is Boltzmann's constant, T is the ambient temperature of 290 K, B is the bandwidth (sample rate), and F is the receiver noise figure. Pass the transmitted waveform through the noisy, lossy 802.11g channel.

noiseVar = 10^((-228.6 + 10*log10(290) + 10*log10(fs) + 9)/10);
rxPPDU = awgnChan(ch802(txPPDU),noiseVar) * pathLoss;

Recover Non-HT Preamble Contents from PPDU

In general, the L-STF and L-LTF are processed to perform frequency offset estimation and correction, and symbol timing. For this example, the carrier frequency is not offset and the packet timing is 'on-time'. Therefore, for accurate demodulation, determination of carrier frequency offset and symbol timing is not required.

Find the start and stop indices for the PPDU fields.

fieldInd = wlanFieldIndices(cfgNonHT)
fieldInd = struct with fields:
         LSTF: [1 160]
         LLTF: [161 320]
         LSIG: [321 400]
    NonHTData: [401 7120]

The stop index of the L-SIG field indicates the preamble length in samples.

numSamples = fieldInd.LSIG(2);

Plot the preamble and the beginning of the packet data. Add markers to and plot to delineate the packet field boundaries.

time = ((0:double(numSamples)-1)/fs)*1e6;
peak = 1.2*max(abs(rxPPDU(1:numSamples)));
fieldMarkers = zeros(numSamples,1);
fieldMarkers(fieldInd.LSTF(2)-1,1)  = peak;
fieldMarkers(fieldInd.LLTF(2)-1,1) = peak;
fieldMarkers(fieldInd.LSIG(2)-1,1) = peak;
plot(time,abs(rxPPDU(1:numSamples)),time,fieldMarkers)
xlabel ('Time (microseconds)')
ylabel('Magnitude')
title('Non-HT Format Preamble')

Demodulate the L-LTF and estimate the channel.

rxLLTF = rxPPDU(fieldInd.LLTF(1):fieldInd.LLTF(2),:);
demodLLTF = wlanLLTFDemodulate(rxLLTF,cfgNonHT);
chEstLLTF = wlanLLTFChannelEstimate(demodLLTF,cfgNonHT);

Extract the L-SIG field from the received PPDU and recover its information bits.

rxLSIG = rxPPDU(fieldInd.LSIG(1):fieldInd.LSIG(2),:);
recLSIG = wlanLSIGRecover(rxLSIG,chEstLLTF,noiseVar,'CBW20');

The first four bits of the L-SIG field, bits 0 through 3, contain the rate information. Confirm that the sequence [1 0 0 1] is recovered. This sequence corresponds to the 24 MHz data rate for the non-HT MCS setting of 4.

rate = recLSIG(1:4)'
rate = 1x4 int8 row vector

   1   0   0   1

Extract and demodulate the L-LTF. Use the demodulated signal to perform channel estimation. Use the channel estimate to recover the non-HT-Data field.

rxLLTF = rxPPDU(fieldInd.LLTF(1):fieldInd.LLTF(2),:);
demodLLTF = wlanLLTFDemodulate(rxLLTF,cfgNonHT);
chEstLLTF = wlanLLTFChannelEstimate(demodLLTF,cfgNonHT);

Recover Non-HT-Data Contents from PPDU

Recover equalized symbols using channel estimates from HT-LTF, specifying a zero-forcing equalization method.

rxPSDU = rxPPDU(fieldInd.NonHTData(1):fieldInd.NonHTData(2),:);
[recPSDU,~,eqSym] = wlanNonHTDataRecover(rxPSDU,chEstLLTF,noiseVar,cfgNonHT,'EqualizationMethod','ZF');

Compare the transmitted and received PSDU bits, and confirm that the number of bit errors is zero.

numErr = biterr(txPSDU,recPSDU)
numErr = 0

See Also

| |

Related Topics