function [rx_datafield,MCS,PSDULength,failCheck,rec_frameNo,estNumerlogy,numeroError] = rx_preambleprocess(rx) searchOffset = 0; % Offset from start of waveform in samples rxWaveLen = 30000; cfg = wlanNonHTConfig('SignalChannelBandwidth',true, ... 'BandwidthOperation','Static'); % Generate field indices ind = wlanFieldIndices(cfg); chanBW = cfg.ChannelBandwidth; sr = wlanSampleRate(cfg); % Sample rate % while (searchOffset + minPktLen) <= rxWaveLen % Packet detection threshold = 0.8; [pktOffset,M] = wlanPacketDetect(rx,chanBW,searchOffset,threshold); plot(M) % Adjust packet offset pktOffset = searchOffset + pktOffset; if isempty(pktOffset) || (pktOffset + ind.LSIG(2) > rxWaveLen) error('** No packet detected **'); end % Coarse frequency offset estimation and correction using L-STF rxLSTF = rx(pktOffset+(ind.LSTF(1):ind.LSTF(2)), :); coarseFreqOffset = wlanCoarseCFOEstimate(rxLSTF,chanBW); rx = helperFrequencyOffset(rx,sr,-coarseFreqOffset); % Symbol timing synchronization searchBufferLLTF = rx(pktOffset+(ind.LSTF(1):ind.LSIG(2)),:); pktOffset = pktOffset+wlanSymbolTimingEstimate(searchBufferLLTF,chanBW); % Fine frequency offset estimation and correction using L-STF rxLLTF = rx(pktOffset+(ind.LLTF(1):ind.LLTF(2)),:); fineFreqOffset = wlanFineCFOEstimate(rxLLTF,chanBW); rx = helperFrequencyOffset(rx,sr,-fineFreqOffset); % 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); % Recover L-SIG field bits [rxLSIGBits, failCheck, ~] = wlanLSIGRecover(rx(pktOffset + (ind.LSIG(1):ind.LSIG(2)), :), lltfChanEst, noiseVar, chanBW); [MCS,PSDULength] = interpretLSIG(rxLSIGBits); rec_frameNo = bi2de(rxLSIGBits(19:24).','right-msb'); if failCheck % Skip L-STF length of samples and continue searching disp('** L-SIG check fail **'); else disp('L-SIG check pass'); end % Recover Numerology field bits rxLSTF = rx(pktOffset+(ind.LSTF(1):ind.LSTF(2)), :); [estNumerlogy,numeroError] = STS_demod(rxLSTF); if numeroError disp('** Numerology check fail **'); else disp('Numerology check pass'); end % output data field % rx_datafield = rx(pktOffset+(ind.NonHTData(1):ind.NonHTData(2)), :); rx_datafield = rx(pktOffset+ind.NonHTData(1):end, :); end %% function [MCS,PSDULength] = interpretLSIG(recLSIGBits) % InterpretLSIG Interprets recovered L-SIG bits % % [MCS,PSDULENGTH] = interpretLSIG(RECLSIGBITS) returns the % modulation and coding scheme and PSDU length given the recovered L-SIG % bits % Rate and length are determined from bits rate = double(recLSIGBits(1:3)); length = double(recLSIGBits(5+(1:12))); % MCS rate table, IEEE Std 802.11-2016, Table 17-6. R = wlan.internal.nonHTRateSignalBits(); mcstmp = find(all(bsxfun(@eq,R(1:3,:),rate)))-1; MCS = mcstmp(1); % For codegen PSDULength = bi2de(length.'); end