Main Content

Analyze CU-Plane Messages for O-RAN Fronthaul Testing

Since R2024a

This example shows how to analyze the contents of a packet capture (PCAP) file that contains open radio access network (O-RAN) messages sent on the fronthaul control planes and user planes (CU-Planes) between an O-RAN distributed unit (O-DU) and an O-RAN radio unit (O-RU). The example shows how to recover the IQ data from the CU-Plane messages and compare it to a test waveform, showing that the data is equivalent to a generated 5G Toolbox™ signal.

Introduction

This example analyzes a PCAP file that contains O-RAN fronthaul CU-Plane messages, as defined in TS O-RAN.WG4.CUS [1], that carry an NR test model waveform, as defined in TS 38.141-1 [2]. The PCAP file in this example was generated using the example in Generate CU-Plane Messages for O-RAN Fronthaul Test. In this example, you build CU-Plane structures containing packet information that you analyze to identify errors, estimate peak network capacity, and build a time-frequency grid of user plane (U-Plane) packets. You then compare the U-Plane waveform to the test waveform.

To analyze the PCAP file and rebuild the waveform correctly, you must know the configuration of the generated O-RAN messages. The included PCAP uses a single extended antenna-carrier identifier (eAxC ID) of 0 to transmit test model 1.1 across 100 MHz for 20 slots. These values are the same as the default values in the Generate CU-Plane Messages for O-RAN Fronthaul Test example. This example rebuilds the U-Plane using the numerology of the waveform and the symbol, slot, and subframe IDs in the U-Plane packets.

Set Configuration Parameters

This example supports the configuration flexibility of the O-RAN fronthaul generator example. While analyzing the PCAP file requires less configuration, you must know critical values or you cannot assemble the structures and waveform correctly.

In this section, configure the following parameters:

  • O-RAN — Set the compression method if it is statically configured and the IQ sample bit-width before and after compression.

  • M-Plane — O-RAN management interface. Configure the O-DU and O-RU interface fields (compression dynamics, byte order, the eAxC ID) to build the time-frequency grid and the maximum PRB size.

% Select the PCAP file to import
pcapFileName = "CUMessages.pcap";

% Select the NR test model parameters for the conformance test waveform
waveConfig = struct();
waveConfig.tm  = "NR-FR1-TM1.1";           % Test model (must be full band)
waveConfig.bw  = "100MHz";           % Channel bandwidth (MHz)
waveConfig.scs = "30kHz";           % Subcarrier spacing (kHz)

% O-RAN configuration
% Set the compression parameters
oranConfig = struct();
oranConfig.method = 'BFP';        % U-Plane compression method for static compression mode
oranConfig.cIQWidth =14;   % Compressed IQ samples bit-width (1 to 16)
oranConfig.IQWidth  = 24;                        % IQ samples bit-width before or without compression

% Set the M-Plane and general parameters
mPlaneConfig = struct();
mPlaneConfig.compMode   = 1;       % Compression mode (statically configured over M-Plane or dynamic to each U-Plane message)
mPlaneConfig.byteOrder  = 0;       % Byte order of U-Plane IQ data
mPlaneConfig.MaxNumerology = -1;    % Highest supported numerology for mixed numerology using section type 3 C-Plane messages 
mPlaneConfig.eAxCIDSelect = 0;                        % Build time-frequency grid using this eAxC ID

% Determine max PRB from conformance test waveform info
frNum = extractBetween(waveConfig.tm,'-','-');
bwTable = hNRReferenceWaveformGenerator.(strcat(frNum, "BandwidthTable"));
mPlaneConfig.MaxPRB = bwTable(waveConfig.scs,waveConfig.bw).Variables;

Build CU-Plane Data Structures from PCAP File

Use the pcapReader function to read the raw packets. Filter the control plane (C-Plane) packets using eCPRI message type label "Real Time Control Data". Filter the U-Plane packets by the label "IQ Data".

