% hTM4InterfModel TM4 interference model
%   [TXWAVEFORM] = hTM4InterfModel(ENB) Generates a time domain waveform of
%   TM4 interference model as per TS36.101 B.5.3.
%
%   ENB is the eNodeB configuration structure. TXWAVEFORM is the generated
%   time domain transmitted waveform for the eNodeB configured with ENB and
%   with the characteristics specified in TS36.101 B.5.3.

%   Copyright 2018 The MathWorks, Inc.

function [txWaveform] = hTM4InterfModel(enb)

fullGrid = [];
totalSubframes = enb.TotSubframes;
enb.TotSubframes = 1; % make sure we generate one at a time in the loop
startSubframe = enb.NSubframe;
for n = startSubframe:startSubframe+(totalSubframes-1) % for all subframes
    enb.NSubframe = n;
    % Generate CQI subbands
    enb.PDSCH.PMIMode = 'Subband';
    pmiInfo = ltePMIInfo(enb,enb.PDSCH); 
    
    % Generate grid without any PDSCH mapped
    [~,grid] = lteRMCDLTool(enb,[]);
    
    % Generate PDSCHs for each subband and map to grid
    for NSubband=0:pmiInfo.NSubbands-1
        
        % get subband PDSCH indices and symbols
        [pdschSym, pdschInd] = subbandPDSCH(NSubband, pmiInfo.k, enb, enb.PDSCH);
        
        % map to grid
        poweradjperRE = 10^((enb.PDSCH.Rho)/20);
        grid(pdschInd) = pdschSym*poweradjperRE;
        
    end
    
    % Add PDCCH
    pdcchInd = ltePDCCHIndices(enb);
    pdcchInfo = ltePDCCHInfo(enb);
    cw = randi([0,1],pdcchInfo.MTot,1);
    pdcchSym = ltePDCCH(enb,cw);
    grid(pdcchInd) = pdcchSym;

    fullGrid = [fullGrid grid]; 
    
end

% OFDM modulation
txWaveform = lteOFDMModulate(enb,fullGrid);

end % function

function [pdschSym, pdschInd] = subbandPDSCH(NSubband, subbandSize, enb, pdsch)
% Generates TM4 interference model as per TS36.101 B.5.3

% Calculate PRBSet for subband
startRB = (NSubband*subbandSize); % all subbands are the same size
finishRB = min([enb.NDLRB (NSubband+1)*subbandSize])-1;
pdsch.PRBSet = (startRB:finishRB).';

% For both interfering cells take the pdsch configuration structure and set
% the following fields:
% - Transmission scheme
% - Number of transmission layers
% - Modulation scheme
% - Precoder matrix indication (PMI) set
% - Generate the payload bits

% Generate random variable to select transmission and modulation schemes
rankSelVar = rand();
% rank 1 (SpatialMux ) 80% of the time
if rankSelVar < 0.8 
    pdsch.TxScheme = 'SpatialMux';
    pdsch.Modulation = {'16QAM'};    
    pdsch.NLayers = 1;
    pmiDims = ltePMIInfo(enb,pdsch);
    pdsch.PMISet = randi([0 pmiDims.MaxPMI],1);
else % rank 2 (SpatialMux )20% of the time
    pdsch.TxScheme = 'SpatialMux';
    pdsch.Modulation = {'16QAM','16QAM'};  
    pdsch.NLayers = 2;
    pmiDims = ltePMIInfo(enb,pdsch);
    pdsch.PMISet = randi([0 pmiDims.MaxPMI],1);
end

% Generate pdsch indices, bit payload and symbols
[pdschInd, pdschinfo] = ltePDSCHIndices(enb, pdsch, pdsch.PRBSet);
bitPayload = arrayfun(@(x) randi([0 1], x,1), pdschinfo.G, 'UniformOutput', false);
pdschSym = ltePDSCH(enb, pdsch, bitPayload);

end % function

