%% 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)

%
% 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)'

%
% 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)

% Copyright 2012 The MathWorks, Inc.