function rxWaveform = heSigRecGenerateWaveform(cfgMU,numRx,delayProfile,noisePower,cfo) %heSigRecGenerateWaveform Generate an impaired waveform for the featured example % Copyright 2018-2019 The MathWorks, Inc. % Specify waveform parameters numTxPkt = 1; % Number of transmitted packets idleTime = 20e-6; % Idle time before and after each packet % Setup TGax Indoor channel chanBW = cfgMU.ChannelBandwidth; numTx = cfgMU.NumTransmitAntennas; sr = wlanSampleRate(cfgMU); % Create channel configuration common for all users tgaxChannel = wlanTGaxChannel; tgaxChannel.DelayProfile = delayProfile; % Delay profile tgaxChannel.NumTransmitAntennas = numTx; % Number of transmit antennas tgaxChannel.NumReceiveAntennas = numRx; % Each user has two receive antennas tgaxChannel.TransmitReceiveDistance = 10; % Non-line of sight distance tgaxChannel.ChannelBandwidth = chanBW; tgaxChannel.SampleRate = sr; % Set a fixed seed for the channel tgaxChannel.RandomStream = 'mt19937ar with seed'; tgaxChannel.Seed = 1; rngState = rng(120); % Set random state % Get allocation info allocInfo = ruInfo(cfgMU); muPSDULengths = getPSDULength(cfgMU); % Create a MAC frame [macFrames,cfgMU] = createMACFrames(cfgMU,allocInfo); macFrames = addMUPadding(macFrames,muPSDULengths); txPSDUPerUser = macFrames; % Generate HE-MU waveform with idle period txWaveform = wlanWaveformGenerator(txPSDUPerUser,cfgMU, ... 'NumPackets',numTxPkt,'IdleTime',idleTime); % Add channel chanOut = tgaxChannel([zeros(round(idleTime*sr),numTx); txWaveform]); % Add carrier frequency offset chanOut = helperFrequencyOffset(chanOut,sr,cfo); % Add noise awgnChannel = comm.AWGNChannel( ... 'NoiseMethod', 'Variance', ... 'Variance', 10^(noisePower/10)); rxWaveform = awgnChannel(chanOut); rng(rngState); % Restore random state function [macFrames,cfgHE] = createMACFrames(cfgHE,allocInfo) %createMACFrames Creates HE-MU MAC frames % Limitation: % ----------- % * wlanMACFrame does not support wlanHEMUConfig object. The MAC % frame format is same for HE-SU and HE-MU packet, we are using % wlanHESUConfig object to create a separate MAC frame for each user in % an HE-MU configuration. % % * Channel coding option "BCC" is not supported for bandwidth > 20MHz % in HE-SU format. If the bandwidth is > 20 MHz, we are forcing the channel % coding value to "LDPC". This does not affect the generated MAC frame % unless "MinimumMPDUStartSpacing" parameter is set to a value > 0. if isa(cfgHE,'wlanHEMUConfig') numUsers = allocInfo.NumUsers; numRUs = allocInfo.NumRUs; apepLength = zeros(numUsers,1); cfgSU = cell(numUsers,1); for ru = 1:numRUs for u = 1:numUsers apepLength(u) = cfgHE.User{u}.APEPLength; if strcmp(cfgHE.ChannelBandwidth,'CBW20') chCoding = cfgHE.User{u}.ChannelCoding; else chCoding = 'LDPC'; end cfgSU{u} = wlanHESUConfig(... 'APEPLength', apepLength(u), ... 'ChannelBandwidth', cfgHE.ChannelBandwidth, ... 'SpatialMapping', cfgHE.RU{ru}.SpatialMapping, ... 'NumSpaceTimeStreams', allocInfo.NumSpaceTimeStreamsPerRU(ru), ... 'MCS', cfgHE.User{u}.MCS, ... 'DCM', cfgHE.User{u}.DCM, ... 'ChannelCoding', chCoding, ... 'NumTransmitAntennas', cfgHE.NumTransmitAntennas, ... 'STBC', cfgHE.STBC, ... 'GuardInterval', cfgHE.GuardInterval, ... 'HELTFType', cfgHE.HELTFType, ... 'SpatialReuse', cfgHE.SpatialReuse); end end else % HE-SU, HE-EXT-SU numUsers = 1; apepLength = cfgHE.APEPLength; cfgSU = {cfgHE}; end % Create a MAC frame configuration cfgMAC = wlanMACFrameConfig('FrameType','QoS Data','FrameFormat',cfgSU{1}.packetFormat); macFrames = cell(numUsers, 1); for i = 1:numUsers % Create payload (MSDUs) for the MAC frame msduLen = wlanMSDULengths(apepLength(i),cfgMAC,cfgSU{i}); msdu = cell(1, numel(msduLen)); for j = 1:numel(msduLen) msdu{j} = randi([0,255],msduLen(j),1); end % Create the MAC frame bits [macFrames{i},length] = wlanMACFrame(msdu,cfgMAC,cfgSU{i},'OutputFormat','bits'); % Update the APEP length. APEP length is always rounded off to a % multiple of 4-octets. if isa(cfgHE, 'wlanHEMUConfig') cfgHE.User{i}.APEPLength = length; else cfgHE.APEPLength = length; end end end end function macFrames = addMUPadding(macFrames, muPSDULengths) %addMUPadding Adds or removes the padding difference between an HE-SU and HE-MU PSDU numFrames = numel(macFrames); eofDelimiter = [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 1 1 0 0 1 1 1 0 0 1 0]'; delimiterLength = 4; for i = 1:numFrames assert(rem(numel(macFrames{i}),8) == 0,'Number of bits in the MAC frame is not a multiple of 8') psdu = macFrames{i}; psdu = psdu(1 : end-rem(numel(macFrames{i})/8,4)*8); psduLength = numel(psdu)/8; % Difference between the required padding for SU and MU formats muPadding = muPSDULengths(i) - psduLength; % Calculate the number of EOF delimiters and zero padding needed % for the MU padding numEOFDelimiters = floor(abs(muPadding)/4); wordPadding = rem(abs(muPadding),4); if muPadding < 0 % Delete the extra padding created with wlanHESUConfig object macFrames{i} = psdu(1 : end - (numEOFDelimiters*delimiterLength*8 + wordPadding*8)); else % Add MU padding to the PSDU macFrames{i} = [psdu; repmat(eofDelimiter, numEOFDelimiters,1); zeros(wordPadding*8,1)]; end end end