Main Content

UE Detection Using Downlink Signals

This example shows how LTE Toolbox™ can be used to detect the presence of UEs associated with an eNodeB. This is achieved by searching a downlink signal for DCI messages and establishing the set of unique identifiers (C-RNTIs) in use.

Introduction

In LTE, the Physical Downlink Control Channel (PDCCH) carries control information in the form of Downlink Control Information (DCI) messages. The DCI messages transmit uplink or downlink scheduling information from the eNodeB to destination UEs, in order that the UEs can identify the resources required to receive on the Physical Downlink Shared Channel (PDSCH) or to transmit on the Physical Uplink Shared Channel (PUSCH). Each UE is assigned an identifier known as a C-RNTI (Cell Radio Network Temporary Identifier). The C-RNTI is used to scramble the CRC bits of the DCI message for that UE, and also to determine the location of the DCI message within the PDCCH. For more information, see the PDCCH Blind Search and DCI Decoding example.

The aim of this example is to decode the PDCCH and look for candidate DCI messages. The C-RNTI is then obtained from valid messages, giving an indication of the number of UEs being addressed, and their pattern over time. Note that in this example all detected RNTIs are returned, not just the RNTIs in the C-RNTI range defined in TS 36.321 Table 7.1-1 [ 1 ]. Keeping these other RNTIs allows this example to be used to identify occurrences of DCI messages associated with System Information (SI-RNTI) or Paging (P-RNTI).

Waveform Under Analysis

In this example, the waveform under analysis is stored in the file ueDetectionWaveform.mat as the variable rxWaveform. It is assumed that the bandwidth, duplexing mode, cyclic prefix length, cell identity, number of cell-specific reference signal ports and PHICH configuration are all known, and the corresponding eNodeB configuration variable enb is also loaded from the file. It is also possible to use a waveform whose eNodeB configuration is not known, in which case the eNodeB configuration would need to be decoded as shown in the Cell Search, MIB and SIB1 Recovery example.

load ueDetectionWaveform.mat;
rxWaveform = double(rxWaveform) / 32768;

Synchronization

Frequency offset estimation and correction and timing synchronization are performed.

% Perform frequency offset estimation and correction
foffset = lteFrequencyOffset(enb,rxWaveform);
rxWaveform = lteFrequencyCorrect(enb,rxWaveform,foffset);

% Perform timing synchronization to the first whole subframe of the
% waveform
toffset = lteDLFrameOffset(enb,rxWaveform);
ofdmInfo = lteOFDMInfo(enb);
sfLength = ofdmInfo.SamplingRate * 1e-3;
offsetSubframes = floor(toffset / sfLength);
toffset = toffset - (offsetSubframes * sfLength);
rxWaveform = rxWaveform(1+toffset:end,:);
enb.NSubframe = mod(-offsetSubframes,10);

OFDM Demodulation

The I/Q waveform rxWaveform is OFDM demodulated to produce the received resource grid rxgrid.

rxgrid = lteOFDMDemodulate(enb,rxWaveform);

Channel Estimator Configuration

Channel estimation and equalization will be needed for processing an I/Q waveform captured off-the-air, so the channel estimator parameters are configured.

cec.PilotAverage = 'UserDefined';     % Type of pilot averaging
cec.FreqWindow = 13;                  % Frequency window size
cec.TimeWindow = 9;                   % Time window size
cec.InterpType = 'cubic';             % 2D interpolation type
cec.InterpWindow = 'Centered';        % Interpolation window type
cec.InterpWinSize = 1;                % Interpolation window size

UE Detection

The downlink waveform under analysis may carry information for a number of UEs. This section attempts to find their RNTIs. The approach applied here uses the fact that for a valid DCI message, the CRC bits are masked with the RNTI. Therefore, assuming there are no errors (CRC = 0), the last 16 decoded bits correspond to the RNTI. This approach is described in Section 5 of [ 2 ].

This example implements the following algorithm:

  • Consider all PDCCH formats in the UE-specific search space (0...3)

  • For each PDCCH format, calculate all possible candidates in the control region that may carry a DCI message.

  • For each candidate, attempt to decode a DCI message (considering all possible DCI formats with unique DCI message length).

