%% Decode NB-IoT UL-SCH Data Codeword
% Generate an NB-IoT UL-SCH data codeword by encoding a 136-bit transport block. Split the codeword into two NPUSCH transmissions in two consecutive slots. Decode the NPUSCH transmission, and then decode the received NB-IoT UL-SCH codeword.
% Configure UE-specific settings.

ue = struct('NBULSubcarrierSpacing','15kHz','NNCellID',10,'NSlot',0);

% Specify a channel transmission configuration.

chs = struct('NPUSCHFormat','Data','NBULSubcarrierSet',0:11,'NRUsc',length(0:11),'NRep',1, ...
    'NRU',1,'NULSlots',2,'Modulation','QPSK','RV',0,'NTurboDecIts',5,'RNTI',20);

% Generate a transport block for encoding.

trBlkLen = 136;
trBlkIn = randi([0 1],trBlkLen,1);

% Get the codeword length by generating the NPUSCH RE indices and associated information.

[~,info] = lteNPUSCHIndices(ue,chs);
outLen = info.G;

% Generate the UL-SCH codeword.

cwIn = lteNULSCH(chs,outLen,trBlkIn);

% Initialize the encoder state for the NPUSCH and the decoder states for the NPUSCH and UL-SCH.

npuschStateIn = struct();
npuschDecodeStateIn = struct();
stateIn = struct();

% Generate NPUSCH symbols for slot 0, and then return the decoder state by decoding the NPUSCH symbols.

[symSlot0,npuschStateOut] = lteNPUSCH(ue,chs,cwIn,npuschStateIn);
[~,npuschDecodeStateOut,~] = lteNPUSCHDecode(ue,chs,symSlot0,npuschDecodeStateIn);

% Generate NPUSCH symbols for slot 1, and then return the decoder state by decoding the NPUSCH symbols.

ue.NSlot = 1;
[symSlot1,~] = lteNPUSCH(ue,chs,cwIn,npuschStateOut);
[cw,~,~] = lteNPUSCHDecode(ue,chs,symSlot1,npuschDecodeStateOut);

% Decode received NB-IoT UL-SCH data codeword.

[trBlkOut,blkCRC,stateOut] = lteNULSCHDecode(chs,trBlkLen,cw,stateIn);

% Confirm that the recovered NB-IoT UL-SCH matches the original transport block.

disp(isequal(trBlkIn,trBlkOut))

% Copyright 2019 The MathWorks, Inc.