Amarisoft

TRX split 7.2 driver example
version 2025-06-05*
This document is based on the latest test release.
Features may not be present in your current installed software. You may check their availability in change history or in your release documentation.
If you require an up to date release, ask for it in a ticket.

Table of Contents

1 Introduction

The purpose of this document is to explain how to implement a driver for Amarisoft softwares to use ORAN split 7.2 compatible radio units. Such a driver must implement the TRX API defined in trx_driver.h and will be used by Amarisoft software as a shared library.
It is stron recommended to be familiar with the legacy TRX API as documentated here.

2 Features

3 Network configuration

The driver has been tested with Intel X710 and E810 network interfaces.
In case of jumbo frame usage, configure your NIC MTU size accordingly.

3.1 Time synchronization

As the system clock is used (CLOCK_REALTIME), the system must be synchronized with the level of accuracy required by the radio unit.

3.1.1 PTP

Here we explain how to configure system as a PTP grandmaster and synchronize system clock to it. This description is not detailed and we recommend to use Internet resources to get more details.

We assume system as at least one network interface supporting PTP.
We assume the radio unit will be synchronize to the system (or same PTP master clock).
We note this interface if-s72.

To check if-s72 PTP support:

ethtool -T if-s72

To use PTP, install linuxptp package (Name may differ depending on Linux distribution).

To configure system as PTP grandmaster, set priority1 and priority2 to 127 (or less) in the global section of your ptp configuration file (/etc/ptp4l.conf) and add a section to use if-s72.

Ex:

[global]
priority1               127
priority2               127
domainNumber            24
...

[if-s72]
network_transport       L2

To configure system as PTP client, select the proper domain number set here to 24.
Change if-s72 by the name of your network interface.

To increase the periodicty of sent ptp announce and sync messages you may set logAnnounceInterval and logSyncInterval Ex:

logAnnounceInterval     -3
logSyncInterval         -4

Then launch ptp4l. Ex:

ptp4l -m -f /etc/ptp4l.conf  -l 7

And use phc2sys to synchronize clock with interface PTP informations:

phc2sys -a -rr -n 24

Replace 24 by your domain number

You may disable NTP service to avoid conflict:

systemctl disable chronyd
systemctl stop chronyd

You may use your distribution service.
Ex with Fedora: First edit /etc/sysconfig/phc2sys to use -a -rr command line options and enable/start services:

systemctl enable ptp4l
systemctl start ptp4l
systemctl enable phc2sys
systemctl start phc2sys

To check phc2sys is working properly (Depends on your Linux distribution), type:

journalctl -f -u phc2sys

You may see such lines:

Jul 17 10:53:55 hostname phc2sys[360200]: [3608400.928] if-s72 sys offset        -9 s2 freq   +2641 delay    499
Jul 17 10:53:56 hostname phc2sys[360200]: [3608401.928] if-s72 sys offset        -8 s2 freq   +2639 delay    496
Jul 17 10:53:57 hostname phc2sys[360200]: [3608402.928] if-s72 sys offset        -7 s2 freq   +2638 delay    501

3.2 Ethernet optimization

We recommend to increase MTU of your network interface to have biggest packet as possible.

We also recommend to turn off adaptive TX feature of your network interface:

ethtool -C <ifname> adaptive-tx off

3.3 VLAN

To use VLANs, you can rely on Linux, it will be transparent.

Ex:

ip link add link if-s72 name if-s72.42 type vlan id 42
ifconfig if-s72.42 up

This will create a VLAN with id 42 on if-s72 interface. To use it just set bind_interface to if-s72.42.

4 Software configuration

4.1 Linux

To send packet on time, as there is no standard mechanism in Linux and hardware to do it, the driver will poll packets.
For that, Linux sched_rt_runtime_us kernel configuration must be set to -1 (disabled).

sysctl -w sched_rt_runtime_us=-1

Note that if you have used the Amarisoft OTS installation script and installed OTS service, this will be automatically done.

4.2 eNB

To enable s72 mode, add a s72 section in your rf_port configuration (cf config.enb/config.cfg file).
If you ave installed Amarisoft lteenb with automatic installation, check config/s72/config.cfg.

4.3 UE

To enable s72 mode, add a s72 section in your cell configuration (cf config.ue/config.cfg file).
The t1a_min_cp_dl, t1a_max_cp_dl, t1a_min_up_dl and t1a_min_up_dl must not be set.

If you ave installed Amarisoft lteue with automatic installation, check config/s72/config.cfg.

4.4 rf_driver

local_sofrf_driver.local_sof

Optional integer (default = 1). If set to 1, the driver will generate eCPRI private packets, else, those packets are expected to be received from the network.

clock_factorrf_driver.clock_factor

Optional number (default = 1). If local_sof is set, a factor will be applied to the system clock time to allow slowing down (< 1) or speeding up (> 1) the time. Usefull for debug but requires radio unit to support it.