The following steps are performed to check if the decoded bits constitute a valid DCI message (a graphical representation of the algorithm is also provided below):

  • Assume there are no errors in the transmission, i.e. assume CRC = 0. This means the last 16 decoded bits constitute the C-RNTI.

  • Separate the DCI message from the 16 C-RNTI bits.

  • Calculate new CRC bits and mask them with the C-RNTI.

  • Re-encode the DCI message.

  • Compare the re-encoded message with the original coded DCI candidate.

Lack of errors in the comparison in this last step means a valid DCI message and C-RNTI (UE identifier) have been detected. In some cases, especially with waveforms captured off-the air, some errors may occur in the DCI decoding process. Therefore, this example uses a threshold (maxErrors) to control how many errors are allowed in the comparison between the received candidate bits and the re-encoded candidate bits.

Two post-processing steps are applied to the list of detected UEs in order to reduce the number of false detections:

  • DCI messages having received candidate symbols whose power (in dB) is less than the threshold minPDCCHPower are excluded. Without this step, received candidate bits consisting solely of noise (even at a low power) can trigger false detections.

  • In the case of overlapping results (i.e. where the candidate indices of one result are a subset of another), the result with the lowest number of bit errors will be selected.

Note that for completeness, the common search space is also searched for DCI format 1A and 1C messages allocating resources for System Information, Paging or Random Access Response messages.

% Maximum number of bit errors allowed to consider a detection as valid
maxErrors = 2;

% Minimum PDCCH power in dB (relative to the cell-specific reference signal
% used for channel estimation) to consider a detection as valid
minPDCCHPower = -5.0;

% Initialize results table
results = table;

% Get DCI formats and lengths for DCI messages in the common search space
pdcchCommon = struct('SearchSpace','Common');
pdcchCommon.ControlChannelType = 'PDCCH';
CIF = 'Off'; % enable or disable Carrier Indicator Field
pdcchCommon.EnableCarrierIndication = CIF;
[dciInfoCommon,pdcchCommon] = getUniqueDCILengths(enb,pdcchCommon);

% Get DCI formats and lengths for DCI messages in the UE-specific search
% space. The length of a DCI message of a given format may be affected by
% various UE-specific higher-layer parameters so the set of different
% unique lengths across those parameters is recorded, along with the
% corresponding parameter combinations
pdcchUESpecific = struct('SearchSpace','UESpecific');
pdcchUESpecific.ControlChannelType = 'PDCCH';
pdcchUESpecific.EnableCarrierIndication = CIF;
[dciInfoUESpecific,pdcchUESpecific] = getUniqueDCILengths(enb,pdcchUESpecific);

% Establish the number of subframes in the waveform
griddims = lteResourceGridSize(enb);
L = griddims(2);
nSubframes = floor(size(rxgrid,2) / L);

