www.gusucode.com > wlan 源码程序 matlab案例代码 > wlan/WLANPacketRecoveryExample.m

    %% WLAN Packet Recovery
% This example shows steps associated with recovering contents of VHT, HT
% and non-HT format waveforms.

%% VHT PPDU Recovery
%% - Generate an 80 MHz VHT Waveform, Create TGac SISO Channel and Pass VHT Waveform Through Channel
% Create a VHT configuration object and transmission bit stream. Set
% |APEPLength| to |3200| and |MCS| to |5|. Later accurate recovery of these
% settings is confirmed.
vht = wlanVHTConfig('APEPLength',3200,'MCS',5);
txBits = randi([0 1],26184,1);
%%
% Create the PPDU fields individually. Use the VHT-Data contents to check
% bit error rate after recovery. 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(vht);
lltf = wlanLLTF(vht);
lsig = wlanLSIG(vht);
vhtSigA = wlanVHTSIGA(vht);
vhtstf = wlanVHTSTF(vht);
vhtltf = wlanVHTLTF(vht);
vhtSigB = wlanVHTSIGB(vht);
vhtData = wlanVHTData(txBits,vht);
%%
% Concatenate the individual fields to create a single PPDU waveform.
txPPDU = [lstf; lltf; lsig; vhtSigA; vhtstf; vhtltf; vhtSigB; vhtData];
%%
% Create TGac SISO and AWGN channel objects.
chBW = vht.ChannelBandwidth;
fs = 80e6;
tgacChan = wlanTGacChannel('SampleRate',fs,'ChannelBandwidth',chBW, ...
    'LargeScaleFadingEffect','Pathloss');
awgnChan = comm.AWGNChannel('NoiseMethod','Variance','VarianceSource','Input port');
%%
% Calculate the noise variance for a receiver with a 9 dB noise figure.
% Pass the transmitted waveform through the noisy, TGac channel.
noiseVar = 10^((-228.6 + 10*log10(290) + 10*log10(fs) + 9)/10);
rxPPDU = awgnChan(tgacChan(txPPDU), noiseVar);
%%
% Find the start and stop indices for the PPDU fields. The preamble is
% contained in the first 3200 samples. Plot the preamble and a some of the
% packet data.
numSamples = 3200;
fieldInd = wlanFieldIndices(vht)
time = ([0:numSamples-1]/fs)*1e6;
peak = 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 format preamble')
%%
% Red vertical markers indicate the preamble field boundaries.
%% - Recover VHT Preamble Contents from the PPDU
% In general, the L-LTF is processed to perform frequency offset estimation
% and correction, and symbol timing. For this example the carrier frequency
% is not offset and packet is timing is 'on-time' so carrier frequency
% offset and symbol timing do not need to be determined for accurate
% demodulation.
%%
% Demodulate the L-LTF and estimate the channel coefficients.
rxLLTF = rxPPDU(fieldInd.LLTF(1):fieldInd.LLTF(2),:);
demodLLTF = wlanLLTFDemodulate(rxLLTF,vht);
chEstLLTF = wlanLLTFChannelEstimate(demodLLTF,vht);
%%
% Extract L-SIG from the received PPDU and recover its information bits.
rxLSIG = rxPPDU(fieldInd.LSIG(1):fieldInd.LSIG(2),:);
recLSIG = wlanLSIGRecover(rxLSIG,chEstLLTF,0.1,chBW);
%%
% Inspect the L-SIG rate information and confirm that the sequence 1 1 0 1
% is recovered. For VHT format the L-SIG rate bits are set to 1 1 0 1. The
% actual rate for VHT format is determined from the MCS setting in the
% VHT-SIG-A2.
rate = recLSIG(1:4)'
%%
% Extract VHT-SIG-A and confirm that the CRC check was passed.
rxVHTSIGA = rxPPDU(fieldInd.VHTSIGA(1):fieldInd.VHTSIGA(2),:);
[recVHTSIGA,failCRC] = wlanVHTSIGARecover(rxVHTSIGA, ...
    chEstLLTF,0.1,chBW);
failCRC
%%
% Extract MCS setting from the VHT-SIG-A. For SU VHT the MCS is located in
% VHT-SIG-A2 bits 4 through 7.
recMCSbits = (recVHTSIGA(29:32))';
recMCS = bi2de(double(recMCSbits))
isequal(recMCS,vht.MCS)
%%
% The recovered MCS setting matches the MCS value in the configuration
% object.
%%
% Extract and demodulate the VHT-LTF. Use the demodulated signal to
% estimate the channel coefficients needed to recover the VHT-SIG-B and
% VHT-Data fields.
rxVHTLTF = rxPPDU(fieldInd.VHTLTF(1):fieldInd.VHTLTF(2),:);
demodVHTLTF = wlanVHTLTFDemodulate(rxVHTLTF,vht);
chEstVHTLTF = wlanVHTLTFChannelEstimate(demodVHTLTF,vht);
%%
% Extract and recover VHT-SIG-B.
rxVHTSIGB = rxPPDU(fieldInd.VHTSIGB(1):fieldInd.VHTSIGB(2),:);
recVHTSIGB = wlanVHTSIGBRecover(rxVHTSIGB,chEstVHTLTF,0.1,chBW);
%%
% Verify that the APEP length, contained in the first 19 bits of SIG-B,
% corresponds to the specified length of 3200 bits.
pktL = recVHTSIGB(1:19)';
pktLbits = bi2de(double(pktL))*4;
isequal(pktLbits,vht.APEPLength)