pcapReadObj = pcapReader(pcapFileName);                                                 % Create PCAP Reader object
rawCPackets = readAll(pcapReadObj, 'ecpri.MessageType == RealTimeControlData');         % Read raw C-Plane packets
reset(pcapReadObj);                                                                     % Reset PCAP reader object index
rawUPackets = readAll(pcapReadObj, 'ecpri.MessageType == IQData');                      % Read raw U-Plane packets

Use the hORANProtocolDecoder.cPlaneDecoder function to create C-Plane message data structures. Use the hORANProtocolDecoder.uPlaneDecoder function to create U-Plane message data structures.

cPlaneMsgs = hORANProtocolDecoder.cPlanePCAPDecoder(rawCPackets);                           % Build C-Plane structures
uPlaneMsgs = hORANProtocolDecoder.uPlanePCAPDecoder(rawUPackets,oranConfig,mPlaneConfig);   % Build U-Plane structures

Analyze O-RAN Packets

Use the hORANPacketAnalyzer.packetSummary function to visualize the CU-Plane packets and obtain a high-level summary of the O-RAN packet.

To identify specific packets, you can use typical table functions such as sortrows. You can also display only the C-Plane packets or only packets associated with a specific eAxC ID.

infoPackets = hORANPacketAnalyzer.packetSummary(cPlaneMsgs,uPlaneMsgs)
infoPackets=2540×8 table
    PacketNo    Timestamp (Microseconds)         Source           Destination       Length (Bytes)        Protocol                                      Info                                 eAxCID
    ________    ________________________    ________________    ________________    ______________    _________________    ______________________________________________________________    ______

        1                   0               {'563BBEA9924C'}    {'DA14DEB05563'}           60         "ORAN FH C-Plane"    {'Section Type: 1, ID: 0, (PRBs: all PRBs, Symbols : 0-13), '}      0   
        2                 120               {'563BBEA9924C'}    {'DA14DEB05563'}         1496         "ORAN FH U-Plane"    {'Section: 0, (PRBs: 0-33, Symbols : 0), '                   }      0   
        3                 120               {'563BBEA9924C'}    {'DA14DEB05563'}         1496         "ORAN FH U-Plane"    {'Section: 0, (PRBs: 34-67, Symbols : 0), '                  }      0   
        4                 120               {'563BBEA9924C'}    {'DA14DEB05563'}         1496         "ORAN FH U-Plane"    {'Section: 0, (PRBs: 68-101, Symbols : 0), '                 }      0   
        5                 120               {'563BBEA9924C'}    {'DA14DEB05563'}         1496         "ORAN FH U-Plane"    {'Section: 0, (PRBs: 102-135, Symbols : 0), '                }      0   
        6                 120               {'563BBEA9924C'}    {'DA14DEB05563'}         1496         "ORAN FH U-Plane"    {'Section: 0, (PRBs: 136-169, Symbols : 0), '                }      0   
        7                 120               {'563BBEA9924C'}    {'DA14DEB05563'}         1496         "ORAN FH U-Plane"    {'Section: 0, (PRBs: 170-203, Symbols : 0), '                }      0   
        8                 120               {'563BBEA9924C'}    {'DA14DEB05563'}         1496         "ORAN FH U-Plane"    {'Section: 0, (PRBs: 204-237, Symbols : 0), '                }      0   
        9                 120               {'563BBEA9924C'}    {'DA14DEB05563'}         1496         "ORAN FH U-Plane"    {'Section: 0, (PRBs: 238-271, Symbols : 0), '                }      0   
       10                 120               {'563BBEA9924C'}    {'DA14DEB05563'}           77         "ORAN FH U-Plane"    {'Section: 0, (PRBs: 272, Symbols : 0), '                    }      0   
       11                 156               {'563BBEA9924C'}    {'DA14DEB05563'}         1496         "ORAN FH U-Plane"    {'Section: 0, (PRBs: 0-33, Symbols : 1), '                   }      0   
       12                 156               {'563BBEA9924C'}    {'DA14DEB05563'}         1496         "ORAN FH U-Plane"    {'Section: 0, (PRBs: 34-67, Symbols : 1), '                  }      0   
       13                 156               {'563BBEA9924C'}    {'DA14DEB05563'}         1496         "ORAN FH U-Plane"    {'Section: 0, (PRBs: 68-101, Symbols : 1), '                 }      0   
       14                 156               {'563BBEA9924C'}    {'DA14DEB05563'}         1496         "ORAN FH U-Plane"    {'Section: 0, (PRBs: 102-135, Symbols : 1), '                }      0   
       15                 156               {'563BBEA9924C'}    {'DA14DEB05563'}         1496         "ORAN FH U-Plane"    {'Section: 0, (PRBs: 136-169, Symbols : 1), '                }      0   
       16                 156               {'563BBEA9924C'}    {'DA14DEB05563'}         1496         "ORAN FH U-Plane"    {'Section: 0, (PRBs: 170-203, Symbols : 1), '                }      0   
      ⋮