% For each subframe in the waveform, attempt to decode the PDCCH
startSubframe = enb.NSubframe;
CFIs = zeros(1,nSubframes);
for i = 0:nSubframes-1

    % Extract the current subframe
    rxSubframe = rxgrid(:,(i*L) + (1:L),:);

    % Perform channel estimation
    [hest,nest] = lteDLChannelEstimate(enb,cec,rxSubframe);

    % If the current subframe contains the first occurrence of the MIB in
    % the waveform, decode the MIB to establish the frame number
    if (enb.NSubframe==0 && i<10)
        startFrame = decodeMIB(enb,rxSubframe,hest,nest,i);
    end

    % Get PCFICH indices, extract received PCFICH symbols and corresponding
    % channel estimate, demodulate PCFICH, decode and record CFI
    pcfichIndices = ltePCFICHIndices(enb);
    [pcfichRx,pcfichHest] = lteExtractResources(pcfichIndices,rxSubframe,hest);
    pcfichBits = ltePCFICHDecode(enb,pcfichRx,pcfichHest,nest);
    enb.CFI = lteCFIDecode(pcfichBits);
    CFIs(i+1) = enb.CFI;

    % Get PDCCH indices
    pdcchIndices = ltePDCCHIndices(enb);

    % Extract received PDCCH symbols and corresponding channel estimate
    [pdcchRx,pdcchHest] = lteExtractResources(pdcchIndices,rxSubframe,hest);

    % Perform PDCCH demodulation to obtain the received PDCCH bits, which
    % may contain encoded DCI messages for one or more users
    [pdcchBits,pdcchSymbols] = ltePDCCHDecode(enb,pdcchRx,pdcchHest,nest);

    % Initialize array of PDCCH format / candidate / DCI format
    % combinations, which represent possible UEs (i.e. possible locations
    % for DCI messages providing a downlink or uplink grant for a UE)
    possibleUEs = [];

    % PDCCH format for UE-specific search space can be 0, 1, 2, or 3
    for pdcchFormat = 0:3

        ue = struct();

        % Get all PDCCH candidate indices and the number of candidates M
        % for the current PDCCH format
        ue.PDCCHFormat = pdcchFormat;
        candidates = getPDCCHCandidates(enb,ue);
        M = size(candidates,1);

        % For each candidate
        for m = 1:M

            % Record PDCCH candidate indices
            ue.Candidate = candidates(m,:);

            % For each DCI format in the UE-specific search space
            dciFormats = fieldnames(dciInfoUESpecific);
            for dciFormatIdx = 1:length(dciFormats)

                % Record DCI format
                ue.DCIFormat = dciFormats{dciFormatIdx};

                % Record this PDCCH format / candidate / DCI format
                % combination as a possible "UE". For DCI formats that have
                % different lengths across the UE-specific higher-layer
                % parameters, each length is recorded as a different
                % possible UE
                dciLengths = dciInfoUESpecific.(ue.DCIFormat);
                for dciLengthIdx = 1:length(dciLengths)
                    ue.DCILength = dciLengths(dciLengthIdx);
                    ue.PDCCH = pdcchUESpecific.(ue.DCIFormat)(dciLengthIdx);
                    possibleUEs = [possibleUEs ue]; %#ok<AGROW>
                end

            end

            % For PDCCH formats 2 or 3, record the possibility of a DCI
            % message in the common search space in this candidate location
            % with format 1A or 1C. Such DCI messages correspond to System
            % Information, Paging, or Random Access Response message rather
            % than uplink or downlink grants for a UE, but are searched for
            % in this example for completeness
            if (any(pdcchFormat==[2 3]))
                for dciFormat = {'Format1A' 'Format1C'}
                    ue.DCIFormat = dciFormat{1};
                    ue.DCILength = dciInfoCommon.(ue.DCIFormat);
                    ue.PDCCH = pdcchCommon.(ue.DCIFormat);
                    possibleUEs = [possibleUEs ue]; %#ok<AGROW>
                end
            end

        end

    end

    % For each possible UE
    for ue = possibleUEs

        % Get the received candidate bits from the received PDCCH bits (for
        % DCI decoding)
        bitIdx = ue.Candidate;
        candidateBits = pdcchBits(bitIdx(1):bitIdx(2));

        % Get the received candidate symbols from the received PDCCH
        % symbols (for PDCCH power estimation). The modulation order Qm = 2
        % is used to convert candidate bit indices into candidate symbol
        % indices (QPSK modulation is always used for PDCCH)
        Qm = 2;
        symIdx = [((bitIdx(1) - 1) / Qm) + 1 bitIdx(2)/Qm];
        candidateSymbols = pdcchSymbols(symIdx(1):symIdx(2));

        % Decode the received candidate bits and get the RNTI. Assuming a
        % CRC pass (CRC = 0), the 2nd output from lteDCIDecode will
        % correspond to the RNTI
        [dciMessageBits,RNTI] = lteDCIDecode(ue.DCILength,candidateBits);

        % Re-encode the decoded DCI message bits (using the detected RNTI)
        % and establish the number of bit errors between the re-encoded
        % candidate bits and received candidate bits
        ue.RNTI = RNTI;
        reencodedCandidateBits = lteDCIEncode(ue,dciMessageBits);
        numErrors = sum(int8(candidateBits > 0) ~= reencodedCandidateBits);

        % If the number of bit errors is greater than maxErrors, continue
        % to the next possible UE (the rest of the loop body here is not
        % executed)
        if (numErrors > maxErrors)
            continue;
        end

        % Create DCI message structure from message bit payload. This is
        % performed because for some DCI formats (e.g. format 0 versus
        % format 1A), the true DCI format amongst DCI formats with
        % the same length can be determined by the value of a message bit
        dci = lteDCI(enb,ue.PDCCH,dciMessageBits);

        % Create table entry for the current DCI message
        result = struct();
        result.Subframe = i;
        result.DetectedRNTI = string(dec2hex(ue.RNTI,4));
        result.NumErrors = numErrors;
        result.DCIFormat = string(dci.DCIFormat);
        result.PDCCHFormat = ue.PDCCHFormat;
        result.Candidate = ue.Candidate;
        result.PDCCHPower = round(10*log10(var(candidateSymbols)),2);
        result.DCI = {dci};
        result = struct2table(result);

        % Check if a DCI message has previously been successfully decoded
        % in this subframe with the same RNTI, DCI format and starting
        % candidate location as the current DCI message (but with a
        % different PDCCH format)
        if (~isempty(results))
            match = (results.Subframe == result.Subframe);
            match = match & (results.DetectedRNTI == result.DetectedRNTI);
            match = match & strcmpi(results.DCIFormat,result.DCIFormat);
            match = match & (results.Candidate(:,1) == result.Candidate(1));
            match = find(match~=0);
        else
            match = [];
        end

        % If a DCI message satisfies the criteria above, it must have been
        % for a smaller PDCCH format and therefore represents successful
        % decoding of part of the current message, i.e. decoding a subset
        % of the candidate Control Channel Elements (CCEs). Therefore the
        % previous result can be replaced with the current result. Note
        % that for larger PDCCH formats the number of bit errors will tend
        % to be bigger as there are more candidate bits, so at low SNRs the
        % detected PDCCH format here may be lower than the true PDCCH
        % format (i.e. the number of errors in the bits for the true PDCCH
        % format exceeds maxErrors)
        if (isempty(match))
            results = [results; result]; %#ok<AGROW>
        else
            results(match,:) = result;
        end

    end

    % Update the subframe number
    enb.NSubframe = mod(enb.NSubframe + 1,10);