%% - Recover VHT-Data Contents from the PPDU
% Construct a recovery configuration object.
cfgRec = wlanRecoveryConfig;
%%
% Recover receive equalized symbols using channel estimates from VHT-LTF.
[recPSDU,~,eqSym] = wlanVHTDataRecover(rxPPDU(fieldInd.VHTData(1):fieldInd.VHTData(2),:),chEstVHTLTF, noiseVar, vht,cfgRec);
%%
% Compare transmission and receive PSDU bits.
numErr = biterr(txBits,recPSDU)
%% HT PPDU Recovery
%% - Generate a 20 MHz HT Waveform, Create TGn SISO Channel and Pass HT Waveform Through Channel
% Create a HT configuration object and transmission PSDU. Set |MCS| to |2|.
% Later accurate recovery of this setting is confirmed.
ht = wlanHTConfig('MCS',2);
txPSDU = randi([0 1],8192,1);
%%
% Create the PPDU fields individually. Use the HT-Data contents to check
% bit error rate after recovery. Create L-STF, L-LTF, L-SIG, HT-SIG,
% HT-STF, and HT-LTF preamble fields and HT-Data field.
lstf = wlanLSTF(ht);
lltf = wlanLLTF(ht);
lsig = wlanLSIG(ht);
htSig = wlanHTSIG(ht);
htstf = wlanHTSTF(ht);
htltf = wlanHTLTF(ht);
htData = wlanHTData(txPSDU,ht);
%%
% Concatenate the individual fields to create a single PPDU waveform.
txPPDU = [lstf; lltf; lsig; htSig; htstf; htltf; htData];
%%
% Create TGn SISO channel and AWGN channel.
fs = 20e6;
chTGn = wlanTGnChannel('SampleRate',fs,'LargeScaleFadingEffect','Pathloss');
awgnChan = comm.AWGNChannel('NoiseMethod','Variance','VarianceSource','Input port');
%%
% Calculate the noise variance for a receiver with a 9 dB 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(tgacChan(txPPDU), noiseVar);
%%
% Find the start and stop indices for the PPDU fields. The preamble is
% contained in the first 720 samples. Plot the preamble and a some of the
% packet data.
numSamples = 800;
fieldInd = wlanFieldIndices(ht)
time = ([0:numSamples-1]/fs)*1e6;
peak = 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')
%%
% Red vertical markers indicate the preamble field boundaries.

%% - Recover HT Preamble Contents from the PPDU
% In general, the L-LTF is processed to perform frequency offset estimation
% and correction, and symbol timing. For this example the carrier frequency
% is not offset and packet is timing is 'on-time' so carrier frequency
% offset and symbol timing do not need to be determined for accurate
% demodulation.
%%
% Demodulate the L-LTF and estimate the channel coefficients.
rxLLTF = rxPPDU(fieldInd.LLTF(1):fieldInd.LLTF(2),:);
demodLLTF = wlanLLTFDemodulate(rxLLTF,ht);
chEstLLTF = wlanLLTFChannelEstimate(demodLLTF,ht);
%%
% Extract L-SIG from the received PPDU and recover its information bits.
rxLSIG = rxPPDU(fieldInd.LSIG(1):fieldInd.LSIG(2),:);
recLSIG = wlanLSIGRecover(rxLSIG,chEstLLTF,0.1,ht.ChannelBandwidth);
%%
% Inspect the L-SIG rate information and confirm that the sequence 1 1 0 1
% is recovered. For HT format the L-SIG rate bits are set to 1 1 0 1. The
% actual rate for HT format is determined from the MCS setting in the
% HT-SIG.
rate = recLSIG(1:4)'
%%
% Extract HT-SIG and confirm that the CRC check was passed.
recHTSIG = rxPPDU(fieldInd.HTSIG(1):fieldInd.HTSIG(2),:);
[recHTSIG,failCRC] = wlanHTSIGRecover(recHTSIG,chEstLLTF,0.1,ht.ChannelBandwidth);
failCRC
%%
% Extract MCS setting from the HT-SIG. For HT the MCS is located in HT-SIG
% bits 0 through 6.
recMCSbits = (recHTSIG(1:7))';
recMCS = bi2de(double(recMCSbits))
isequal(recMCS,ht.MCS)
%%
% The recovered MCS setting matches the MCS value in the configuration
% object.
%%
% Extract and demodulate the HT-LTF. Use the demodulated signal to estimate
% the channel coefficients needed to recover the HT-Data field.
rxHTLTF = rxPPDU(fieldInd.HTLTF(1):fieldInd.HTLTF(2),:);
demodHTLTF = wlanHTLTFDemodulate(rxHTLTF,ht);
chEstHTLTF = wlanHTLTFChannelEstimate(demodHTLTF,ht);

