function [rxPSDU,bitErrorRate,eqSymPlot,txPSDUByte] = heSURx(rx,cfgHE,userIdx,frameIdx,rxPSDU,cfgUI,SEED,bitErrorRate,eqSymPlot,txPSDUByte) chanBW = cfgHE.ChannelBandwidth; ind = wlanFieldIndices(cfgHE); fs = wlanSampleRate(cfgHE); ofdmInfo = wlanHEOFDMInfo('HE-Data',cfgHE); % Packet detect and determine coarse packet offset coarsePktOffset = wlanPacketDetect(rx,chanBW); LSTF = wlanLSTF(wlanNonHTConfig); if isempty(coarsePktOffset) coarsePktOffset = 0; end % Extract L-STF and perform coarse frequency offset correction lstf = rx(coarsePktOffset+(ind.LSTF(1):ind.LSTF(2)),:); tmp_xcorr = abs(xcorr(LSTF,lstf)); coarseFreqOff = wlanCoarseCFOEstimate(lstf,chanBW); rx = helperFrequencyOffset(rx,fs,-coarseFreqOff); % 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; if max(tmp_xcorr)>50 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); % If packet detected outwith the range of expected delays from % 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); % Display estimated carrier frequency offset cfoCorrection = coarseFreqOff + fineFreqOff; % Total CFO fprintf('Estimated CFO: %5.1f Hz\n\n',cfoCorrection); % HE-LTF demodulation and channel estimation rxHELTF = rx(pktOffset+(ind.HELTF(1):ind.HELTF(2)),:); heltfDemod = wlanHEDemodulate(rxHELTF,'HE-LTF',cfgHE); [chanEst,pilotEst] = heLTFChannelEstimate(heltfDemod,cfgHE); % Data demodulate rxData = rx(pktOffset+(ind.HEData(1):ind.HEData(2)),:); demodSym = wlanHEDemodulate(rxData,'HE-Data',cfgHE); % Pilot phase tracking demodSym = heCommonPhaseErrorTracking(demodSym,chanEst,cfgHE); % Estimate noise power in HE fields nVarEst = heNoiseEstimate(demodSym(ofdmInfo.PilotIndices,:,:),pilotEst,cfgHE); % Extract data subcarriers from demodulated symbols and channel % estimate demodDataSym = demodSym(ofdmInfo.DataIndices,:,:); chanEstData = chanEst(ofdmInfo.DataIndices,:,:); % Equalization and STBC combining [eqDataSym,csi] = heEqualizeCombine(demodDataSym,chanEstData,nVarEst,cfgHE); % eqDataOut = eqDataSym(1:end); % Recover data rxPSDUbits = wlanHEDataBitRecover(eqDataSym,nVarEst,csi,cfgHE,'LDPCDecodingMethod','layered-bp'); % [rxPSDU(:,frameIdx),~] = RX_CRC32(double(rxPSDUbits)); rxPSDU(:,frameIdx) = rxPSDUbits; EVM = comm.EVM; EVM.ReferenceSignalSource = 'Estimated from reference constellation'; EVM.Normalization = 'Average constellation power'; release(EVM); EVM.ReferenceConstellation = wlanReferenceSymbols(cfgHE); Evm = EVM(eqDataSym(:)); fprintf(' HE-Data EVM:%2.2fdB\n\n',20*log10(Evm)); rx = rx(pktOffset+ind.HEData(2):end,:); frameIdx = frameIdx+1; [rxPSDU,bitErrorRate,eqSymPlot] = heSURx(rx,cfgHE,userIdx,frameIdx,rxPSDU,cfgUI,SEED,bitErrorRate,eqSymPlot); else [~,numPkt] = size(rxPSDU); psduLength = length(rxPSDU(:,1))/8; switch cfgUI.DataType case 'test' txPSDU = DataGenerate(cfgUI,numPkt,SEED,psduLength,txPSDUByte); txPSDU = txPSDU{1}; bitError = sum(txPSDU(1:end - 32,:)~=rxPSDU); bitErrorRate = bitError/length(rxPSDU); ACK = (bitErrorRate == 0); case 'text' case 'photo' [~,numPkt] = size(rxPSDU); bitstream = reshape(rxPSDU,1,[]); % 恢复比特变比特流 imgLen = bin2dec(num2str(bitstream(1:16))); bit_array = reshape(bitstream,8,[])'; byte_array = num2str(bit_array); img = bin2dec(byte_array); % 二进制转十进制 if imgLen+3 > length(img) imgLen = length(img)-3; end rxPSDU = int16(img(1:imgLen+3)); % double转int16 % rxCRC = 0; % for i = 1:imgLen+2 % rxCRC = mod(rxCRC+rxPSDU(i),256); % end rxCRC = mod(sum(rxPSDU(1:length(rxPSDU)-1)),256); if rxCRC == rxPSDU(end) disp('Pass RX Sum Check!'); bitErrorRate = zeros(1,numPkt); else disp('Fail RX Sum Check!'); bitErrorRate = ones(1,numPkt); end ACK = (rxCRC == rxPSDU(end)); end save(['TXPackets\ACKfeedback_for_User' num2str(userIdx) '.mat'],'ACK'); end end