end

% Remove results whose estimated PDCCH power (in dB) is lower than the
% minimum power threshold. Without this step, received candidate symbols
% consisting solely of noise (even at a low power) can trigger false
% detections
if (~isempty(results))
    results(results.PDCCHPower < minPDCCHPower,:) = [];
end

% Check if results are empty
if (isempty(results))
    disp('No RNTIs found.');
    return;
end

% In any given subframe, in the case of overlapping results (i.e. where the
% candidate indices of one result are a subset of another), the result with
% the lowest number of bit errors will be selected
overlapping = [];
for i = unique(results.Subframe).'

    % Find result rows which correspond to the current subframe and extract
    % those results
    sf = find(results.Subframe == i).';

    % For each pair of results in this subframe
    for a = sf
        for b = sf

            ca = results{a,'Candidate'};
            cb = results{b,'Candidate'};

            % If the first result's candidate indices are a subset of the
            % second result's candidate indices
            if (ca(1)>=cb(1) && ca(2)<=cb(2))

                % If the first result has more errors
                if (results{a,'NumErrors'}>results{b,'NumErrors'})

                    % Mark the first result in the pair as overlapping
                    % (i.e. mark it for removal)
                    overlapping = [overlapping a]; %#ok<AGROW>

                end

            end

        end
    end

end

% Remove overlapping results
results(overlapping,:) = [];

% Add a label for each row of the results table
results.Properties.RowNames = strsplit(num2str(1:height(results)));

Display Results Table