Approximate the bit rate of the fronthaul traffic between O-DU and O-RU using the timestamps.

cMBitRate = (sum([cPlaneMsgs.Length])*8)/(max([cPlaneMsgs.Timestamp])-min([cPlaneMsgs.Timestamp]))
cMBitRate = 
1.0105
uMBitRate = (sum([uPlaneMsgs.Length])*8)/(max([uPlaneMsgs.Timestamp])-min([uPlaneMsgs.Timestamp]))
uMBitRate = 
2.7078e+03

Inspect Individual Packets

Use the hORANPacketAnalyzer.packetDetails function to inspect individual packets and obtain O-RAN application layer packet information.

Specify the packet number to inspect the O-RAN application layer content of any individual packet.

packetNo = 101;            % Packet 101 is the 2nd C-Plane packet in the O-RAN stream
[infoTime, infoSectionHeader, infoSections, infoSectExt]= hORANPacketAnalyzer.packetDetails(cPlaneMsgs,uPlaneMsgs,packetNo,mPlaneConfig)
infoTime=1×7 table
    LinkDirection    PayloadVersion             Filter              FrameID    SubframeID    SlotID    SymbolID
    _____________    ______________    _________________________    _______    __________    ______    ________

        "DL"               1           "standard channel filter"       0           0           1          0    

infoSectionHeader=1×3 table
    NumberOfSections    SectionType    UdCompHdr
    ________________    ___________    _________

           1                 1             0    

infoSections=1×6 table
    SectionID      RBs      SymInc                  REMask                  NumSymbol                 Ef             
    _________    _______    ______    __________________________________    _________    ____________________________

        0        0:1:272      0       1  1  1  1  1  1  1  1  1  1  1  1       14        "No section extensions used"

infoSectExt = 
"No section extensions"

Check CU-Plane Messages for Errors

Use the hORANPacketAnalyzer.errorCheck function to detect different protocol errors in the CU-Plane. Detectable errors include:

  • SeqErr — Sequence errors in the O-RAN packet stream for C or U-Plane

  • NumSymbolErr — Bound errors in the "NumSymbol" field of C-Plane packets

  • PlaneReservedErr — Nonzero values in reserved fields, if they are present in the C or U-Plane

  • udCompHdrErr — Nonzero udCompHeader value in C-Plane when compression is dynamically configured

  • SymIncErr — Nonzero values in the "SymInc" field of U-Plane packets

cPlaneErrorCheck = hORANPacketAnalyzer.errorCheck(cPlaneMsgs,mPlaneConfig)
cPlaneErrorCheck = struct with fields:
               SeqErr: 0
         NumSymbolErr: 0
    cPlaneReservedErr: 0

uPlaneErrorCheck = hORANPacketAnalyzer.errorCheck(uPlaneMsgs)
uPlaneErrorCheck = struct with fields:
       SeqErr: 0
    SymIncErr: 0