%% - Recover HT-Data Contents from the PPDU
% Construct a recovery configuration object.
cfgRec = wlanRecoveryConfig;
%%
% Recover receive equalized symbols using channel estimates from HT-LTF.
[recPSDU,~,eqSym] = wlanHTDataRecover(rxPPDU(fieldInd.HTData(1):fieldInd.HTData(2),:),chEstHTLTF, noiseVar, ht,cfgRec);
%%
% Compare transmission and receive PSDU bits.
numErr = biterr(txPSDU,recPSDU)

%% non-HT PPDU Recovery
%% - Generate a 20 MHz non-HT Waveform, Create an 802.11g SISO Channel and Pass non-HT Waveform Through Channel
% Create a non-HT configuration object and transmission PSDU. Set |MCS| to
% |4|. Later accurate recovery of this setting is confirmed.
nht = wlanNonHTConfig('MCS',4);
txPSDU = randi([0 1],8000,1);
%%
% Create the PPDU fields individually. Use the non-HT-Data contents to
% check bit error rate after recovery.  Create L-STF, L-LTF, and L-SIG
% preamble fields and non-HT-Data fields.
lstf = wlanLSTF(nht);
lltf = wlanLLTF(nht);
lsig = wlanLSIG(nht);
nhtData = wlanNonHTData(txPSDU,nht);
%%
% Concatenate the individual fields to create a single PPDU waveform.
txPPDU = [lstf; lltf; lsig; nhtData];
%%
% Calculate 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;
ch802 = stdchan(1/fs,3,'802.11g',trms);
awgnChan = comm.AWGNChannel('NoiseMethod','Variance','VarianceSource','Input port');
%%
% Calculate the noise variance for a receiver with a 9 dB 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(filter(ch802,txPPDU), noiseVar) * pathLoss;
%%
% Find the start and stop indices for the PPDU fields. The preamble is
% contained in the first 400 samples. Plot the preamble.
numSamples = 500;
fieldInd = wlanFieldIndices(nht)
time = ([0:numSamples-1]/fs)*1e6;
peak = 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')
%%
% Red vertical markers indicate the preamble field boundaries.

%% - Recover non-HT Preamble Contents from the PPDU
% In General, the L-LTF is processed to perform frequency offset estimation
% and correction, and symbol timing. For this example the carrier frequency
% is not offset and packet is timing is 'on-time' so carrier frequency
% offset and symbol timing do not need to be determined for accurate
% demodulation.
%%
% Demodulate the L-LTF and estimate the channel coefficients.
rxLLTF = rxPPDU(fieldInd.LLTF(1):fieldInd.LLTF(2),:);
demodLLTF = wlanLLTFDemodulate(rxLLTF,nht);
chEstLLTF = wlanLLTFChannelEstimate(demodLLTF,nht);
%%
% Extract L-SIG from the received PPDU and recover its information bits.
rxLSIG = rxPPDU(fieldInd.LSIG(1):fieldInd.LSIG(2),:);
recLSIG = wlanLSIGRecover(rxLSIG,chEstLLTF,0.1,'CBW20');
%%
% Inspect the L-SIG rate information and confirm that the sequence 1 0 0 1
% is recovered. This sequence corresponds to a 24 MHz data rate used for
% this non-HT transmission.
rate = recLSIG(1:4)'
%%
% For non-HT an MCS setting of |4| corresponds to a 24 MHz data rate.
%%
% Extract and demodulate the L-LTF. Use the demodulated signal to estimate
% the channel coefficients needed to recover the non-HT-Data field.
rxLLTF = rxPPDU(fieldInd.LLTF(1):fieldInd.LLTF(2),:);
demodLLTF = wlanLLTFDemodulate(rxLLTF,nht);
chEstLLTF = wlanLLTFChannelEstimate(demodLLTF,nht);

%% - Recover non-HT-Data Contents from the PPDU
% Construct a recovery configuration object with its equalization method
% set to zero forcing.
cfgRec = wlanRecoveryConfig('EqualizationMethod','ZF');
%%
% Recover equalized symbols using channel estimates from HT-LTF.
[recPSDU,~,eqSym] = wlanNonHTDataRecover(rxPPDU(fieldInd.NonHTData(1):fieldInd.NonHTData(2),:),chEstLLTF,noiseVar,nht,cfgRec);
%%
% Compare transmission and receive PSDU bits.
numErr = biterr(txPSDU,recPSDU)