The table of detected RNTIs and other information associated with the detected DCI messages is displayed. Each row of this table includes:

  • Subframe: The subframe number (relative to the start of the received waveform) in which the detected RNTI occurs.

  • DetectedRNTI: The detected RNTI.

  • NumErrors: The number of bit errors between the re-encoded candidate bits and received candidate bits (less than or equal to maxErrors).

  • DCIFormat: The DCI format of the DCI message. Note that during the UE detection process, only DCI formats with unique lengths were used, as only the length of the output DCI message influences the decoding process (specifically, the rate matching prior to convolutional decoding). Within the LTE system, multiple DCI messages can have the same length for the same eNodeB configuration. This ambiguity is resolved in normal system operation by each UE being assigned a Transmission Mode (TM). TS 36.213 Table 7.1-5 [ 3 ] shows which DCI formats are applicable for a given TM, and all formats for a given TM will have unique lengths. Because this example operates without knowledge of the UEs and their TMs, the true DCI format detected for the UE may not match the DCI format here, but the length will match. The function lteDCIInfo can be used to establish which other DCI formats have the same length as the DCI format here.

  • PDCCHFormat: The PDCCH format of the received candidate bits for the DCI message. For more information about PDCCH formats, see the PDCCH Blind Search and DCI Decoding example.

  • Candidate: The inclusive [begin,end] bit indices (1-based) of the PDCCH candidate location for the DCI message i.e. the location of the received candidate bits in the set of overall received PDCCH bits. The overall set of PDCCH search space candidates for a given eNodeB configuration, PDCCH format and RNTI can be found using the ltePDCCHSpace function.

  • PDCCHPower: The power of the received candidate symbols (in dB) associated with this DCI message.

  • DCI: The decoded DCI message structure, assuming that the DCI format noted above is the true DCI format for the message.

disp(results);
          Subframe    DetectedRNTI    NumErrors    DCIFormat     PDCCHFormat     Candidate     PDCCHPower        DCI     
          ________    ____________    _________    __________    ___________    ___________    __________    ____________

    1         0          "9397"           1        "Format0"          1           1     144       0.32       {1x1 struct}
    2         0          "F24A"           0        "Format0"          2         289     576       3.24       {1x1 struct}
    3         0          "717A"           0        "Format2A"         2         577     864       3.36       {1x1 struct}
    4         1          "717A"           0        "Format2A"         2           1     288       2.99       {1x1 struct}
    5         1          "717A"           0        "Format0"          2         289     576       3.02       {1x1 struct}
    6         1          "9397"           0        "Format0"          1         577     720      -0.22       {1x1 struct}
    7         2          "717A"           0        "Format2A"         2           1     288       3.19       {1x1 struct}
    8         2          "9397"           0        "Format0"          1         289     432       0.52       {1x1 struct}
    9         3          "4C87"           0        "Format2A"         2           1     288       3.16       {1x1 struct}
    10        3          "9397"           0        "Format0"          1         289     432      -0.11       {1x1 struct}
    11        3          "96C1"           0        "Format2A"         1         577     720       3.27       {1x1 struct}
    12        4          "717A"           0        "Format0"          2           1     288       3.41       {1x1 struct}
    13        4          "9397"           2        "Format0"          0         433     504       1.07       {1x1 struct}
    14        4          "717A"           1        "Format2A"         1         577     720       3.57       {1x1 struct}
    15        5          "9397"           0        "Format0"          0           1      72       2.42       {1x1 struct}
    16        5          "96C1"           1        "Format0"          0         145     216        0.6       {1x1 struct}
    17        5          "717A"           0        "Format0"          1         289     432       5.68       {1x1 struct}
    18        5          "4C87"           2        "Format2A"         0         577     648       1.66       {1x1 struct}
    19        6          "717A"           0        "Format2A"         2           1     288       2.95       {1x1 struct}
    20        6          "9397"           0        "Format0"          1         289     432       0.27       {1x1 struct}
    21        6          "077B"           0        "Format0"          1         433     576       6.17       {1x1 struct}
    22        7          "FFFF"           0        "Format1A"         2           1     288       0.14       {1x1 struct}
    23        7          "9397"           1        "Format0"          1         289     432       1.38       {1x1 struct}
    24        7          "4C87"           0        "Format2A"         1         577     720       6.21       {1x1 struct}
    25        8          "4C87"           0        "Format2A"         2           1     288       3.03       {1x1 struct}
    26        8          "717A"           0        "Format2A"         2         577     864       3.05       {1x1 struct}
    27        9          "717A"           0        "Format2A"         2         577     864       3.05       {1x1 struct}
    28       10          "4C87"           0        "Format2A"         2           1     288       3.11       {1x1 struct}
    29       10          "F24A"           0        "Format0"          2         289     576       3.25       {1x1 struct}
    30       10          "9397"           0        "Format2A"         1         721     864       2.98       {1x1 struct}
    31       11          "4C87"           0        "Format2A"         2           1     288       2.27       {1x1 struct}
    32       11          "717A"           0        "Format0"          2         289     576       2.37       {1x1 struct}
    33       11          "F24A"           0        "Format2A"         2         577     864       2.38       {1x1 struct}
    34       12          "FFFF"           2        "Format1A"         1           1     144        0.7       {1x1 struct}
    35       12          "4C87"           0        "Format2A"         2         865    1152       3.85       {1x1 struct}
    36       14          "717A"           2        "Format0"          1           1     144       2.64       {1x1 struct}
    37       14          "B073"           2        "Format2"          0         145     216       3.01       {1x1 struct}
    38       14          "717A"           0        "Format2A"         2         577     864       3.58       {1x1 struct}