Generate Test Waveform

Use the hNRReferenceWaveformGenerator class to generate the 5G NR test model waveform.

tmWaveGen = hNRReferenceWaveformGenerator(waveConfig.tm,waveConfig.bw, ...
    waveConfig.scs,"FDD");

% Generate waveform and get resource grid of one frame of data
[~,gridSet] = generateWaveform(tmWaveGen);
tmGrid = gridSet.ResourceGridBWP;

Build U-Plane Time-Frequency Grid

Inspect and observe that the size of the IQ data in the first U-Plane message is less than the test waveform.

singlePacketIQ = [uPlaneMsgs(1).oran.Sections(1).PRBs.IQData];
[singlePacketREs, singlePacketSymbols] = size(singlePacketIQ(:))
singlePacketREs = 
408
singlePacketSymbols = 
1
[refWaveformREs, refWaveformSymbols] = size(tmGrid)
refWaveformREs = 
3276
refWaveformSymbols = 
280

Use the hORANProtocolDecoder.uPlaneGridBuilder function to generate the entire time-frequency grid from all the U-Plane packets. This function uses the timing information in each U-Plane packet to assign it to the grid, so packets can be received out of order.

scs = str2double(extractBefore(waveConfig.scs,'kHz'));
uPlaneGrid = hORANPacketAnalyzer.uPlaneGridBuilder(uPlaneMsgs,oranConfig, mPlaneConfig, scs);
[uPlaneGridREs, uPlaneGridSymbols] = size(uPlaneGrid)
uPlaneGridREs = 
3276
uPlaneGridSymbols = 
280

The reconstructed uPlaneGrid contains the same number of resource elements and symbols as the test waveform. Observe that the constellation of the data is QPSK, also as expected for the test waveform.

figure();
plot(uPlaneGrid,'o');
xlabel('In-Phase'); ylabel('Quadrature')
title('U-Plane Grid Constellation');
m = abs(max(uPlaneGrid,[],"all")) * 1.1;
axis([-m m -m m]);

Figure contains an axes object. The axes object with title U-Plane Grid Constellation, xlabel In-Phase, ylabel Quadrature contains 280 objects of type line.

Test U-Plane Signal Performance

Ensure both waveforms are the same size. Different lengths in time or frequency indicates an error in the U-Plane waveform.

if any(size(tmGrid) ~= size(uPlaneGrid))
    warning('Size mismatch in time or frequency between U-Plane and Conformance Test waveform');
    evmSize = min([size(tmGrid);size(uPlaneGrid)]);
    tmGrid = tmGrid(1:evmSize(1),1:evmSize(2));
    uPlaneGrid = uPlaneGrid(1:evmSize(1),1:evmSize(2));
end

You must apply a scaling factor as the PCAP file contains integer values scaled to their full bit width, while the test waveform has a unity magnitude.

scaleFactor = max(tmGrid,[],"all")/max(uPlaneGrid,[],"all");     % Scaling factor to take digital waveform down to unity magnitude
uPlaneGridScaled = uPlaneGrid.*scaleFactor;

Instantiate the comm.EVM System object™ to calculate the Error Vector Magnitude (EVM) between the reference waveform (tmGrid) and the scaled U-Plane grid (uPlaneGridScaled).

evm = comm.EVM;
errorSigRms = evm(uPlaneGridScaled, tmGrid);
peakError = max(errorSigRms);
peakEVMdB = 20*log10(peakError/100)
peakEVMdB = 
-319.0918

The peak EVM is negligible, so the waveform constructed from the PCAP file U-Plane is the same as the test waveform.

References

[1] TS O-RAN.WG4.CUS. "O-RAN Fronthaul Working Group - Control, User and Synchronization Plane Specification".

[2] 3GPP TS 38.141-1. "NR; Base Station (BS) conformance testing Part 1: Conducted conformance testing." 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.

See Also

Functions

Related Topics