Analyze CU-Plane Messages for O-RAN Fronthaul Testing
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-PlaneNumSymbolErr
— Bound errors in the "NumSymbol" field of C-Plane packetsPlaneReservedErr
— Nonzero values in reserved fields, if they are present in the C or U-PlaneudCompHdrErr
— Nonzero udCompHeader value in C-Plane when compression is dynamically configuredSymIncErr
— 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]);
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.