Plot Detected RNTIs

A plot is produced showing the detected RNTIs versus subframe number. The received downlink resource grid is displayed and the RNTIs are used to label the PDSCH resources signaled by the corresponding DCI messages. An empty uplink resource grid is also displayed and the PUSCH resources signaled by any DCI format 0 or format 4 messages are displayed and are labeled with the corresponding RNTIs. A question mark appears after any RNTI for which the number of bit errors between the re-encoded candidate bits and received candidate bits, NumErrors, is greater than zero (and less than or equal to maxErrors). The System Frame Numbers (SFNs) used here use integers to represent the SFN and decimals (tenths) to represent the subframe within the SFN.

enb.NFrame = startFrame;
enb.NSubframe = startSubframe;
enb.CFI = CFIs;
summary = hPlotDetectedRNTIs(results,enb,rxgrid);

Display Summary of Detected PDSCH or PUSCH Resource Allocations

Finally, a summary of the detected PDSCH or PUSCH resource allocations is displayed. For each detected DCI message the following is displayed:

  • System Frame Number (SFN)

  • RNTI

  • Number of errors

  • DCI format (and associated link direction)

  • Allocated PRBs

  • An estimate of the received power in the allocated PRBs

Note that because no uplink resource grid is present, the power estimated for uplink DCI messages will be -Inf. Note that if a summary per RNTI is required, the summary table can easily be sorted to group results for the same RNTI using sortrows(summary,'RNTI').

