Generate CU-Plane Messages for O-RAN Fronthaul Test
This example shows how to generate fronthaul control plane and user plane (CU-Plane) plane messages for open radio access network (O-RAN) conformance tests using 5G Toolbox™. These O-RAN compliant messages are considered as split option 7.2x test vectors generated from an O-RAN distributed unit (O-DU). The example generates a packet capture (PCAP) file that contains these messages.
Introduction
This example shows how to build the O-RAN fronthaul CU-Plane messages, as defined in TS O-RAN.WG4.CUS, to transmit an NR test model or an uplink FRC, as defined in TS 38.141-1 and TS 38.104, respectively. These O-RAN compliant messages are considered as split option 7.2x test vectors generated from an O-DU. The example generates a PCAP file, which contains the messages. You can use the generated packets to test an O-RAN radio unit (O-RU) following the conformance test specifications in TS O-RAN.WG4.CONF. You can also analyze the generated PCAP file by using the Analyze CU-Plane Messages for O-RAN Fronthaul Testing example or third-party packet analysis tools. In this example, Wireshark is used to verify that the content of the CU-Plane messages is as expected.
This example builds the CU-Plane messages required to transmit the specified NR test model or uplink FRC waveform. The example generates at least one control plane (C-Plane) message for every extended antenna-carrier identifier (eAxC ID) per slot. Each C-Plane message is associated with one or more user plane (U-Plane) messages per symbol, depending on the Ethernet MTU size. You can send the C-Plane messages as section type 1 (for most data) or section type 3 (for mixed numerology data). The U-Plane messages encapsulate the IQ data using a single section per message. This diagram illustrates the flow of the generated CU-Plane messages for a single eAxC ID using section type 1 C-Plane messages.
Set Configuration Parameters
The constructed data frames consist of the entire grid of a 5G NR test model or an uplink FRC, as defined in TS 38.141-1 and TS 38.104, respectively. You can set the waveform, the channel bandwidth, and the subcarrier spacing of the test waveform. This example supports FDD duplex mode only and does not apply any precoding or beamforming.
The generated PCAP file includes the Ethernet, eCPRI, and O-RAN protocols. In this section, you can configure parameters available in the three protocols:
O-RAN — Set the compression method and the IQ samples bit-width before and after compression.
eCPRI — Set the eAxC ID fields. To create multiple data streams, use a vector of IDs to replicate the waveform on each CU-Plane stream.
Ethernet — Set the Ethernet MTU, VLAN tag, and the MAC source and destination addresses.
This example does not generate management plane (M-Plane) messages. However, the example enables you to set these M-Plane parameters: compression mode, byte order, number of bits per field in eAxC ID, the timing between a C-Plane message and U-Plane message, and the maximum supported numerology.
Waveform Configuration
Select the reference waveform parameters.
waveConfig = struct(); waveConfig.tm = "NR-FR1-TM1.1"; % Test model (TM) or uplink FRC (G) waveConfig.bw = "100MHz"; % Channel bandwidth (MHz)li waveConfig.scs = "30kHz"; % Subcarrier spacing (kHz)
O-RAN Configuration
Set the compression parameters.
oranConfig = struct(); oranConfig.method = 'BFP'; % U-Plane compression method. For modulation compression, SectionType must be 1. oranConfig.SectionType = 1; % C-Plane message Section Type oranConfig.IQWidth = 24; % IQ samples bit-width before or without compression
The cIQWidth
field only applies to BFP, block scaling, and mu-Law compression methods.
oranConfig.cIQWidth =14; % Compressed IQ samples bit-width (1 to 16).
eCPRI Configuration
Set the eAxC ID values in terms of the DU_Port_ID, BandSector_ID, CC_ID and RU_Port_ID subfields. The eAxCIDBits
field of the mPlaneConfig
structure defines the bit-width of each ID part.
To specify multiple eAxC ID values, use a vector of values in each ID field. In that case, the same messages are sent on all specified eAxC dataflows.
eCPRIConfig = struct(); eCPRIConfig.DUPortID = 0; % Distributed unit identifiers eCPRIConfig.BandSectorID = 0; % Band and sector identifiers eCPRIConfig.CCID = 0; % Component carrier identifiers eCPRIConfig.RUPortID = 0; % Spatial stream identifiers
Expand any vectors of values in the four eAxC ID subfields into combinations of individual values, where each combination is a single eAxC ID. Each eAxC ID is returned as a separate element of a structure array.
eCPRIConfig = eAxCIDConfigExpand(eCPRIConfig);
Ethernet Configuration
Set Ethernet MTU size in bytes.
ethernetConfig = struct();
ethernetConfig.MTU = 1500;
Select the Ethernet VLAN tag.
ethernetConfig.TPID = 0x8100; % Tag protocol identifier ethernetConfig.priority =7; % Priority level (0 to 7) ethernetConfig.DEI = 0; % Drop eligible indicator ethernetConfig.VID = 1; % Unique VLAN identifier (0 to 4095)
Set the MAC source and destination addresses. The source address represents the O-DU, and the destination address represents the O-RU.
ethernetConfig.sourceAddress = [0x56 0x3b 0xbe 0xa9 0x92 0x4c]; % MAC source address (hex or string input) ethernetConfig.destAddress = [0xda 0x14 0xde 0xb0 0x55 0x63]; % MAC destination address (hex or string input)
M-Plane Configuration
Set the general M-Plane parameters.
mPlaneConfig = struct(); mPlaneConfig.compMode = 1; % Compression mode (statically configured over M-Plane or dynamic in the messages) mPlaneConfig.byteOrder = 0; % Byte order of U-Plane IQ data mPlaneConfig.eAxCIDBits = [2 6 4 4]; % Bits per field in eAxC ID (DUPortID,BandSectorID,CCID,RUPortID) mPlaneConfig.MaxNumerology = -1; % Highest supported numerology for mixed numerology using section type 3 C-Plane messages
Configure the time between the transmission of the C-Plane messages and the arrival of the first associated U-Plane message. For downlink configurations, set the Tcp_adv_dl
parameter, and for uplink configurations, set the T1a_cp_ul
and Ta3_up_ul
parameters. For further information on CU-Plane timing, see TS O-RAN.WG4.CUS Section 4.4.3 [2].
mPlaneConfig.Tcp_adv_dl = 0.00012; % DL CU-Plane timing advance (secs) mPlaneConfig.T1a_cp_ul = 0.00009; % UL C-Plane timing advance (secs) mPlaneConfig.Ta3_up_ul = 0.00003; % UL U-Plane timing delay (secs)
Packet Capture File
Set the name and format of the PCAP/PCAPNG file.
pcapFileName = 'CUMessages'; % PCAP file name pcapFormat = 0; % PCAP or PCAPNG file format
Generate U-Plane Data
Use the hNRReferenceWaveformGenerator
class to generate the complete 5G NR waveform that you selected in the previous section. The resource grid of the NR frame (split option 7.2x) is the data carried in the U-Plane messages.
tmWaveGen = hNRReferenceWaveformGenerator(waveConfig.tm,waveConfig.bw, ... waveConfig.scs,"FDD"); % Generate waveform and get resource grid of one frame of data [~,gridSet,wInfo] = generateWaveform(tmWaveGen); grid = gridSet.ResourceGridBWP; % Get the number of symbols per slot and the number of slots per subframe waveConfig.ModulationInfo = gridSet.Info;
Compress U-Plane Data
Next, compress the generated resource grid. Depending on the compression method that you select in the O-RAN configuration, use the hORANModulationCompressionCoder.encode
or nrORANBlockCompress
function. The available compression methods are block floating point (BFP), block scaling, mu-law, and modulation compression, as defined in TS O-RAN.WG4.CUS Annex A.1, A.2, A.3, and A.5, respectively.
Before applying compression, scale the IQ samples in the resource grid to full scale, as defined in TS O-RAN.WG4.CUS section 8.1.3.1, and to the bit-width specified by the oranConfig.IQWidth
parameter.
peakPower = sqrt(max(grid.*conj(grid),[],'all')); scaleFactor = peakPower/2^(oranConfig.IQWidth-1); oranConfig.scaledGrid = round(grid/scaleFactor); % Apply compression to the scaled resource grid, if selected switch oranConfig.method case 'modulationCompression' [oranConfig.cGrid,oranConfig.cIQWidth,oranConfig.CPlaneInfo] = ... hORANModulationCompressionCoder.encode(oranConfig.scaledGrid,oranConfig.IQWidth,tmWaveGen.Config,wInfo); decompressedGrid = hORANModulationCompressionCoder.decode(oranConfig.cGrid,oranConfig.CPlaneInfo, ... oranConfig.cIQWidth,oranConfig.IQWidth); case {'BFP','blockScaling','muLaw'} [oranConfig.cGrid,oranConfig.cParam] = nrORANBlockCompress(oranConfig.scaledGrid, ... oranConfig.method,oranConfig.cIQWidth,oranConfig.IQWidth); decompressedGrid = nrORANBlockDecompress(oranConfig.cGrid,oranConfig.cParam, ... oranConfig.method,oranConfig.cIQWidth,oranConfig.IQWidth); end
Create CU-Plane Message Structures
Use the hORANProtocolBuilder.getCUMessages
function to create CU-Plane message data structures:
Ethernet header
eCPRI header
eCPRI payload (O-RAN application data)
[cMessages,uMessages] = hORANProtocolBuilder.getCUMessages(waveConfig,mPlaneConfig,...
oranConfig,eCPRIConfig,ethernetConfig);
Encode CU-Plane Messages
The hORANProtocolBuilder.encodeMessagesToFile
function encodes the CU-Plane message structures and writes the packet octets to a PCAP file. The function also returns a high-level summary of the generated O-RAN packets which is saved to a .json
file as a reference.
% Encode CU-Plane messages and write the packets to PCAP file [cufilename,summary] = hORANProtocolBuilder.encodeMessagesToFile(waveConfig,cMessages,uMessages,... mPlaneConfig,pcapFileName,pcapFormat,eCPRIConfig(2:end)); fprintf('Created %s file.',cufilename);
Created CUMessages.pcap file.
Analyze Generated CU-Plane Messages
You can check the summary of the CU-Plane packets to ensure that the time, length, protocol, eAxC ID and message info summarized within the PCAP file are correct.
struct2table(summary)
ans=2540×5 table
Time Length Protocol eAxCID Info
_________ ______ ___________ ________________ ___________________________________________________
0 60 {'C-Plane'} 0 0 0 0 "C-Plane, Type: 1, Id: 0 (all PRBs, Symbols: 0-13)"
0.00012 1496 {'U-Plane'} 0 0 0 0 "U-Plane, Id: 0 (PRB: 0-33, Symbols: 0)"
0.00012 1496 {'U-Plane'} 0 0 0 0 "U-Plane, Id: 0 (PRB: 34-67, Symbols: 0)"
0.00012 1496 {'U-Plane'} 0 0 0 0 "U-Plane, Id: 0 (PRB: 68-101, Symbols: 0)"
0.00012 1496 {'U-Plane'} 0 0 0 0 "U-Plane, Id: 0 (PRB: 102-135, Symbols: 0)"
0.00012 1496 {'U-Plane'} 0 0 0 0 "U-Plane, Id: 0 (PRB: 136-169, Symbols: 0)"
0.00012 1496 {'U-Plane'} 0 0 0 0 "U-Plane, Id: 0 (PRB: 170-203, Symbols: 0)"
0.00012 1496 {'U-Plane'} 0 0 0 0 "U-Plane, Id: 0 (PRB: 204-237, Symbols: 0)"
0.00012 1496 {'U-Plane'} 0 0 0 0 "U-Plane, Id: 0 (PRB: 238-271, Symbols: 0)"
0.00012 77 {'U-Plane'} 0 0 0 0 "U-Plane, Id: 0 (PRB: 272, Symbols: 0)"
0.0001562 1496 {'U-Plane'} 0 0 0 0 "U-Plane, Id: 0 (PRB: 0-33, Symbols: 1)"
0.0001562 1496 {'U-Plane'} 0 0 0 0 "U-Plane, Id: 0 (PRB: 34-67, Symbols: 1)"
0.0001562 1496 {'U-Plane'} 0 0 0 0 "U-Plane, Id: 0 (PRB: 68-101, Symbols: 1)"
0.0001562 1496 {'U-Plane'} 0 0 0 0 "U-Plane, Id: 0 (PRB: 102-135, Symbols: 1)"
0.0001562 1496 {'U-Plane'} 0 0 0 0 "U-Plane, Id: 0 (PRB: 136-169, Symbols: 1)"
0.0001562 1496 {'U-Plane'} 0 0 0 0 "U-Plane, Id: 0 (PRB: 170-203, Symbols: 1)"
⋮
%winopen(cufilename) % Uncomment to open the file in Wireshark on Windows
You can also open the PCAP file containing the generated CU-Plane messages in a packet analyzer and compare the PCAP file content with the displayed summary. The generated PCAP file content must match the O-RAN fronthaul protocol preferences in Wireshark. These figures show the analysis of two captured CU-Plane messages in Wireshark.
First C-Plane Message
First U-Plane Message
References
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.
TS O-RAN.WG4.CUS. "O-RAN Fronthaul Working Group - Control, User and Synchronization Plane Specification".
TS O-RAN.WG4.CONF. "O-RAN Fronthaul Working Group - Conformance Test Specification".
Wireshark : https://www.wireshark.org/. Accessed 21 July 2023.
Local Functions
function eCPRIConfig = eAxCIDConfigExpand(eCPRIConfig) % Expands the eCPRIConfig structure for all eAxC IDs % including all combinations of DUPortID, BandSectorID, CCID, and RUPortID % such that every unique eAxC ID has a corresponding structure. eAxCIDFields=fieldnames(eCPRIConfig); % Iterate through each subfield of the eAxC ID for fieldIndex=length(eAxCIDFields):-1:1 ids = eCPRIConfig.(eAxCIDFields{fieldIndex}); % Take IDs in each subfield eAxCIDSubField = num2cell(repmat(ids,length(eCPRIConfig),1)); % Create a cell for the subfield eCPRIConfig = repmat(eCPRIConfig,1,length(ids)); % Expand the array of structures [eCPRIConfig.(eAxCIDFields{fieldIndex})] = eAxCIDSubField{:}; % Assign subfield values across entire eCPRI structure end end