tai_offsetrf_driver.tai_offset

Optional integer (default = computed by Linux). Set the offset in seconds between UTC time and TAI time.

alpha_offsetrf_driver.alpha_offset

Optionel integer (default = 0). System Frame Number Calculation alpha offset.

beta_offsetrf_driver.beta_offset

Optionel integer (default = 0). System Frame Number Calculation beta offset.

rf_portsrf_driver.rf_ports

Array of object. Each object represent a cell configuration with following parameters:

transportrf_driver.rf_ports.transport

Optional string (default = ethernet). Can be udp or ethernet.

max_pdu_sizerf_driver.rf_ports.max_pdu_size

Optional integer (default = 1472). Maximum eCPRI PDU size in bytes.

bind_addrrf_driver.rf_ports.bind_addr

String. If udp mode is set, defines the IP address to use to send and receive packets.

bind_interfacerf_driver.rf_ports.bind_interface

String. If ethernet mode is set, defines the network interface name to use to send and receive packets.

remote_addrrf_driver.rf_ports.remote_addr

String. If ethernet mode is set, defines the destination mac address of the TX ethernet fames.
If udp mode is set, defines the destination IP address to send UDP packet to.

t1a_min_cp_dlrf_driver.rf_ports.t1a_min_cp_dl

Optional integer. ORAN t1a_min_cp_dl management parameter in microseconds. If not set, the eCPRI packets will be sent as soon as they are generated.

t1a_max_cp_dlrf_driver.rf_ports.t1a_max_cp_dl

Optional integer. ORAN t1a_max_cp_dl management parameter in microseconds.

t1a_min_up_dlrf_driver.rf_ports.t1a_min_up_dl

Optional integer. ORAN t1a_min_up_dl management parameter in microseconds.

t1a_max_up_dlrf_driver.rf_ports.t1a_max_up_dl

Optional integer. ORAN t1a_max_up_dl management parameter in microseconds.

ta3_maxrf_driver.rf_ports.ta3_max

Optional integer. Set time margin in microseconds for incoming U-Plane packet to arrive.
In other words, IQ packets for slot N may arrive up to ta3_max after start of slot N+1

pcap_filerf_driver.rf_ports.pcap_file

Optional string. If set, must refer to pcap network capture. Instead of reading packet from network, driver will try to use the packets of the capture.
Driver will extract ethernet packet with ethertype 0xAEFE matching the pcap_mac and pcap_dir conditions.

pcap_macrf_driver.rf_ports.pcap_mac

Optional string. Must be set if pcap_file is set. Only ethernet packets with this destination mac address will be injected.

pcap_dirrf_driver.rf_ports.pcap_dir

Optional string. Can be ul or dl (default). Only ORAN packets with same direction will be injected.

5 Troubleshoot

5.1 Statistics

To check eCPRI/ORAN traffic or to troubleshoot the system, you can use the t s72 monitor command of LTEENB and LTEUE.

5.1.1 eNB

On eNB, you will get the following columns prompted:

     --User----------------------------------------------- - Slots - ----
Cell total type1 type3   err   inv  miss  late early  lost skip past  err
   1     0     0     0     0     0     1     0     0     0    0    0    0
   1     0     0     0     0     0     1     0     0     0    0    0    0

Here is the definition of each column

Cell

Internal cell ID

User

User plane statistics:

InfoDescription
totalTotal number of valid eCPRI packets
type1Number of valid ORAN section type 1
type3Number of valid ORAN section type 3
errorNumber of unwanted ORAN sections (type 3 only)
invNumber of ORAN invalid section, i.e wrong header values
missNumber of non complete OFDM symbols
lateNumber of outdated eCPRI packets
earlyNumber of eCPRI packets arriving too early
lostNumber of eCPRI packets without associated control
Slots

eCPRI Start Of Frame private packets statistics:

InfoDescription
skip Number of dsicontinuities in frame number
past Number packets with frame number in the past

5.2 Packet jitter

If you have a hard time to get packet being sent in the proper time window and you want to easily get information avout your the global system, we provide a tool inside OTS package of Amarisoft software release.
If you have used Amarisoft installation script, it may be located in /root/ots. The tool is called lte_toolbox and has a special mode to listen to a network interface and capture ORAN/eCPRI packets and estimate their time arrival towards local time.

Ex:

./lte_toolbox s72_time eth0
LTE toolbox version 2024-09-13, Copyright (C) 2012-2025 Amarisoft
Frame number: 1638
--Bitrate--  ----------U-Plane-------------  --------DL C-Plane------------  --------UL C-Plane------------
               count min   avg max    ±   Δ    count min   avg max    ±   Δ    count min   avg max    ±   Δ
  0.000gbps        0   0   0.0   0  0.0   0        0   0   0.0   0  0.0   0        0   0   0.0   0  0.0   0
  0.846gbps    20647 -95 191.0 234 43.8 329     1619 -18 187.9 241 78.0 259      101 -103 -87.9 -71  9.7  32
  0.836gbps    20400 -23 190.9 234 43.6 257     1600 -17 187.1 241 77.9 258      100 -104 -88.0 -71  9.7  33