disp(summary);
     SFN      RNTI     NumErrors    DCIFormat     LinkDirection                    PRBSet                     Power
    _____    ______    _________    __________    _____________    _______________________________________    _____

    833.3    "9397"        1        "Format0"      "Uplink"        "[7 8]"                                     -Inf
    833.3    "F24A"        0        "Format0"      "Uplink"        "[9...23]"                                  -Inf
    833.3    "717A"        0        "Format2A"     "Downlink"      "[0...24]"                                 15.98
    833.4    "717A"        0        "Format2A"     "Downlink"      "[0...24]"                                 16.24
    833.4    "717A"        0        "Format0"      "Uplink"        "[22 23]"                                   -Inf
    833.4    "9397"        0        "Format0"      "Uplink"        "[20 21]"                                   -Inf
    833.5    "717A"        0        "Format2A"     "Downlink"      "[2 3 6 7 10 11 14 15 18 19 22 23]"        15.95
    833.5    "9397"        0        "Format0"      "Uplink"        "[22 23]"                                   -Inf
    833.6    "4C87"        0        "Format2A"     "Downlink"      "[0 1 4 5 8 9 12 13 16 17 20...24]"         14.9
    833.6    "9397"        0        "Format0"      "Uplink"        "[22 23]"                                   -Inf
    833.6    "96C1"        0        "Format2A"     "Downlink"      "[2 3 6 7 10 11 14 15 18 19]"              15.38
    833.7    "717A"        0        "Format0"      "Uplink"        "[16 17]"                                   -Inf
    833.7    "9397"        2        "Format0"      "Uplink"        "[14 15]"                                   -Inf
    833.7    "717A"        1        "Format2A"     "Downlink"      "[0...24]"                                 13.96
    833.8    "9397"        0        "Format0"      "Uplink"        "[16 17]"                                   -Inf
    833.8    "96C1"        1        "Format0"      "Uplink"        "[14 15]"                                   -Inf
    833.8    "717A"        0        "Format0"      "Uplink"        "[12 13]"                                   -Inf
    833.8    "4C87"        2        "Format2A"     "Downlink"      "[0...24]"                                 13.98
    833.9    "717A"        0        "Format2A"     "Downlink"      "[0...24]"                                 15.32
    833.9    "9397"        0        "Format0"      "Uplink"        "[20 21]"                                   -Inf
    833.9    "077B"        0        "Format0"      "Uplink"        "[18 19]"                                   -Inf
      834    "FFFF"        0        "Format1A"     "Downlink"      "[0...7]"                                  17.31
      834    "9397"        1        "Format0"      "Uplink"        "[20 21]"                                   -Inf
      834    "4C87"        0        "Format2A"     "Downlink"      "[8...24]"                                 16.71
    834.1    "4C87"        0        "Format2A"     "Downlink"      "[20 21]"                                  17.68
    834.1    "717A"        0        "Format2A"     "Downlink"      "[0...19 22...24]"                         18.11
    834.2    "717A"        0        "Format2A"     "Downlink"      "[0...24]"                                 18.38
    834.3    "4C87"        0        "Format2A"     "Downlink"      "[0 1 4...24]"                             17.51
    834.3    "F24A"        0        "Format0"      "Uplink"        "[22 23]"                                   -Inf
    834.3    "9397"        0        "Format2A"     "Downlink"      "[2]"                                      18.42
    834.4    "4C87"        0        "Format2A"     "Downlink"      "[0...3 6 7 10 11 14 15 18 19 22...24]"     15.9
    834.4    "717A"        0        "Format0"      "Uplink"        "[22 23]"                                   -Inf
    834.4    "F24A"        0        "Format2A"     "Downlink"      "[4]"                                       16.8
    834.5    "FFFF"        2        "Format1A"     "Downlink"      "[0...13]"                                 14.12
    834.5    "4C87"        0        "Format2A"     "Downlink"      "[14...24]"                                10.18
    834.7    "717A"        2        "Format0"      "Uplink"        "[16 17]"                                   -Inf
    834.7    "B073"        2        "Format2"      "Downlink"      "[7 11 15 19]"                             14.08
    834.7    "717A"        0        "Format2A"     "Downlink"      "[0...24]"                                 14.32

Observations on Detected RNTIs

The following observations can be made using the results summary and plot:

  • System Information (SI): The RNTI used for System Information (SI-RNTI) is FFFF hex. DCI messages associated with System Information Blocks (SIBs) can be seen in SFN = 834.0 (NFrame = 834, NSubframe = 0) and SFN = 834.5 (NFrame = 834, NSubframe = 5). SystemInformationBlockType1 (SIB1) occurs in subframe 5 of even frames, so the occurrence in SFN = 834.5 is SIB1. Other SIBs are dynamically scheduled, with the scheduling information being contained in SIB1.

  • RNTIs occurring in multiple subframes: The RNTIs 717A and 4C87 occur frequently throughout the waveform, typically with zero errors, so they are likely to correspond to active UEs.

The detection process can result in errors due to noise and distortion in the downlink signals. There are two main types of errors, these are described below using examples:

  • Missed detection: Observe SFN 834.6. There is energy in PDSCH resource blocks 0 to 7. However, no DCI message has been detected. Rerun the simulation setting maxErrors=3. Now RNTI 4C87 is detected in this region. This RNTI is present in other subframes, which means that this is likely to be a genuine UE.

  • False positive: Observe the PDSCH allocation with RNTI B073 in the final subframe of the waveform. It overlaps with PDSCH allocation 717A. Given that RNTI 717A occurs frequently throughout the waveform and that RNTI B073 decodes with 2 errors, it is likely that RNTI B073 is a "false positive" detection.

Appendix

This example uses the helper function:

Selected Bibliography

  1. 3GPP TS 36.321 "Medium Access Control (MAC) protocol specification"

  2. Kumar, Hamed, Katabi and Li. "LTE Radio Analytics Made Easy and Accessible", SIGCOMM '14 (2014): 211-222

  3. 3GPP TS 36.213 "Physical layer procedures"

Local Functions

This example uses the following local functions:

  • getUniqueDCILengths: Get DCI message information for DCI formats with unique lengths

  • decodeMIB: Decode the MIB to get frame number

  • getPDCCHCandidates: Get all PDCCH candidates

% Get DCI message information for DCI formats with unique lengths, across
% all UE-specific higher-layer parameters
function [infoOut,pdcchOut] = getUniqueDCILengths(enb,pdcchIn)

    infoOut = [];

    for EnableSRSRequest = {'Off' 'On'}

        pdcchIn.EnableSRSRequest = EnableSRSRequest{1};

        for EnableMultipleCSIRequest = {'Off' 'On'}

            pdcchIn.EnableMultipleCSIRequest = EnableMultipleCSIRequest{1};

            for NTxAnts = [1 2 4]

                pdcchIn.NTxAnts = NTxAnts;

                % Get the DCI message lengths for all formats, as a
                % structure
                info = lteDCIInfo(enb,pdcchIn);

                % Convert the structure into a cell array of field names
                % and values
                formats = fieldnames(info);
                sizes = struct2cell(info);

                % Remove DCI format 3 and 3A as these DCI formats are used
                % for conveying power control commands rather than resource
                % allocations
                dci3idx = ismember(formats,{'Format3','Format3A'});
                formats(dci3idx) = [];
                sizes(dci3idx) = [];

                % Keep only DCI format 1A and 1C for the common search
                % space
                if (strcmpi(pdcchIn.SearchSpace,'Common'))
                    commonidx = ismember(formats,{'Format1A','Format1C'});
                    formats = formats(commonidx);
                    sizes = sizes(commonidx);
                end

                % Find the indices of the unique sizes, the first
                % occurrence of each unique size will be retained in the
                % original order
                [~,idxs] = unique(cat(2,sizes{:}),'stable');

                % If the current UE-specific settings yield unique sizes
                % for any format (compared to all other formats and
                % UE-specific settings thus far), then record them
                if (isempty(infoOut))
                    infoOut = cell2struct(sizes(idxs),formats(idxs));
                    pdcchOut = cell2struct(repmat({pdcchIn},size(idxs)),formats(idxs));
                else
                    sizes_out = struct2cell(infoOut);
                    sizes_out = cat(2,sizes_out{:});
                    for i = idxs.'
                        if (~any(sizes_out==sizes{i}))
                            format = formats{i};
                            infoOut.(format) = [infoOut.(format) sizes{i}];
                            pdcchOut.(format) = [pdcchOut.(format) pdcchIn];
                        end
                    end
                end

            end

        end

    end

end

% Decode the MIB to get the frame number
function startFrame = decodeMIB(enb,rxSubframe,hest,nest,i)

    pbchIndices = ltePBCHIndices(enb);
    [pbchRx, pbchHest] = lteExtractResources(pbchIndices,rxSubframe,hest);
    [~,~,nfmod4,mibbits] = ltePBCHDecode(enb,pbchRx,pbchHest,nest);
    mib = lteMIB(mibbits);
    startFrame = double(mib.NFrame) + nfmod4;
    if (i>0)
        startFrame = mod(startFrame - 1,1024);
    end

end

% Get all PDCCH candidates for a given eNodeB configuration and UE
% configuration, without having to evaluate all possible RNTIs
function pdcchCandidates = getPDCCHCandidates(enb,ue)

    % PDCCH dimensionality information
    pdcchInfo = ltePDCCHInfo(enb);

    % Aggregation level
    L = 2 ^ ue.PDCCHFormat;

    % Number of candidates
    M = floor(double(pdcchInfo.NCCE)/L);

    % 1 CCE = 9 REGs = 36 REs = 72 bits
    bitsPerCCE = 72;

    % PDCCH candidate indices within PDCCH bits (1-based)
    pdcchCandidates = L*bitsPerCCE*(0:M-1).' + [1 L*bitsPerCCE];

end