function [PSDU_LENGTH,TXTIME,varargout] = ehtPLMETxTimePrimative(cfg)
%ehtPLMETxTimePrimative EHT PSDULength and TXTIME from PLME TXTIME primitive
% 
%   [PSDU_LENGTH,TXTIME] = ehtPLMETxTimePrimative(CFG) returns the PSDU
%   length per user, and TX time as per as per IEEE P802.11be/D1.0 Section
%   36.4.3.
%
%   [...,COMMONCODINGPARAMS] = ehtPLMETxTimePrimative(CFG) additionally
%   returns the common coding parameters.
%
%   [...,COMMONCODINGPARAMS,USERCODINGPARAMS] = ehtPLMETxTimePrimative(CFG)
%   additionally returns the user coding parameters.

%   Copyright 2021 The MathWorks, Inc.

allocationInfo = ruInfo(cfg);
numUsers = allocationInfo.NumUsers;

% Get the APEPLength per user
apepLength = zeros(numUsers,1);

for userIdx = 1:numUsers
    if cfg.User{userIdx}.STAID==2046
        % If STAID is 2046, then RU carries no data, therefore do not
        % include user in coding calculations by setting the APEPLength
        % to 0
        apepLength(userIdx) = 0;
    else
        apepLength(userIdx) = cfg.User{userIdx}.APEPLength;
    end
end

% Number of EHT-LTF and EHT-SIG symbols
NEHTLTF = wlan.internal.numVHTLTFSymbols(max(allocationInfo.NumSpaceTimeStreamsPerRU));
ehtSIGInfo = ehtSIGCodingInfo(cfg);
NEHTSIG = ehtSIGInfo.NumSIGSymbols;

% Calculate TXTIME
SignalExtension = 0; % in ns, 0 for 5 GHz or 6000 for 2.4 GHz
[commonCodingParams,userCodingParams] = ehtCodingParameters(cfg);

NSYM = commonCodingParams.NSYM;
npp = wlan.internal.heNominalPacketPadding(cfg);
trc = ehtTimingRelatedConstants(cfg.ChannelBandwidth,cfg.GuardInterval,cfg.EHTLTFType,commonCodingParams.PreFECPaddingFactor,npp,commonCodingParams.NSYM);

% Equation 36-96
TEHT_PREAMBLE = trc.TRLSIG+trc.TUSIG+NEHTSIG*trc.TEHTSIG+trc.TEHTSTFNT+NEHTLTF*trc.TEHTLTFSYM;

sf = 1e3; % Scaling factor to convert bandwidth and time in ns to samples
% Equation 36-110
TXTIME = 20*sf+TEHT_PREAMBLE+NSYM*trc.TSYM+trc.TPE+SignalExtension; % TXTIME in ns

% Calculate PSDU_LENGTH per user
PSDU_LENGTH = zeros(1,numUsers);
for u = 1:numUsers
    PSDU_LENGTH(u) = userCodingParams(u).PSDULength; 
end

% Force PSDULength to 0 when APEPLength is 0
PSDU_LENGTH(apepLength==0) = 0;

varargout{1} = commonCodingParams;
varargout{2} = userCodingParams;
end