5.3 Signal

When setting debug to true in s72 section of your software component configuration file and if s72 log level is set to debug, for each IQ samples packet received, a new log giving RMS/MAX of IQ samples in dBFS will displayed.
Ex:

13:46:46.951 [S72] -  1 type=IQ frame=126 sf=8 slot=0 symb=1 sect_id=0x007 rms=-34.3 max=-14.0

6 trx_s72.c

Here are some details about the example code.
For better understading we recommend to also look at the code to get more details and precision.

6.1 eCPRI transport

Two transport mode are supported: UDP and Ethernet

6.1.1 UDP mode

In this mode, eCPRI PDU are sent inside UDP payloads.
This mode is for testing and has low performances.

6.1.2 Ethernet mode

This mode conforms to ORAN specification by sending eCPRI data inside Ethernet payloads using the 0xaefe ethernet type.

This mode uses Linux raw socket in PACKET_MMAP mode for high performances.

The Ethernet frames may be sent as fast as possible or may be buffered to be sent on time.
When sending frames in best effort mode, no time synchronization is needed with the radio unit as the driver expect the radio unit to keep all packets, even if received several slots earlier. To send frames on time, clock synchronization must be ensured.

6.2 API Implementation

When split 7.2 mode is enabled, trx_start_func2 will be called with s72_enable set to true in TRXDriverParams2.

6.2.1 Callbacks

Compared to legacy TRX driver, the following methods are mandatory:

The trx_get_packet_config is optional.

The following methods do not apply to split 7.2 implementation:

6.2.1.1 trx_get_packet_config

This method is called after init and before start to provide following informations:

max_pdu_size

Maximum size in byte(s) of eCPRI pdu. Will bound the size of generated packets for TX. If set to 0, the default value is 1472.

max_read_packets

Tells application how maximum number of packets that can be read during trx_read_packet call. Default is 1.

rx_async_release

If set to 1, RX packet provided by driver during trx_read_packet call may not be released by application on next call. In this case, trx_read_packet must explicitely check TRX_READ_PACKET_MD_FLAG_RELEASE in metadata to be aware of released packets.
Using this option will help to reduce internal jitter/latency and help sending packets on time.

If trx_get_packet_config is not defined, default values apply.

6.2.1.2 trx_read_packet

This method is constantly called by application. It may be blocking, waiting for EPCRI packets to be available.
It is up to the driver to allocate packets and provide them using packets[n].data.
Up to count packets may be provided. Packets provided during a call to this method are considered as non used anymore on next call to this method and thus can be released.
Application is expected to get EPCRI header at packets(n].data position.
Length of packet must be set in packets[n].len.
eCPRI packets must not be fragmented.
eCPRI message concatenation is supported.
eCPRI packets should be provided as fast as possible.

A private eCPRI packet is expected at the beginning of each new uplink slot, cf build_ecpri_start_of_slot in trx_s72.c to provide application its clock.

TRXReadPacketMetadata may be filled this way:

If rx_async_release has been set during trx_get_packet_config, packets pointer will reference TRXReadPacketMetadata.release_count packets that can be released.

6.2.1.3 trx_write_packet

This method is called by application to provide generated eCPRI packets to the radio unit.
The eCPRI packets are provided as fast as possible and it is up to the driver to send them at the appropriate time. I.e if the radio unit has limited buffer, it is up to the driver to buffer packets and send them later.
The driver can read the packet information to retrieve timing informations (cf trx_s72_write_packet) to send them at a precise time.

Packets length will be limited by the max_pdu_size configuration parameter provided by trx_get_packet_config.

TRXWritePacketMetadat may be filled this way:

6.2.2 trx_get_packet

This method is optional. If set, the application will call it to get a buffer to fill eCPRI packet.
TRXPacketVec.data must be filled with a buffer of at lease size byte(s).
TRXPacketVec.user_data may be used to identify packet.
Each generated packet will be passed through trx_write_packet and can be identified by TRXPacketVec.user_data. The application won’t use the buffer anymore after the call so it is up to the driver to release the buffer.

6.2.3 Miscellaneous

7 Change history

7.1 Version 2025-06-05

7.2 Version 2025-03-14

7.3 Version 2024-09-13

7.4 Version 2024-06-14

7.5 Version 2024-03-15

8 License

trx_s72.c is copyright (C) 2012-2025 Amarisoft. Its redistribution without authorization is prohibited.

trx_s72.c is available without any express or implied warranty. In no event will Amarisoft be held liable for any damages arising from the use of this software.

For more information on licensing, please refer to license terms.