HE/isDataEmpty.m

191 lines
7.1 KiB
Mathematica
Raw Normal View History

2024-03-30 16:35:40 +08:00
function flag = isDataEmpty(rx,cfgUI)
chanBW = cfgUI.ChannelBandwidth;
cfgHE=wlanHESUConfig;
cfgHE.NumTransmitAntennas = cfgUI.numTx;
%% Setup Waveform Recovery Parameters
% Perform synchronization with 11ac components
% chanBW = cfg.ChannelBandwidth;
fs = wlanSampleRate(cfgHE);
cfgRx = wlanHERecoveryConfig;
cfgRx.ChannelBandwidth = chanBW;
% Get the field indices for extract fields from the PPDU
% ind = wlanFieldIndices(cfg);
ind = wlanFieldIndices(cfgRx);
% Minimum packet length is 10 OFDM symbols
lstfLength = double(ind.LSTF(2));
minPktLen = lstfLength*5; % Number of samples in L-STF
rxWaveLen = size(rx,1);
%% Front-End Processing
searchOffset = 0; % Offset from start of waveform in samples
while (searchOffset + minPktLen) <= rxWaveLen
% Packet detection
coarsePktOffset = wlanPacketDetect(rx,chanBW,searchOffset);
rxLSTF = rx(coarsePktOffset+(ind.LSTF(1):ind.LSTF(2)), :);
coarseFreqOffset = wlanCoarseCFOEstimate(rxLSTF,chanBW);
rx = helperFrequencyOffset(rx,fs,-coarseFreqOffset);
% Extract the non-HT fields and determine fine packet offset
nonhtfields = rx(coarsePktOffset+(ind.LSTF(1):ind.LSIG(2)),:);
finePktOffset = wlanSymbolTimingEstimate(nonhtfields,chanBW);
% Determine final packet offset
pktOffset = coarsePktOffset+finePktOffset;
% Extract L-LTF and perform fine frequency offset correction
rxLLTF = rx(pktOffset+(ind.LLTF(1):ind.LLTF(2)),:);
fineFreqOff = wlanFineCFOEstimate(rxLLTF,chanBW);
rx = helperFrequencyOffset(rx,fs,-fineFreqOff);
% Timing synchronization complete: packet detected
fprintf('Packet detected at index %d\n',pktOffset + 1);
% Display estimated carrier frequency offset
cfoCorrection = coarseFreqOffset + fineFreqOff; % Total CFO
fprintf('Estimated CFO: %5.1f Hz\n\n',cfoCorrection);
break; % Front-end processing complete, stop searching for a packet
end
% Scale the waveform based on L-STF power (AGC)
gain = 1./(sqrt(mean(rxLSTF.*conj(rxLSTF))));
rx = rx.*gain;
%% Packet Format Detection
rxLLTF = rx(pktOffset+(ind.LLTF(1):ind.LLTF(2)),:);
lltfDemod = wlanLLTFDemodulate(rxLLTF,chanBW);
lltfChanEst = wlanLLTFChannelEstimate(lltfDemod,chanBW);
noiseVar = helperNoiseEstimate(lltfDemod);
rxSIGA = rx(pktOffset+(ind.LSIG(1):ind.HESIGA(2)),:);
pktFormat = wlanFormatDetect(rxSIGA,lltfChanEst,noiseVar,chanBW);
fprintf(' %s packet detected\n\n',pktFormat);
% Set the packet format in the recovery object and update the field indices
cfgRx.PacketFormat = pktFormat;
ind = wlanFieldIndices(cfgRx);
%% L-LTF Channel Estimate
lltfDemod = wlanHEDemodulate(rxLLTF,'L-LTF',chanBW);
lltfChanEst = wlanLLTFChannelEstimate(lltfDemod,chanBW);
%% L-SIG and RL-SIG Decoding
% Extract L-SIG and RL-SIG fields
rxLSIG = rx(pktOffset+(ind.LSIG(1):ind.RLSIG(2)),:);
% OFDM demodulate
helsigDemod = wlanHEDemodulate(rxLSIG,'L-SIG',chanBW);
% Estimate CPE and phase correct symbols
helsigDemod = preHECommonPhaseErrorTracking(helsigDemod,lltfChanEst,'L-SIG',chanBW);
% Estimate channel on extra 4 subcarriers per subchannel and create full
% channel estimate
preheInfo = wlanHEOFDMInfo('L-SIG',chanBW);
preHEChanEst = preHEChannelEstimate(helsigDemod,lltfChanEst,preheInfo.NumSubchannels);
% Average L-SIG and RL-SIG before equalization
helsigDemod = mean(helsigDemod,2);
% Equalize data carrying subcarriers, merging 20 MHz subchannels
[eqLSIGSym,csi] = preHESymbolEqualize(helsigDemod(preheInfo.DataIndices,:,:), ...
preHEChanEst(preheInfo.DataIndices,:,:),noiseVar,preheInfo.NumSubchannels);
% Decode L-SIG field
[~,failCheck,lsigInfo] = wlanLSIGBitRecover(eqLSIGSym,noiseVar,csi);
if failCheck
disp(' ** L-SIG check fail **');
else
disp(' L-SIG check pass');
end
% Get the length information from the recovered L-SIG bits and update the
% L-SIG length property of the recovery configuration object
lsigLength = lsigInfo.Length;
cfgRx.LSIGLength = lsigLength;
%% HE-SIG-A Decoding
rxSIGA = rx(pktOffset+(ind.HESIGA(1):ind.HESIGA(2)),:);
sigaDemod = wlanHEDemodulate(rxSIGA,'HE-SIG-A',chanBW);
hesigaDemod = preHECommonPhaseErrorTracking(sigaDemod,preHEChanEst,'HE-SIG-A',chanBW);
% Equalize data carrying subcarriers, merging 20 MHz subchannels
preheInfo = wlanHEOFDMInfo('HE-SIG-A',chanBW);
[eqSIGASym,csi] = preHESymbolEqualize(hesigaDemod(preheInfo.DataIndices,:,:), ...
preHEChanEst(preheInfo.DataIndices,:,:), ...
noiseVar,preheInfo.NumSubchannels);
% Recover HE-SIG-A bits
[sigaBits,failCRC] = wlanHESIGABitRecover(eqSIGASym,noiseVar,csi);
% Perform the CRC on HE-SIG-A bits
if failCRC
disp(' ** HE-SIG-A CRC fail **');
else
disp(' HE-SIG-A CRC pass');
end
%% Interpret Recovered HE-SIG-A bits
cfgRx = interpretHESIGABits(cfgRx,sigaBits);
ind = wlanFieldIndices(cfgRx); % Update field indices
if isempty(ind.HEData)
flag = true;
else
flag = false;
end
% %% HE-SIG-B Decoding
% if flag
% if ~cfgRx.SIGBCompression
% s = getSIGBLength(cfgRx);
% % Get common field symbols. The start of HE-SIG-B field is known
% rxSym = rx(pktOffset+(ind.HESIGA(2)+(1:s.NumSIGBCommonFieldSamples)),:);
% % Decode HE-SIG-B common field
% [status,cfgRx] = heSIGBCommonFieldDecode(rxSym,preHEChanEst,noiseVar,cfgRx);
%
% % CRC on HE-SIG-B content channels
% if strcmp(status,'Success')
% fprintf(' HE-SIG-B (common field) CRC pass\n');
% elseif strcmp(status,'ContentChannel1CRCFail')
% fprintf(' ** HE-SIG-B CRC fail for content channel-1\n **');
% elseif strcmp(status,'ContentChannel2CRCFail')
% fprintf(' ** HE-SIG-B CRC fail for content channel-2\n **');
% elseif any(strcmp(status,{'UnknownNumUsersContentChannel1','UnknownNumUsersContentChannel2'}))
% error(' ** Unknown packet length, discard packet\n **');
% else
% % Discard the packet if all HE-SIG-B content channels fail
% error(' ** HE-SIG-B CRC fail **');
% end
% % Update field indices as the number of HE-SIG-B symbols are
% % updated
% ind = wlanFieldIndices(cfgRx);
% end
%
% % Get complete HE-SIG-B field samples
% rxSIGB = rx(pktOffset+(ind.HESIGB(1):ind.HESIGB(2)),:);
% fprintf(' Decoding HE-SIG-B user field... \n');
% % Decode HE-SIG-B user field
% [failCRC,cfgUsers] = heSIGBUserFieldDecode(rxSIGB,preHEChanEst,noiseVar,cfgRx);
%
% % CRC on HE-SIG-B users
% if ~all(failCRC)
% fprintf(' HE-SIG-B (user field) CRC pass\n\n');
% numUsers = numel(cfgUsers);
% elseif all(failCRC)
% % Discard the packet if all users fail the CRC
% error(' ** HE-SIG-B CRC fail for all users **');
% else
% fprintf(' ** HE-SIG-B CRC fail for at least one user\n **');
% % Only process users with valid CRC
% numUsers = numel(cfgUsers);
% end
%
% else % HE-SU, HE-EXT-SU
% cfgUsers = {cfgRx};
% numUsers = 1;
% end
end