As of adding this commit, the ArmRAL LDPC encoder is very ineficient.
OAI segment encoder if far better on Arm systems.
But ArmRAL LDPC decoder on the other end is pretty good and outperforms
OAI decoder in some cases in term of SNR and processing time.
Therefore there is a point in having a LDPC coding library with ArmRAL
LDPC decoder and OAI segment encoder.
This is what this commit adds.
There has been a change of the LDPC decoder interface in ArmRAL
between past version `e9a0dfc702e3e8096e077f3ae1e404bde05407af`
and new version `armral-25.04`
This MR updates the usage of the decoder function accordingly.
Integration: `2026.w03`
* !3818 Update threadCreate
* !3845 Update physim timing thresholds in gNB-N300-Timing-Phytest-LDPC
* !3849 Make gpd config utility global
* !3812 Fix reestablishment after handover
* !3826 Define speed of light
* !3799 Fix for threadpool abort function
* !3791 fix array lenght errors, k variable wrapping threshold. Make the code smaller and more efficient
* !3718 Introduce SRS physical simulator and improvements
* !3857 Fix bug "no AMF for UE"
* !3858 remove function decode_cellGroupConfig
* !3668 Support beam index for LiteON FR2 RU that needs per symbol section in CP packets
* !3844 CI: Remove testcase ids from XML files
* !3620 update multi-RU 7.2 documentation for DAS scenario
* !3788 Fix handover documentation and configuration files for event configuration
See merge request oai/openairinterface5g!3854
Support beam index for LiteON FR2 RU that needs per symbol section in CP packets
This branch supports beam index for LiteOn FR2 RU and others. It adds
the support of beam index for LiteOn RU that uses per-symbol CP packet
and is a sequel of MR !3605 (merged) that supports beam index for RU
that uses per-slot CP packets.
A. To support LiteOn FR2 RU, the following are needed.
a. Per symbol beamforming. Need separate section for each symbol on CP packet.
b. Handle these two bugs:
- section ID on UP packet is set wrongly to 13 for all sections
- prach eAxC offset starts from 0 instead of from last antenna port
number used by other channels.
B. Implementation
a. set fh_config->RunSlotPrbMapBySymbolEnable based on the setting in the configuration file
- if disable, the existing per-slot scheme is run on xran.
- if enable, RunSlotPrbMapBySymbolEnable mode is on in xran so that xran
will generate PrbElm per symbol (aka total of 14)and perform
per-symbol processing on the corresponding PrbElm.
b. set fh_config->LiteOnIgnoreUPSectionIdEnable based on the setting in
the configuration file if enable, handle 2 "features" of Liteon:
- To handle the section_id = 13 issue on Liteon where section ID is set
wrongly to 13 for all sections
- To handle the prach eAxC offset issue on Liteon where it starts from 0
instead of from the end of last antenna port number
c. if fh_config->RunSlotPrbMapBySymbolEnable, OAI FHI
- invoke xran_fh_rx_read_slot_BySymbol() instead of xran_fh_rx_read_slot()
- invoke xran_fh_tx_send_slot_BySymbol() instead of xran_fh_tx_send_slot()
C. Testing
a. Command to test benetel RU
sudo LD_LIBRARY_PATH=.:$DPDK_INST/lib/x86_64-linux-gnu/ ./nr-softmodem -O /etc/ran_development/CONFs/gnb.sa.band77.273prb.fhi72.4x4-benetel550_c0.conf --thread-pool 21,22,23,24,25,26,27,28
Results:
iperf UDP uplink
[ 5] 0.00-10.22 sec 87.3 MBytes 71.6 Mbits/sec 0.100 ms 370/63081 (0.59%) receiver
iperf UDP downlink
[ 5] 0.00-10.00 sec 796 MBytes 668 Mbits/sec 0.017 ms 1824/586404 (0.31%) receiver
b. Command to test LiteOn FR2 RU
sudo LD_LIBRARY_PATH=.:$DPDK_INST/lib/x86_64-linux-gnu/ ./nr-softmodem -O /etc/ran_development/CONFs/gnb.sa.band78.66prb.fhi72.2x2-liteon-F-Release.conf--thread-pool 21,22,23,24,25,26,27,28
Result:
iperf UDP uplink
[ 5] 0.00-10.20 sec 89.9 MBytes 73.9 Mbits/sec 0.156 ms 212/64848 (0.33%) receiver
iperf UDP downlink
[ 5] 0.00-10.00 sec 361 MBytes 303 Mbits/sec 0.077 ms 277662/542891 (51%) receiver
D. Difference between LiteOn FR2 E release configuration file and that for F release is
diff gnb.sa.band78.66prb.fhi72.2x2-liteon-KB.conf gnb.sa.band78.66prb.fhi72.2x2-liteon-F-Release.conf 39d38
< beam_weights = [1, 1];
225a225
> beam_weights = [1];
312c312,313
< mtu = 1500; # check if xran uses this properly
---
> #mtu = 1500; # check if xran uses this properly
> mtu = 9000; # check if xran uses this properly
313a315,316
> RunSlotPrbMapBySymbol = 1;
> LiteOnIgnoreUPSectionId = 1;
Add the F patch that work on both Benetel and LiteOn RU. support
fh_config parameters RunSlotPrbMapBySymbol and LiteOnIgnoreUPSectionId.
Change version number.
Fix bug "no AMF for UE"
It might happen that the RRC does not know the AMF UE NGAP ID, yet. Even
in that case, we should forward the release request to the NGAP module,
which can either forward a message to the AMF, or reply back to release
the UE. This avoids an error where the CU claims there was no AMF, when
there actually is.
One possible problematic behavior is if a UE disconnects before the gNB
receives an NGAP Initial Context Setup. In this case, the AMF UE NGAP ID
was not forwarded to the RRC (although it was known at NGAP), thus
blocking the release of the UE.
This is the main fix, the rest are minor fixes:
- store AMF UE NGAP ID as early as possible
- warn in MAC if UE unknown for UE context release command
- show TEIDs with correct endianness in GTP
- avoid NG Setup Failure+Setup log.
Introduce SRS physical simulator and improvements
This MR consists of two parts:
- Introduces SRS physical simulator to test different configurations of
SRS
- Improvements in the SRS channel estimation (Addressing the comments
from old, unfinished MR !2875)
- rewrite nr_srs_channel_estimation() to loop over rx antennas and
antenna ports to be able to parallelize
- Improvements in timing_advance_offset and timing_advance_offset_nsec
computation
- Introduce SRS multi-symbol channel estimation
- The channel impulse response is estimated from the averaged
channel frequency response over multiple symbols
- The channel frequency estimates are left as they are to be able to
estimate doppler in the future
- Simplify SRS channel estimation to handle memory alignment in the
case of different SRS configurations (eg: comboffset)
To use multiple symbols when running gNB, the following parameters needs
to be edited in the function get_srs_resource()
- srs_res->resourceMapping.startPosition with a range from {0,1,..,5}
corresponds to the start symbol {13, 12, .. 8} with in a slot
- srs_res->resourceMapping.nrofSymbols indicates the number of symbols
{n1, n2, and n4}
Make sure the that start symbol + number of symbols is < 14
The timing results for SRS in develop and srs_phy_simulator are as follows:
Command used: sudo ./nr_ulsim -n1000 -s50 -S50 -R273 -W2 -y2 -z2 -E 1 -P
develop
|__ RX SRS time 124.94 us (1000 trials) (124.94 total [ms])
|__ Generate SRS sequence time 0.05 us (1000 trials) ( 0.05 total [ms])
|__ Get SRS signal time 19.41 us (1000 trials) ( 19.41 total [ms])
|__ SRS channel estimation time 89.11 us (1000 trials) ( 89.11 total [ms])
|__ SRS timing advance estimation time 13.10 us (1000 trials) ( 13.10 total [ms])
|__ SRS report TLV build time 2.80 us (1000 trials) ( 2.80 total [ms])
|__ SRS beam report build time 0.00 us ( 0 trials)
|__ SRS IQ matrix build time 2.73 us (1000 trials)
srs_phy_simulator
|__ RX SRS time 211.93 us (1000 trials) (211.93 total [ms])
|__ Generate SRS sequence time 0.04 us (1000 trials) ( 0.04 total [ms])
|__ Get SRS signal time 19.55 us (1000 trials) ( 19.55 total [ms])
|__ SRS channel estimation time 152.05 us (1000 trials) (152.05 total [ms])
|__ SRS timing advance estimation time 36.67 us (1000 trials) ( 36.67 total [ms])
|__ SRS report TLV build time 2.96 us (1000 trials) ( 2.96 total [ms])
|__ SRS beam report build time 0.00 us ( 0 trials)
|__ SRS IQ matrix build time 2.88 us (1000 trials)
Note that in srs_phy_simulator, to compute timing offset ns, an
oversampling factor of 2 is performed. Also, for peak detection, we
average the channel estimates for every port.
fix array lenght errors, k variable wrapping threshold. Make the code smaller and more efficient
generate_nr_prach() has several errors coming from replace int16_t by
c16_t, and also older error in k wrapping at the end of the symbol
the code is also ridiculously complex, wasting memory and cpu time in
intermediate useless buffers and headache usage of memmove()
On NGSetupFailure, before moving, we might have
[NGAP] Received NG setup failure for AMF... please check your parameters
[NGAP] Received NGSetupResponse from AMF
In the Initial Context Setup message, the NGAP forwards the AMF UE ID,
but not in the DL NAS Message, although 38.413 says, in $8.3.1.2 either
> The NG-RAN node shall use the AMF UE NGAP ID IE and RAN UE NGAP ID IE
> received in the INITIAL CONTEXT SETUP REQUEST message as identification
> of the logical connection
or in $8.6.2.2
> The NG-RAN node shall use the AMF UE NGAP ID IE and RAN UE NGAP ID IE
> received in the DOWNLINK NAS TRANSPORT message as identification of the
> logical connection
So forward in both cases for harmonization.
It might happen that the RRC does not know the AMF UE NGAP ID, yet. Even
in that case, we should forward the release request to the NGAP module,
which can either forward a message to the AMF, or reply back to release
the UE.
Reported-By: Jegor Zelenjak <jzelenjak@proton.me>
Make gpd config utility global
Make gpd a global utility macro for reading config/command line
parameters. Add a corresponding function with full name for clarity,
keep the short name for the macro for backward compatibility and ease of
use.
The main benefit of gpd/config_get_paramdef_from_name macro/function is
that it does not require maintaining a separate parameter index list.
Update physim timing thresholds in gNB-N300-Timing-Phytest-LDPC
The lower bound for the tests are too tight and any slight improvement
in the timing can result in a test failure. For example, these tests
were failing due to the improvements from the MR !3718
The lower bound for the tests are too tight and any slight improvement in the timing can result in a test failure.
For example, these tests were failing due to the improvements from the MR 3718
- We use the same function at gNB and UE.
- We always use nb_antennas_tx to check the max possible number of ports (which is wrong).
- At gNB, we should use nb_antennas_rx and at the UE, we should use nb_antennas_tx.
The memory alignment is required to use c16multaddVectRealComplex
in SRS channel interpolation. With a change in SRS comb_offset, the
existing algorithm was giving segmentation fault.
The existing srs channel estimation required memory alignment at two
stages. 1. When k = 0 (the first srs subcarrier), 2. When subcarrier <
K_TC (wrapped around after ofdm_symbol_size). Thus two memory alignments
are required leading to complications.
The srs channel estimation is now simplified to do it linearly instead of
wrapping around. This simplified the memory alignment required only when
k = 0.
- Introduce signal energy and noise variance functions
- Combine rotation and OFDM modulation RX as a function
- Harmonize the use of number of antennas across the code
- Rename nr_ue_pusch_common_procedures() to nr_tx_rotation_and_ofdm_mod() to decribe the functionality better
Integration: `2026.w02`
* !3828 L2 UE files code cleanup for static functions
* !3839 Couple rfsim fixes
* !3835 Correctly include cblas include directories for RHEL
* !3840 Fix missing return statements in SIB1 TDA validation
* !3836 move NTN UE L1 functions to a new file
* !3793 CI: Remove redundant Jenkinsfiles
* !3770 RRC UE: Implement proper NH chain synchronization for RRC Reestablishment
* !3843 fix(documentation): issue 1042
* !3842 Remove unused cmake_targets files
* !3832 Remove global iq_txshift and iq_rxrescale
* !3847 Minor CI and nr_ulsim reporting adjustments
* !3838 NR NGAP (N2HO) : Fix Time UE Stayed in Cell IE type and calculation
* !3677 Support prach with start symbol of PRACH not at symbol 0
Closes#1042 and #857
See merge request oai/openairinterface5g!3841
Make gpd a global utility macro for reading config/command line parameters.
Add a corresponding function with full name for clarity, keep the short name
for the macro for backward compatibility and ease of use.
The main benefit of gpd/config_get_paramdef_from_name macro/function is that
it does not require maintaining a separate parameter index list.
Support prach with start symbol of PRACH not at symbol 0
The following PRACH indice have been tested.
index / format (nf mod x = y) / Subframe/ start_symbol /no_of_slot / occ / duration
152 B4 2 1 4,9 0 2 1 12
151 B4 2 1 4,9 2 1 1 12
157 B4 1 0 4 0 1 1 12
159 B4 1 0 9 0 1 1 12
NR NGAP (N2HO) : Fix Time UE Stayed in Cell IE type and calculation
According to 3GPP TS 38.413, the 'Time UE Stayed in Cell' IE is an
integer ranging from 0 to 4095. This patch updates the data structure
to reflect the correct bit width and implements the dynamic calculation
based on the UE's residence time.
- Change time_in_cell from long to uint16_t in ngap_messages_types.h.
- Replace dummy value with real-time calculation in rrc_gNB_NGAP.c.
- Implement a ceiling of 4095 to comply with the 12-bit protocol limit.
Ref: 3GPP TS 38.413 Section 9.3.1.97
Refactor key derivation logic to properly handle Next Hop (NH) chain
synchronization according to 3GPP TS 33.501 specifications for both RRC
Reestablishment and Master Key Update procedures.
Changes in rrc_gNB.c:
- Clarify key derivation in rrc_gNB_generate_RRCReestablishment by explicitly
selecting base key (NH or KgNB) based on nh_ncc value
- Add comment explaining vertical vs horizontal derivation logic
Changes in rrc_UE.c:
Refactored the NH chain synchronization and key derivation code to match
TS 33.501 terminology:
- nr_sync_nh_chain(): Common helper to synchronize NH parameter chain per
TS 33.501 Annex A.10, supporting both Master Key Update and RRC Reestablishment
procedures
- nr_derive_kgnb_horizontal(): Derive KNG-RAN* from current KgNB when NCC values
match (horizontal derivation per TS 33.501 A.11/A.12)
- nr_derive_kgnb_vertical(): Derive KNG-RAN* from synchronized NH after NH chain
sync (vertical derivation per TS 33.501 A.11/A.12)
- nr_update_kgnb_from_ncc(): Unified function implementing TS 33.501 6.9.2.3.4
logic for updating KgNB based on received nextHopChainingCount
- Refactor as_security_key_update(): Use new nr_update_kgnb_from_ncc() helper
function for cleaner, more maintainable code
- Fix nr_rrc_ue_process_rrcReestablishment(): Properly handle received
nextHopChainingCount and update KgNB using unified helper function
- Replaced the previous nr_rrc_nh_update() helper with these functions to
improve clarity and alignment with the specification.
- Add debug logging for key derivation process
Key NAS deriver utils:
- update derive_kgnb documentation and protect input keys with const attribute
Closes#857
These files are not used anywhere. The only remaining cmake find files
are:
- findarmral and findxran: used by FHI7.2 driver
- findsctp: used by top-level CMakeLists.txt
- findgnutls: NOT actually used but GnuTLS is a dependency of websrv, so
I leave it for the moment (should be removed if the webserver is
removed)
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
There is no HSS/MME in this repository, which is the majority of this
file. Remove it, since it is outdated.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Setup routes was added by the author of FlexRAN. The UEs always set up
routes automatically, and this file is therefore not needed.
See-also: 287c182925 ("Remove FlexRAN")
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
According to 3GPP TS 38.413, the 'Time UE Stayed in Cell' IE is an
integer ranging from 0 to 4095. This patch updates the data structure
to reflect the correct bit width and implements the dynamic calculation
based on the UE's residence time.
- Change time_in_cell from long to uint16_t in ngap_messages_types.h.
- Replace dummy value with real-time calculation in rrc_gNB_NGAP.c.
- Implement a ceiling of 4095 to comply with the 12-bit protocol limit.
Ref: 3GPP TS 38.413 Section 9.3.1.97
RHEL uses a dedicated cblas include directory. Correctly include this
for the one target PHY_UE that relies on this.
Co-authored-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Per TS 33.501 6.9.2.3.4 and Fig 6.9.2.1.1-1, when sending
RRCReestablishment with nextHopChainingCount, the gNB is staying at
the same NCC level (not advancing). Therefore, horizontal derivation
from the currently active KgNB must be used, not vertical derivation
from NH.
Vertical derivation (from NH) is only used when advancing to a new
NCC level, which happens during handover or masterKeyUpdate procedures.
The previous implementation incorrectly used vertical derivation from
NH whenever nh_ncc > 0, which caused key mismatch between gNB and UE
during reestablishment after handover, leading to integrity check
failures.
This fix ensures both gNB and UE use horizontal derivation when
nextHopChainingCount matches the current NCC level, aligning with the
specification's "virtual NH at NCC=0" model where:
- Horizontal derivation = derive KNG-RAN* from currently active KgNB
- Vertical derivation = derive KNG-RAN* from NH (only when advancing NCC)
During N2 handover, the UE receives reconfigurationWithSync which correctly
sets the target cell frequency in mac->phy_config.config_req.carrier_config
via config_common_ue() call.
However, when SIB1 is decoded after reconfiguration,
nr_rrc_mac_config_req_sib1() calls config_common_ue_sa() which unconditionally
overwrites the frequency with the command-line parameter (downlink_frequency),
which corresponds to the source cell frequency.
This causes a critical issue during RRC re-establishment:
- The UE uses the wrong frequency (source cell) for key derivation (kgnb*)
- The gNB uses the correct frequency (target cell) for key derivation
- This mismatch results in different kgnb* keys on UE and gNB
- Integrity check fails: "Integrity of RRCReestablishment failed, going to IDLE"
Root cause:
config_common_ue_sa() is used for SIB1 processing (initial cell selection) and
uses ServingCellConfigCommonSIB which doesn't contain absoluteFrequencyPointA.
It must derive frequency from command-line parameters. However, after handover,
the frequency has already been correctly set by config_common_ue() (used for
reconfigurationWithSync) which uses ServingCellConfigCommon with absolute
frequency information.
Solution:
Modify config_common_ue_sa() to preserve the existing frequency if it's already
initialized (non-zero). Only set frequency from command-line parameters during
initial cell selection when dl_frequency is 0. This ensures:
- Initial cell selection: frequency derived from command-line parameter, just once
- After handover: frequency preserved from reconfigurationWithSync
- MAC maintains its own frequency state independently
The fix applies to both DL and UL frequencies to maintain consistency.
There is probably room for more refactoring to the resync flow, since
the functionalities in config_common_ue and config_common_ue_sa are
partially overlapping and upon reconfigurationWithSync some other
configurations might be applied twice.
These logs are very helpful to identify cell configuration
changes in MAC/PHY, for monitoring purposes, and to rapidly
signal integrity failures during re-establishment.
The RNTI from the target context was not updated after HO acknowledge
this led to a failure in the first re-establishment after HO.
This commit is introducing the function nr_rrc_apply_target_context
in nr_rrc_n2_ho_acknowledge() and also updates the cell ID for
consistency.
Refactor handover target context application logic into a reusable
function nr_rrc_apply_target_context() that updates both F1AP
associations (secondary UE and DU association) and RNTI from the
target handover context.
And apply to rrc_CU_process_ue_context_modification_response()
Integration: `2025.w52`
* !3809 [FHI72] Fix the PRACH FFT size
* !3829 Hotfix for handling the case where the number of physical antennas is larger than the number of logical antennas
* !3663 NR UE: calculate DL and UL Doppler based on SIB19 information in NTN mode, fixing LEO reestablishment
* !3819 CORESET start multiple of 6 fix
* !3641 automatic selection of SIB1 TDA
* !3804 gNB: apply new NR_CellGroupConfig when RRCReconfiguration is acknowledged
* !3833 Add missing CMakeLists entries for test_nr_frame_params
* !3656 Rfsimulator beam reception/transmission
Closes#1037 and #1002
See merge request oai/openairinterface5g!3830
Rfsimulator beam reception/transmission
A simplified beam switching simulation for rfsimulator. This works
mainly in 1 gNB - N UEs scenarios. This is not a real beamformer with
antenna, channel and propagation model. The way it works is that the
peers inform each other about the beams they transmit in, and on
reception before channel modelling, the beam data is combined based on
preconfigured rx_beam/tx_beam gain matrix.
Usage:
- Add --rfsimulator.enable_beams to enable beam simulation
- Add --rfsimulator.beam_gains .
Example list: 0,-5,-10
Resulting matrix:
[[0, -5, -10] [-5, 0, -5]] [-10, -5, 0]]
- Add --telnetsrv if you want to control the beams manually. The command
in telnet is "rfsimu setbeam <beam_map>", where beam_map is a uint64_t
controling the reception beam and transmission beam. If the
application is switching the beams automatically the beams will be
overwritten as soon as the application chooses to switch beams.
Supports up to 64 concurrent TX and RX beams.
gNB: apply new NR_CellGroupConfig when RRCReconfiguration is acknowledged
Currently part of the NR_CellGroupConfig is already applied when the
RRCReconfiguration message is created. This is not correct and this MR
fixes this by applying it when the RRCReconfiguration message is
acknowledged.
With this fixed, we also move disabling the feedback (in case
disable_harq is used) from the RRCSetup message to the
RRCReconfiguration message.
Closes: #1002
Add CLI parameter rfsimulator.beam_ids which uses a list of beam ids instead of a
beam map. The beam map API is still present and can be used interchangably.
Add telnet command setbeamids which has similar semantics
Allow arbitrary order of beam ids in set_beams2 function. This
allows the application to select any arbitrary order of beam ids.
The underlying transport mechanism still uses beam_map so the beam_ids
are ordered before sending.
Also replaced tx_beam_map/rx_beam_map into beam_map.
Also fixed an issue where --rfsimulator.enable_beams required an argument.
- Added first beam optimization to combine_tx_buffers.
- Added first beam & first peer optimization to rfsimulator_read_internal
This results in significant speed up for the first rx beam, first tx
beam and first peer which is the base case with beam simulation disabled.
In rfsim, received packets are dynamically allocated and freed when no longer
needed, which is dependent on the channel model, packet timestamp and packet
size (number of samples carried).
This commit fixes the packet age check for channels with nonzero channel offset
(most notalby NTN channels).
Also present:
- extract the NTN satellite position update code to a separate function and
call it once per trx_read call instead of once per rx beam.
Add a set of macros with designated initializers to simplify using
paramdef_t arrays in C++ source code. Fix clang error with
RFSIMULATOR_PARAMS_DESC using mixed designated and non-designated
initializers.
- Received packets are dynamically allocated and kept in a
queue for as long as they are needed.
- The layout of the packets was changed from interleaved antennas
to non-interleaved antennas.
- Generate a contiguous buffer from saved packets as needed.
There is extra work caused by this change due to recv() call no
longer saving data directly into the circular buffer, however further
processing is easier due to contiguous nature of the tx antenna buffers
prepared. The impact on performance was not measured.
A simplified beam switching simulation for rfsimulator. This works
mainly in 1 gNB - N UEs scenarios. This is not a real beamformer with
antenna, channel and propagation model. The way it works is that the
peers inform each other about the beams they transmit in, and on
reception before channel modelling, the beam data is combined based on
preconfigured rx_beam/tx_beam gain matrix.
Usage:
- Add --rfsimulator.enable_beams to enable beam simulation
- Add --rfsimulator.beam_gains <comma separated Toepliz form matrix of gains in dB>.
Example list: 0,-5,-10
Resulting matrix:
[[0, -5, -10]
[-5, 0, -5]]
[-10, -5, 0]]
- Add --telnetsrv if you want to control the beams manually. The command in telnet
is "rfsimu setbeam <beam_map>", where beam_map is a uint64_t controling the
reception beam and transmission beam. If the application is switching the beams
automatically the beams will be overwritten as soon as the application chooses to
switch beams.
Co-authored-by: Laurent Thomas <laurent.thomas@open-cells.com>
CORESET start multiple of 6 fix
According to the standard any CORESET (except CSET0) would always start
from the first common resource block index which is multiple of 6 in the
BWP. This was not taken into account in the code. The BWP switch CI test
is modified to test a BWP start not multiple of 6.
An exception is the case where rb-Offset-r16 parameter is set, but can't
be used at gNB for FAPI compatibility.
Closes: #1037
[FHI72] Fix the PRACH FFT size
ru_config->fftSize is used for the C-plane Section Type 3 which is
dedicated for PRACH and mixed numerology. Previously, we assumed that
PRACH FFT size is equivalent to PxSCH FFT size, but should be based on
the PRACH format.
Tests with the following RUs:
- [x] Benetel v1.2.2 & v1.4.1
- [x] VVDN Gen 3
- [x] Liteon 02.00.10
- [x] Metanoia v2.2.8 (Jura)
Integration `2025.w51`
* !3816 Add two missing include guards
* !3715 Pass beam ID as per FAPI v222.10
* !3777 UE NTN : Fix in case SIB19 periodicity is greater than 2 secs
* !3813 Reset outdated PUCCHs to avoid Assertion caused by non-processed and active PUCCHs
* !3815 Remove phy_extern_nr_ue file
* !3824 CI: adjust UE attach timeout handling
* !3735 vrtsim: Optimize channel modelling
See merge request oai/openairinterface5g!3817
Per TS 33.501 6.9.2.3.4 and Fig 6.9.2.1.1-1, when sending
RRCReestablishment with nextHopChainingCount, the gNB is staying at
the same NCC level (not advancing). Therefore, horizontal derivation
from the currently active KgNB must be used, not vertical derivation
from NH.
Vertical derivation (from NH) is only used when advancing to a new
NCC level, which happens during handover or masterKeyUpdate procedures.
The previous implementation incorrectly used vertical derivation from
NH whenever nh_ncc > 0, which caused key mismatch between gNB and UE
during reestablishment after handover, leading to integrity check
failures.
This fix ensures both gNB and UE use horizontal derivation when
nextHopChainingCount matches the current NCC level, aligning with the
specification's "virtual NH at NCC=0" model where:
- Horizontal derivation = derive KNG-RAN* from currently active KgNB
- Vertical derivation = derive KNG-RAN* from NH (only when advancing NCC)
Refactor key derivation logic to properly handle Next Hop (NH) chain
synchronization according to 3GPP TS 33.501 specifications for both
RRC Reestablishment and Master Key Update procedures.
Changes in rrc_gNB.c:
- Clarify key derivation in rrc_gNB_generate_RRCReestablishment by
explicitly selecting base key (NH or KgNB) based on nh_ncc value
- Add comment explaining vertical vs horizontal derivation logic
Changes in rrc_UE.c:
- Add nr_sync_nh_chain(): Common helper to synchronize NH parameter
chain per TS 33.501 Annex A.10, supporting both Master Key Update
and RRC Reestablishment procedures
- Add nr_derive_kgnb_horizontal(): Derive KNG-RAN* from current KgNB
when NCC values match (horizontal derivation per TS 33.501 A.11/A.12)
- Add nr_derive_kgnb_vertical(): Derive KNG-RAN* from synchronized NH
after NH chain sync (vertical derivation per TS 33.501 A.11/A.12)
- Add nr_update_kgnb_from_ncc(): Unified function implementing TS 33.501
6.9.2.3.4 logic for updating KgNB based on received nextHopChainingCount
- Refactor as_security_key_update(): Use new nr_update_kgnb_from_ncc()
helper function for cleaner, more maintainable code
- Fix nr_rrc_ue_process_rrcReestablishment(): Properly handle received
nextHopChainingCount and update KgNB using unified helper function
- Add debug logging for key derivation process
Key NAS deriver utils:
- update derive_kgnb documentation and protect input keys with const attribute
Make sure to apply Doppler and TA not directly when receiving the target cell ntn_config,
but apply Doppler just before the initial sync, and the TA after the initial sync when
we have tha actuel cell frame and slot numbers.
We need the ntn_config when reconfiguring the PHY layer for a new initial sync,
e.g. for calculating the DL Doppler frequency.
As a dedicated scheduled_response dl_config PDU it reaches the PHY layer too late,
as part of the phy_config.config_req it reaches the PHY layer in time with the
other configuration values.
vrtsim: Optimize channel modelling
Optimization pass for channel modelling on transmission in vrtsim. This
comes from a requirement of O-RU to perform channel modelling with minimum
latency. The latency measured in O-RU 4TX 2RX on the UE is lowered from
~400 uS to ~100uS.
- Reduced MAX_CHANNEL_LENGTH to 200 and introduced SAVED_SAMPLES_LEN
- Refactored channel modelling actor allocation to parallelize work better
- Improved batching and task creation for channel modelling
- Replaced static global saved_samples with local static buffer in vrtsim_write_with_chanmod
Create a new CI pipeline for testing with vrtsim on Gracehopper:
https://jenkins-oai.eurecom.fr/job/RAN-VRT-Sim-Test-5G/
CI: adjust UE attach timeout handling
This modification addresses an issue in the RFSim-5G 2x2 test where the UE
often fails to attach within the initial 20s window. The timeout may cause
the UE to restart, which leads to two UEs appearing in the gNB log. By
increasing the initial timeout to 40s, we avoid unnecessary restarts.
- Set default attach_timeout to 40s
- Increase timeout only after failed attach attempts
This modification addresses an issue in the RFSim-5G 2x2 test where the UE
often fails to attach within the initial 20s window. The timeout may cause
the UE to restart, which leads to two UEs appearing in the gNB log. By
increasing the initial timeout to 40s, we avoid unnecessary restarts.
This function is to be called by the application to switch beams
on reception and transmission. When receiving new samples using
trx_read/trx_write the application is expected to be able to
determine which beam the samples belong to.
Reset outdated PUCCHs to avoid Assertion caused by non-processed and
active PUCCHs
When there is real-time issues in L1 it may happen that the scheduler
misses/skips some slots, thus, L2 not processing and not freeing some
structures like PUCCH. This commit avoids the Assertion by resetting
any Active outdated PUCCH
UE NTN : Fix in case SIB19 periodicity is greater than 2 secs
This was observed when testing OAI NTN UE against a third party gNB (UXM).
LEO SIB19 periodicity of > 2000 ms was used, in which case T430 timer expires
before SIB19 is re-read. This fix handles the case where SIB19 periodicity >
2secs, such that SIB19 is re-read in time and T430 timer does not expire.
Pass beam ID as per FAPI v222.10
This MR
1. Sets MSB of beam ID when passing beam ID to 7.2 radio
2. Modifies phytest scheduler to allocate SSBs on different beams
3. Introduce new MAC config parameter for beam mode to specify HiPHY or LoPHY
beamforming
In perfrom_channel_modelling, do convolution in batches which allows
vrtsim to write the channel samples as they are being produced instead
of waiting for the last sample in the slot to be ready.
Limit sample history to 256 samples and copy it into each channel modelling
task instead of relying on globally available buffer. This simplifies the code
and addressing into the saved samples buffer as well as enabling further
optimizations without sacrificing thread safety.
We assumed that PRACH FFT size is equivalent to PxSCH FFT size.
However, the parameter ru_config->fftSize is used for the C-plane Section Type 3
which is dedicated for PRACH and mixed numerology.
Based on the PRACH format, short or long, the PRACH values 256 or 1024
shall be filled.
Co-authored-by: knopp <raymond.knopp@eurecom.fr>
When doing analogue beamforming, the beam ID for a pre-defined beam
table is passed directly to RU and there is no need to store the beam
table in PHY.
When there is real-time issues in L1 it may happen that the scheduler misses/skips some slots, thus, L2 not processing and not freeing some structures like PUCCH.
This commit avoids the Assertion by resetting any Active outdated PUCCH
Integration `2025.w50`
* !3638 NR UE: calculate TA based on SIB19 information in NTN mode, if autonomous TA is not enabled
* !3624 NR UE: improve handling of Handover procedures
* !3807 doc: Update doc for IF setup
* !3741 Update documenation for handover
* !3798 Fix for computation of PRACH occasions and association period
* !3808 Add symbol timing functions for NR_DL_FRAME_PARMS + optimization for slot timing counterparts
Closes#981
See merge request oai/openairinterface5g!3806
Add symbol timing functions for NR_DL_FRAME_PARMS + optimization for slot timing
counterparts
Add two new functions for calculation symbol timestamp and symbol duration for
NR_DL_FRAME_PARMS. Also includes an optimization focused on removing
inefficiencies related slot-related counterparts.
1. Removed function pointers for functions get_samples_per_slot(),
get_samples_slot_timestamp() and get_slot_from_timestamp() as it does
not offer any advantage. The functions are now called directly from
everywhere.
2. Optimized these functions by removing loops where ever possible.
Update documenation for handover
Update documentation for handover to include the changes that were made after
upgrading the CI handover setup (attenuator, USRPs synchronization)
NR UE: calculate TA based on SIB19 information in NTN mode, if autonomous TA is not enabled
To achieve the goal, the hyper frame number (HFN) is introduced at the NR UE
PHY, MAC and RRC layers.
Besides this, we also implemented an orbit propagation to improve the accuracy
of N_UE_TA_adj, and a fix to keep the N_TA from RAR and MAC CE.
Fixes#981
Add two new functions for calculation symbol timestamp and symbol
duration for NR_DL_FRAME_PARMS. These functions are not using
the existing indirection mechanism via function pointers as this
prevents the compiler from properly optimizing the code.
Fixed an issue where if threadpool was aborted when some threads were in a running
state the threadpool would never exit. This was due to the fact that the thread
terminate task (func == NULL && args == NULL) could have been pushed to queues which
were inactive. This change adds a uint64_t mask of threads that have already exited
so whenever the terminate task is sent to another queue, it is ensured that the queue
used will wake up at least one tpool worker.
Also added pushTpool_mask which allows to specify a subset of threads to push the task
to but its only used internally.
Also added in this commit: A way to allocate thread-safe storage for thread pool
workers via get_tpool_worker_index. This index is unique to the thread pool worker
within one threadpool and can be used to access arrays in a thread-safe manner.
An example of such use was added in a testcase that was added which compares delay
between actors and threadpool workers.
Fix FAPI WLS timing, UL counter, doc
- Fix FAPI WLS timing
- Fix periodical PNF UL throughput logs
- Update documentation to better explain how to run WLS with radio (USRP
B210)
Fixes for BWP switching
This MR fixes some issues when performing BWP switching via
reconfiguration. It also adds a CI test for BWP switching. # Please
enter a commit message to explain why this merge is necessary,
In all cases (CFRA in SA for HO, or CFRA in NSA/do-ra for access), the
UE has the full configuration already. We can therefore directly switch
to a dedicated search space, as it is already known to the UE.
... so if we want to have 1 BWP configured at any given time we need to
reconfigure BWP 1 every time. This means that since the gNB has more
than 1 BWPs (for use for different UEs), that there is a "gNB BWP ID"
(as used by the gNB), which can be any BWP ID X, and one "UE BWP ID",
which is always 1. This commit implements this distinction.
Return from triggering reconfiguration with BWP switch if BWP is the
same as before the switch, and add check to verify if BWP triggered by
switch command exists
Current FAPI slot_ahead value for WLS is too low for UL, as we see these
errors:
[NR_MAC] Unexpected ULSCH HARQ PID 14 (have 3) for RNTI 0xa68e
[NR_MAC] UE a68e expected HARQ pid 3 feedback at 586. 7, but is at 587.17 instead (HARQ feedback is in the past)
Similarly to nFAPI, scale it by mu (for mu=1 => slot_ahead=2) to give
additional time, which removes these warnings at the VNF.
E2SM-RC RRC message forwarding (e.g., to signal a new UE, measurement
reports, ...) was broken since commit d6c29b2d2c, as we accidentally
removed the E2_AGENT compilation definition from RRC layer.
Although this commit fixes the mentioned issue, it also causes undefined
references to functions defined in ran_func_rc.c file. Therefore, we
add a hack that provides the definition, and abort if we ever hit these
functions, which in theory should not happen.
Future cleanup should avoid linking in RRC and other layers into
simulators.
Fixes: d6c29b2d2c ("Fix E2_AGENT linking w.r.t. simulators ")
Testing has revealed that if PDCP drops some packets, the scheduler
falls behind with handling Slot.indication. It could be that we don't
have enough cores, which was reduced previously (from total 8 -> 2).
Reincrease to four cores to have a bit more headroom.
See-also: a18a4888ec ("Change number of cores used for OAI gNB from 8 to 2")
The PDUSessionResourceReleaseResponse message was missing the mandatory
pDUSessionResourceReleaseResponseTransfer IE in each released PDU session item. This caused Open5GS to send an error indication.
Changes:
- Add encode_ngap_pdusession_release_response_transfer() function to
properly encode the transfer structure (empty since Secondary RAT Usage
Information is optional and not used, per 9.3.4.21)
- Always include the mandatory PDUSessionResourceReleasedListRelRes IE
- Always encode the pDUSessionResourceReleaseResponseTransfer for each
PDU session item
- Fix Release Command handler to decode and log Cause from command transfer:
instead of incorrectly copying command data to response: the 2 transfer
IEs in the Command and the Response messages are different and should
not be mixed
- Split Command/Response struct type definitions
- Add missing includes
1) Remove UE Context Release Response code: there is no
such thing in the specs, it is either UE Context Release Request
(NG-RAN node initiated) or UE Context Release (AMF initiated)
(3GPP TS 38.413). The former message has only the request, no
response is defined by the specs. The code in the stack had no
purpose at all and was removed.
2) The UE Context Release Request message only contains a PDU
Session Resource List (optional) of PDU Session IDs, therefore
the use of pdusession_release_t was wrong and was refactored
Add yq to edit yaml files and add yaml-dev library in containers missing it
- nr-cu-up and some containers were missing the yaml-config support
libraries
- yq tool is required to manipulate YAML files from within the container
for Helm charts
Consistently use OAI_RNGSEED env variable for RNG
use OAI_RNGSEED env variable everywhere. Hide normal table
initialization of Ziggurat generator from outside. Fix atoi() to use
stroul()
atoi() used previously does not capture all of unsigned long (so we
could not reproduce a high seed), and its use is discouraged as it does
not detect errors. Use strtoul() instead, which allows to also use other
bases (so we can e.g., write OAI_RNGSEED=0x1234)
Hide normal table initialization of Ziggurat generator from outside to
force the usage of randominit() for RNG initialization. In this step,
remove the randominit() seed parameter and only rely on OAI_RNGSEED for
a consistent RNG initialization, as this parameter was used differently
("0" as fixed number or to force a random seed).
Now, only use OAI_RNGSEED env variable to force the usage of a fixed
seed.
Integration `2025.w48`
* !3778 CI: Update IP addresses in Aerial gNB config files
* !3659 UE NTN - Epoch time handling for Target cell
* !3772 CI: Ensure EPC is always terminated in NSA-B200 pipeline
* !3773 Fix doc for UTC timestamp
* !3759 NR UE: fix bug for SRS generation when freqDomainShift (n_shift) is not 0
* !3774 Use UL functions for Qm/R determination
* !3767 Fix DRB integrity failures during handover and re-establishment
* !3764 Avoid measGap configuration on handover in intra-freq scenarios
* !3768 Fix MIB encoding in F1SetupRequest: use encode_MIB_NR_setup instead of encode_MIB_NR
* !3771 CI build analysis: print log file errors
* !3703 Taking into account UE capabilities for TBS_lbrm layers
* !3561 Implementation of STOP exchange
* !3776 Fix reestablishment after handover
* !3763 CI: Reduce the tries to attach the UE in CI runs
* !3761 fix(FHI 7.2): PRACH frame test
* !3616 [FHI72 M-plane] Update the M-plane support to v16.01
* !3790 Correctly copy nFAPI messages
* !3779 CFRA: mark RA complete when sending Msg2 - check CI
Closes#563 and #1034
See merge request oai/openairinterface5g!3775
CFRA: mark RA complete when sending Msg2
The current contention-free random access forces a "Msg3" (which does
not exist in CFRA) to be received by a UE. Sometimes, this "Msg3" is not
received (for whatever reason), and the MAC declare that RA failed.
This is problematic, as the spec says that RA is complete once Msg2 is
received by the UE. Since the gNB cannot know when this is, simply mark
it as complete once we sent Msg2.
We still send Msg3 in CFRA, which is explained further in the commits.
Also, improve logging and stabilize an RFsim test by reducing sl_ahead.
Correctly copy nFAPI messages
All nFAPI message have copy helpers, so use that for "loading" nFAPI
messages into the L1. This also fixes a bug/error message
2. 0 no corresponding tx_data.request for dl_tti.request index 11, dropping
because the loop over DL_tti.request assumed that all messages are PDSCH
PDUs, when we can have others such as PDCCH, etc. In other words, when
looking up indices ("11" in the example above), we were checking also
inside other messages for SSB, PDCCH, etc, which is of course wrong.
That loop was an attempt to validate matching PDSCH PDUs with
TX_data.requests. This check is already done inside
phy_procedures_gNB_TX() through an assert, but this commit replaces with
the equivalent check previously inside nr_pnf_p7_get_msgs(). This is ok,
as the L1 cannot trust the scheduler (in monolithic) to provide the
correct information, either.
Fixes: eefb9da6 ("Reimplement nFAPI message exchange after msgDataTx removal")
[FHI72 M-plane] Update the M-plane support to v16.01
- retrieve the additional hardware states (oper-state, admin-state,
availability-state) and update according to the received notifications
- properly configure MIMO mode if a RU supports
- update the yang models to v16.01
- tested with Benetel v1.4.1, and added an example run in the M-plane doc
Note: backwards compatible with M-plane v05.00
Also, memory leakages fixed cause by ru_session_list_t, and xml functions
xmlReadMemory() and xmlNodeGetContent().
fix(FHI 7.2): PRACH frame test
A test was missing in the PRACH RX function of the FHI 7.2 in order to know if
the frame had a PRACH occasion. This was leading to continuous warning messages
as PRACH RX was triggered on frames in which PRACH was not expected by the
scheduler.
CI: Reduce the tries to attach the UE in CI runs
The goal of this MR is to save time in CI runs by reducing the UE attach tries
to 3 instead of 4 and UE timeout to 20 seconds, which will be incremented after
each fail, instead of 60 seconds.
Since the parent commit, CFRA is inconditionally marked complete on Msg3
reception (successful or not). This works because the current
implementation still sends a UL grant (see parent commit for details).
In this commit, handle Msg3 if received in CFRA (notably for TA and
power). Note that since we declare RA complete, UE->ra does not exist
anymore, and so an intermediate variable is introduced to capture the
CFRA flag. The code should be such that if we are in CFRA, we never
access any UE->ra variable.
All nFAPI message have copy helpers, so use that for "loading" nFAPI
messages into the L1. This also fixes a bug/error message
2. 0 no corresponding tx_data.request for dl_tti.request index 11, dropping
because the loop over DL_tti.request assumed that all messages are PDSCH
PDUs, when we can have others such as PDCCH, etc. In other words, when
looking up indices ("11" in the example above), we were checking also
inside other messages for SSB, PDCCH, etc, which is of course wrong.
That loop was an attempt to validate matching PDSCH PDUs with
TX_data.requests. This check is already done inside
phy_procedures_gNB_TX() through an assert, but this commit replaces with
the equivalent check previously inside nr_pnf_p7_get_msgs(). This is ok,
as the L1 cannot trust the scheduler (in monolithic) to provide the
correct information, either.
Fixes: eefb9da69a ("Reimplement nFAPI message exchange after msgDataTx removal")
A test was missing in the PRACH RX function of the FHI 7.2 in order to
know if the frame had a PRACH occasion.
This was leading to continuous warning messages as PRACH RX was
triggered on frames in which PRACH was not expected by the scheduler.
The current contention-free random access forces a "Msg3" (which does
not exist in CFRA) to be received by a UE. Sometimes, this "Msg3" is not
received (for whatever reason), and the MAC declare that RA failed.
This is problematic, as the spec says that RA is complete once Msg2 is
received by the UE. To avoid this, inconditionally mark RA as complete
as soon as we receive an indication of Msg3 (DTX or not).
Note that after this change, we still send a UL grant in Msg2. This is
because 38.321 §5.1.4 is not clear to me whether we should send UL grant
(it does not explicitly exclude it), and it says
> 3> if the Random Access Response includes a MAC subPDU with RAPID only:
> [...]
> 4> indicate the reception of an acknowledgement for SI request to
> upper layers.
which is NOT the case (but then I don't know/think we can have CFRA for
SI request?). Since it also works with COTS UE, I leave Msg3 for the
moment.
The reason to not directly mark RA as complete when sending Msg2 is
because of possible retransmissions in do-ra mode. In fact, in do-ra,
there might already be data awaiting. In that case, the DLSCH scheduler
schedules data _in the same slot as Msg2_, which the UE does not decode,
leading to retransmissions.
Implementation of STOP exchange
This implements the STOP.request/indication for all 3 transport mechanisms, the
VNF will send the STOP.request to the PNF, indicating it will disconnect, and
await a STOP.indication from the PNF
The WLS VNF is reworked to be able to start before the PNF, by calling call
rte_eal_init and rte_dev_probe to determine if dpdk has been initialized
properly, before calling rte_eal_init in the intended process when it is
appropriate to do so
Fix reestablishment after handover
- fix reestablishment by not re-creating LCIDs with priority set to 0 (see first
commit for more details)
- cleanup code
CI build analysis: print log file errors
The generated HTML from CI builds so far only shows the number of errors, but
not the errors themselves. This is inconvenient, as this means that developers
have to go to the logs.
This commit modifies AnalyzeBuildLogs(), which already iterates the entire file,
to store the lines containing "error:" (as it would be emitted by a compiler).
The callers of AnalyzeBuildLogs() now also print the analysis outcome in a more
concise manner.
Also, change the return parameter of AnalyzeBuildLogs() to a tuple to make the
variable handling easier, and remove the unused warnings list.
The idea is to reestablish all RLC entities (it's a new UE, and we set
reestablishRLC on all bearerrs), so we should reestablish all RLC
entities on gNB side as well, without any additional loop.
Co-authored-by: Roberto Magueta <rmagueta@allbesmart.pt>
Move the file process_addmod_bearers_cellGroupConfig() to the file where
it is used. Correctly set priorities as requested in RLC bearer
configuration.
In all cases (NSA, HO), we create LCIDs before the UE triggers random
access. Hence, process_addmod_bearers_cellGroupConfig() is not
necessary, as it just tries to recreate an LCID.
Furthermore, it includes a bug, as this function does set a wrong
priority (0), so the sorting of LCIDs is not correct. This in turn
creates problems with reestablishment, as LCID 1/SRB1 is not in the
first position, making reestablishment fail (where we assume LCID 1 be
in first position).
The actual bug of setting priorities is fixed in the next commit.
Fix MIB encoding in F1SetupRequest: use encode_MIB_NR_setup instead of encode_MIB_NR
- The DU was using encode_MIB_NR() while constructing the GNB-DU System
Information for the F1SetupRequest.
- encode_MIB_NR() encodes a full NR_BCCH_BCH_Message_t, causing the MIB to be
wrapped in a BCH container.
- This results in incorrect MIB values in the F1SetupRequest PCAP (e.g., wrong
systemFrameNumber, SCS, DMRS position, cellBarred).
- According to 3GPP TS 38.473, the MIB carried in F1AP must be encoded as a raw
NR_MIB_t.
- The correct function encode_MIB_NR_setup() encodes MIB in the required format
but was not used.
- This patch replaces encode_MIB_NR() with encode_MIB_NR_setup() to ensure correct
and standards-compliant MIB encoding in the F1SetupRequest.
Closes issue #1034.
Fix DRB integrity failures during handover and re-establishment
This MR fixes DRB integrity protection failures that occur during N2 handover
and connection re-establishment scenarios. The issues were caused by incorrect
security key handling and ciphering configuration during these procedures with
DRB integity enabled.
See merge request !3767 for more details.
Avoid measGap configuration on handover in intra-freq scenarios
During the handover, we are incorrectly configuring the measGap, even though
neighboring cells are on the same frequency. Since gNB is not expecting this
measGap, the SRS scheduling is performed. Therefore, we are periodically
receiving these logs after the handover:
[NR_MAC] Invalid timing advance offset for RNTI 58e2
[NR_MAC] Invalid timing advance offset for RNTI 58e2
[NR_MAC] Invalid timing advance offset for RNTI 58e2
[NR_MAC] Invalid timing advance offset for RNTI 58e2
[NR_MAC] Invalid timing advance offset for RNTI 58e2
[NR_MAC] Invalid timing advance offset for RNTI 58e2
These logs occur at a time when UE is performing a MeasGap operation and not
sending the SRS, while gNB thinks it will receive the SRS, but will not receive
any SRS.
This MR resolves this issue, and after the handover, these logs no longer
appear.
CI: Update IP addresses in Aerial gNB config files
This MR updates the NG-AMF and NG-U IP addresses in both Aerial configuration
files (standard and UL-heavy) following the IP address change on GH1.
Use UL functions for Qm/R determination
During refactoring, the wrong functions and correspondingly tables have
been used to calculate UL TB size. Fix through correct functions.
This should fix these error messages:
3624774.778195 [MAC] E (nr_get_Qm_dl:2034) Invalid MCS table index 3 (expected in range [0,2])
3624774.778207 [MAC] E (nr_get_code_rate_dl:2066) Invalid MCS table index 3 (expected in range [0,2])
3624774.778211 [NR_MAC] E (nr_compute_tbs:63) Error in compute TBS with a NULL input, returning NULL TBS
Fixes: 9449f777 ("Remove TBS table and recompute on demand")
NR UE: fix bug for SRS generation when freqDomainShift (n_shift) is not 0
According to TS 38.211 section 6.4.1.4.3, the frequency domain shift value
n_shift is from higher-layer parameter freqDomainShift. The quantity n_RRC
is given by higher-layer parameter freqDomainPosition. Also corrected
k_0_overbar_p calculation formula to align with standard.
Fix doc for UTC timestamp
After merging !3751 (merged), the UTC timestamp now prints only the time.
Update the documentation to reflect this simplified format.
UE NTN - Epoch time handling for Target cell
In case of Handover, NTNconfig sent in RRCreconfiguration triggering handover
contains epoch time wrt timing of Target cell. NTNconfig in RRC needs to be
processed only after timing is acquired on the target cell.
In case of Target cell, epoch time is the sfn nearest to the frame timing of the
target cell.
During refactoring, the wrong functions and correspondingly tables have
been used to calculate UL TB size. Fix through correct functions.
This should fix these error messages:
3624774.778195 [MAC] E (nr_get_Qm_dl:2034) Invalid MCS table index 3 (expected in range [0,2])
3624774.778207 [MAC] E (nr_get_code_rate_dl:2066) Invalid MCS table index 3 (expected in range [0,2])
3624774.778211 [NR_MAC] E (nr_compute_tbs:63) Error in compute TBS with a NULL input, returning NULL TBS
Fixes: 9449f777cc ("Remove TBS table and recompute on demand")
This change updates the NSA-B200 CI pipeline to guarantee that the EPC is
properly terminated regardless of pipeline success or failure. This avoids
leaving EPC processes running after failed test.
The generated HTML from CI builds so far only shows the number of
errors, but not the errors themselves. This is inconvenient, as this
means that developers have to go to the logs.
This commit modifies AnalyzeBuildLogs(), which already iterates the
entire file, to store the lines containing "error:" (as it would be
emitted by a compiler). The callers of AnalyzeBuildLogs() now also print
the analysis outcome in a more concise manner.
Also, change the return parameter of AnalyzeBuildLogs() to a tuple to make
the variable handling easier, and remove the unused warnings list.
- The DU was using encode_MIB_NR() while constructing the GNB-DU System Information for the F1SetupRequest.
- encode_MIB_NR() encodes a full NR_BCCH_BCH_Message_t, causing the MIB to be wrapped in a BCH container.
- This results in incorrect MIB values in the F1SetupRequest PCAP (e.g., wrong systemFrameNumber, SCS, DMRS position, cellBarred).
- According to 3GPP TS 38.473, the MIB carried in F1AP must be encoded as a raw NR_MIB_t.
- The correct function encode_MIB_NR_setup() encodes MIB in the required format but was not used.
- This patch replaces encode_MIB_NR() with encode_MIB_NR_setup() to ensure correct and standards-compliant MIB encoding in the F1SetupRequest.
Closes issue #1034.
Problem:
During N2 handover with integrity protection (NIA1/NIA2), the target gNB
was disabling ciphering when configuring SRB1 security, while the UE
continued using the old security context from the source gNB until it
received and processed the RRC Reconfiguration with masterKeyUpdate. The
first PDUs sent after CFRA were still ciphered with the old keys, but the
target gNB had ciphering disabled, causing it to skip deciphering and
attempt integrity verification on ciphered data, leading to MAC-I
mismatches and integrity failures.
Specification Reference:
According to TS 33.501 section 6.11, "the UE shall keep the K gNB used in
the source cell until the handover or a connection re-establishment has been
completed successfully". This means the UE continues using the old security
context (old KRRCint, KRRCenc) until it receives and processes the RRC
Reconfiguration with masterKeyUpdate. The target gNB must therefore enable
ciphering during handover setup to correctly decipher and verify integrity
of PDUs sent with the old security context before the UE switches to the new
keys.
Root Cause:
The code was calling nr_rrc_pdcp_config_security(UE, false) during
handover setup, which disabled ciphering. This was incorrect because:
1. The UE already has security active from the source gNB
2. The UE continues using old ciphered keys until masterKeyUpdate
3. The UE sends ciphered PDUs immediately after CFRA succeeds
4. The target gNB must be able to decipher these PDUs to verify integrity
Why it only manifested when drb_integrity = "yes":
The bug was always present, but only caused visible failures when
integrity verification was enabled. When drb_integrity = "no", the config
typically also sets integrity_algorithms to only NIA0, resulting in
UE->integrity_algorithm = 0, which causes has_integrity = 0 for SRB1,
skipping integrity verification and hiding the underlying ciphering bug.
When drb_integrity = "yes", integrity_algorithms typically includes
NIA1/NIA2, resulting in has_integrity = 1 for SRB1, causing integrity
checks to run on ciphered data and fail.
Fix:
Change nr_rrc_pdcp_config_security(UE, false) to
nr_rrc_pdcp_config_security(UE, true) during handover setup to enable
ciphering immediately, allowing the target gNB to correctly decipher and
verify integrity of PDUs sent with the old security context.
Note: This fix is specific to handover. During initial context setup,
ciphering should remain disabled until SecurityModeComplete is received,
as the UE hasn't activated ciphering yet at that point.
During re-establishment, new KgNB* is derived, requiring new UP keys (KUPint,
KUPenc) to be sent to CU-UP. When do_drb_integrity = true, CU-UP needs the
updated integrity keys to verify DRB PDUs. Without this update, CU-UP uses
old keys while the UE uses new keys, causing integrity failures.
The fix ensures security info is always sent during re-establishment,
which is critical for DRB integrity.
Instead of using the projected velocity and acceleration vectors,
calculate vel_sat_gnb and acc_sat_gnb so the delay is correct for
epoch_time, epoch_time + 5 seconds and epoch_time + 10 seconds.
Separate timing_advance (N_TA) from timing_advance_ntn (N_common_TA_adj + N_UE_TA_adj)
to keep N_TA when updating N_common_TA_adj + N_UE_TA_adj.
Fixes#981
Instead of trying to estimate N_UE_TA_adj with a second degree polynomial,
we introduce orbit propagation to calculate N_UE_TA_adj with higher accuracy.
When we receive the satellite ephemeris data consisting of the satellite position vector
and the satellite velocity vector, we calculate parameters for orbit propagation, assuming
a circular orbit in the plane created by the satellite position vector and the satellite
velocity vector. This is done in the function prepare_ue_sat_ta().
Every millisecond, we use these parameters together with the time since epoch to calculate
the satellite position on that orbit and from this the reound-trip-time between UE and the
satellite, what corresponds to N_UE_TA_adj. This is done in the function apply_ntn_timing_advance().
In case of Handover, NTNconfig sent in RRCreconfiguration triggering handover contains epoch time wrt
timing of Target cell. NTNconfig in RRC needs to be processed only after timing is acquired on the target cell
In case of Target cell, epoch time is the sfn nearest to the frame timing of the target cell.
Integration `2025.w46`
* !3754 NR UE: correctly provide measured SSB SINR value from PHY to MAC
* !3666 NTN: Fixing variable ULDLduplex issue for NTN bands
* !3747 SDAP: guard RX header parsing with enable_sdap and init per-entity
* !3729 DCI 00 alt size fix
* !3753 gNB: fix MAC TA command scheduling if measurement gaps are configured
* !3722 [NGAP] Fix incorrect AMF Set ID type (uint8 → uint16) causing AMF lookup failure
* !3745 Collection of small fixes
* !3755 CI: Increase tested UL throughput on Aerial pipeline using 2L UL
* !3752 [MAC] Add UL total/used aggregated MAC stats; [E2 agent] Properly calculate used UE PRBs in KPM
* !3707 Cleanup phy_procedures_gNB_uespec_RX
* !3750 Handling newly opened UE issues
* !3751 Update log header format to align log output
* !3757 Remove schedule response and update L1 threading documentation
* !3748 Refactor imscope
* !3760 gNB: modify RLC configuration applied for SRB1 during RRCReestablishment
* !3684 PDU Session Release
Closes#867, #960, #1025, #1024, #1026, #1031, #1030, and #1012
See merge request oai/openairinterface5g!3756
PDU Session Release
This MR implements end-to-end PDU Session Release functionality
according to 3GPP TS 38.413 and TS 38.331 specifications.
Reason for Change Previous implementation had incomplete and wrongly
places tunnel cleanup during PDU session release. UP cleanup shall be
done at CUUP, RRCReconfiguration shall be sent after retrieval of
updated CellGroupConfig from the DU. This implies F1 and E1 exchanges
during PDU session release procedure.
Major Changes:
1. RRC PDU Session Release: DRBs and PDU session teardown in NGAP PDU
Session Release Response callback
- Helper Functions: Introduced rm_pduSession,
find_drb_by_pdusession_id and rm_drbs() helpers to locate and clean
up DRBs linked to a specific PDU session
- Targeted Cleanup: RRC PDU Session and per-session DRB removal in
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE()
- Status Cleanup: Removed unused PDU_SESSION_STATUS_RELEASED status
2. RRC PDU Session Release: Refactor
rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND
- Any PDU session in the pdusession_release_params list that is
present in the RRC list can be set to release, regardless of its
status
- Function Signature Update: Updated function signature and other
minor changes
- Response Handling: rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE is
sent upon completion of RRCReconfiguration
3. RRC PDU Session Release: add missing procedures E1AP Integration:
- Populates E1AP Bearer Modification for each to be released session
- PDCP Enhancement: Added nr_pdcp_release_drbs() to remove all DRBs
linked to a given PDU session in CUUP
- GTP-U Cleanup: GTP tunnel teardown handled in CUUP
e1_bearer_context_modif() using correct F1 or N3 GTP instance
4. NR PDCP/GTP:
- Enhanced Tunnel Deletion Logic: Separate handling for N3 tunnels (1
per PDU session) and F1-U tunnels (1 per DRB)
- New PDCP API Function: Added nr_pdcp_get_drb_ids_for_pdusession()
function to retrieve all DRB IDs associated with a specific PDU
session
5. RRC PDU Session Release: F1AP-based UE Context Modification:
- Replaced direct RRC message transfer with F1AP UE Context
Modification Request for proper retrieval from DU
- Cell Group Configuration: handling of updated CellGroupConfig from
DU ensures DRB release at CU
6. Docs and testing:
- Added PDU session add/remove test cases to 25 PRB RFSIM pipeline
- Documentation: Added PDU Session Release sequence diagram
- Telnet Commands: Added ci command to trigger NGAP PDU Session
Release and ciUE command to trigger establishment of a new PDU
Session
7. Additional fixes:
- UE RLC Management: ensure release of RLC entities
- Unify NG delay control before calling the RRC NGAP handler, for both
Setup and Release
8. Code Cleanup: Cleaned up unused GTP teardown functions.
Closes#867
- Add delayed_action_state_t in the UE context for ongoing delayed action
- Move delay check and timer re-enqueue to rrc thread in rrc_gNB.c (rrc_delay_transaction)
- Call delay before NGAP setup/release handlers; remove local delay logic from rrc_gNB_NGAP.c
- Clear on RRCReconfigurationComplete (reset_delayed_action)
Closes#960
- Enable telnet server on VNF (gNB) and UE in docker-compose.yaml
- Add new test cases for PDU session management:
* Add PDU session via UE telnet
* Release PDU session via telnet
* Verify connectivity after PDU session release
- Integrate telnet commands into existing container_5g_rfsim_u0_25prb.xml pipeline
- Test cases added before undeploy step in proper execution order
This commit introduces a new telnet server command `pdu_session_release` to
manually trigger the NGAP PDU Session Release Command message from the telnet ci shell.
This is useful for integration testing of PDU session teardown behavior.
Details:
- Added `trigger_ngap_pdu_session_release()` to send NGAP_PDUSESSION_RELEASE_COMMAND
to the RRC task, targeting the specified `gNB_ue_ngap_id`.
- The command currently releases PDU session ID 10 (hardcoded).
- Hooked into telnet shell with command: `pdu_session_release [gNB_ue_ngap_id]`
Usage example:
telnet > pdu_session_release 1
We need to keep PDU sessions and DRBs in list until the NGAP PDU Session Release Response is sent.
* Introduced find_drb() and remove_drbs_by_pdu_session() helpers to locate
and clean up DRBs linked to a specific PDU session
* Targeted per-session DRB removal in rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE()
* Ensures DRBs for unaffected PDU sessions remain intact
* Remove unused PDU_SESSION_STATUS_RELEASED status: keeping this status is no longer relevant
since the PDU sessions are effectively removed from the RRC lists
Closes#867
Also, refactor rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND
3GPP TS 38.413 8.2.2 PDU Session Resource Release says:
> upon reception the NG-RAN node shall execute the release of the requested PDU sessions.
> For each PDU session to be released the NG-RAN node shall release the corresponding
> resources over Uu and over NG, if any.
Therefore, any PDU session in the pdusession_release_params list that is
also present in the RRC list can be set to release, regardless of its status.
The function signature was also updated along with other minor changes.
The partial-tunnel deletion API was buggy and redundant:
* e.g. It erased entries from globGtp.te2ue_mapping but never erases
the corresponding entries from inst->ue2te_mapping[ue].bearers
All current use cases are already covered by:
* newGtpuDeleteOneTunnel() for targeted deletion
* newGtpuDeleteAllTunnels() for full cleanup
Call sites should explicitly loop over newGtpuDeleteOneTunnel()
if multiple tunnels need removal.
This commit implements proper PDU Session Release handling across
RRC, PDCP, F1AP, E1AP to ensure clean resource cleanup when
a PDU session is terminated.
Key changes:
NGAP:
In `rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND()`:
* Populates E1AP Bearer Modification for each released session
* If a CU-UP is connected, triggers `bearer_context_mod()` for PDU teardown
PDCP:
* Added `nr_pdcp_release_drbs()` to remove all DRBs linked to a given PDU session
* Called from `e1_bearer_context_modif()` for correct clean-up during session release
F1AP UE Context Modification:
Replace direct RRC message transfer with F1AP UE Context Modification Request
to properly handle PDU session release according to 3GPP TS 38.331.
3GPP TS 38.331 `5.3.5.6.4 DRB release` says: whether or not the RLC and MAC entities associated
with a PDCP entity are reset or released is determined by the CellGroupConfig. Thus,
updated CellGroupConfig needs to be received by the UE. This has to be retrieved by CUCP
from the DU. Therefore:
After receiving an NGAP_PDUSESSION_RELEASE_COMMAND, the CUCP shall:
1) forward (store for later) the NAS PDU to the UE, if present as per 3GPP TS 38.413, and
2) send a UE Context Modification to the DU with the list of DRBs to release
and the RRC container (RRCReconfiguration with NAS PDU)
After reception of UE Context Modification Response, the list of drbs to release
is prepared based on PDU session status PDU_SESSION_STATUS_TORELEASE
in rrc_gNB_generate_dedicatedRRCReconfiguration and then encoded
in drb_ToReleaseList for a new RRCReconfiguration with the new cellGroupConfig.
Key changes:
* rrc_gNB_generate_dedicatedRRCReconfiguration_release() now uses F1AP UE Context
Modification Request instead of direct RRC transfer
* Only DRBs to be released are now added to the list.
* The ASN.1 memory allocation is entirely done in build_RRCReconfiguration_IEs
* No longer needed to store ASN1 struct in UE context
GTP-U:
* Previous implementation had incomplete tunnel cleanup during PDU session release
- Missing distinction between N3 (PDU session level) and F1-U (DRB level) tunnels
- Lack of proper DRB identification for F1-U tunnel deletion
Major Changes:
* GTP tunnel teardown now handled in `e1_bearer_context_modif()` using the correct
F1 or N3 GTP instance (`newGtpuDeleteOneTunnel()`)
* Enhanced Tunnel Deletion Logic (cucp_cuup_handler.c):
- Separate handling for N3 tunnels (1 per PDU session) and F1-U tunnels (1 per DRB)
- Added proper DRB identification for F1-U tunnel cleanup
- Improved error handling with detailed logging for each tunnel deletion
- Enhanced logging to distinguish between N3 and F1-U tunnel operations
* New PDCP API Function (nr_pdcp_oai_api.c/h):
- Added nr_pdcp_get_drb_ids_for_pdusession() function
- Enables retrieval of all DRB IDs associated with a specific PDU session
- Supports proper F1-U tunnel cleanup by providing DRB identifiers in CUUP
* Enhanced GTP Interface (gtp_itf.cpp/h):
- Modified newGtpuDeleteOneTunnel() to accept tunnel_type parameter
- Improved logging to distinguish between PDU session and DRB tunnel types
- Better error messages for tunnel deletion failures
- Enhanced debugging information for remaining tunnels
Clean-up:
* Ensured xid tracking works consistently between PDU Session Establishment (with NAS PDU)
and dedicated RRCReconfiguration
* Add function to release GTP-U tunnel in Bearer Context Modification Request handler
* Do not send rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE when no PDU session are to
be released: it is sent upon completion of the RRCReconfiguration and needs to contain
released PDU Sessions (mandatory IE), therefore it is no necessary to send it in case
there is no PDU session to release.
Related to #867
Co-authored-by: rmagueta <rmagueta@allbesmart.pt>
gNB: modify RLC configuration applied for SRB1 during RRCReestablishment
TS 38.331 clause 5.3.7.4 specifies to apply the configuration defined in
9.2.1 for SRB1 at UE side. This implies that the gNB also has to apply
sn_field_length = 12, but there are no implications on the other RLC
parameters.
As wrong timer values break SRB1 e.g. for long RTT NTN scenarios, this
commit switches to using the RLC timer values provided in the
configuration file. Currently we still set poll_pdu, poll_byte and
max_retx_threshold to the values defined in 9.2.1, but this can be
changed.
Refactor imscope
This MR refactors imscope by introducing changes to the default layout
in the config file imgui.ini. The global settings are moved to a new
menu item. This modified layout is intended as a suggestion subject to
change based on feedback. This MR also adds PDCCH LLR and IQ plots to
the UE scope and set axes to AutoFit by default.
The MR has a screenshot of the new layout.
Remove schedule response and update L1 threading documentation
This merge requests removes the somewhat superfluous "schedule response"
mechanism. "schedule response" was run after running the scheduler
itself and copied various FAPI messages into a global msgDataTx
structure from which the various TX/RX jobs were triggered. It is not
necessary, though, given that the scheduler is run inside the tx_func()
(running the TX jobs of the L1), and so the scheduler output FAPI
messages can directly be read into a variable of the existing
NR_Sched_Rsp_t type. This allows to delete a couple of hundred lines of
code (while retaining functionality), and simplifies the msgDataTx type
(which is still there to trigger TX job (including the scheduler) from
the ru thread).
In short, prior, there was this call chain:
- tx_func() calls run_scheduler_monolithic() (through fptr
NR_slot_indication())
- get some memory through allocate_sched_response() which has enough
space for NR_Sched_Rsp_t type variable
- call the scheduler and fill the variable
- call nr_schedule_response() (through fptr NR_schedule_response())
which copies into L1: to msgDataTx for TX, to separate structures
for RX
this is changed to
- tx_func() runs one message at a time, hence we can use memory in the
data segment for NR_Sched_Rsp_t. It calls run_scheduler_monolithic()
through the fptr
- pointers into NR_Sched_Rsp_t are passed to the scheduler, which
fills as before
- we return, memory is in its right place and does not need an extra
copy.
Additionally, this merge request updates documentation on threading and
cleans up some unused code along the way.
Update log header format to align log output
The new format:
- left-aligns the log header name and enforces a minimum width of 6 characters,
padding shorter names with spaces while allowing longer names to be printed in
full
- shortens UTC timestamp
- align function names to 32 characters
Example output:
[19:51:34.647930] [NGAP] I (ngap_gNB_decode_initiat:100) Handover Resource Allocation initiating message
[19:51:34.648539] [NGAP] D (decode_ng_handover_requ:267) AllowedNSSAI.list.count 2
[19:51:34.648586] [NGAP] I (ngap_gNB_handle_handove:728) Received NG Handover Request from AMF OAI-AMF (ID=1)
[19:51:34.648627] [NR_RRC] I (rrc_gNB_process_Handove:1199) Received Handover Request (on NR Cell ID=11111111, PCI=1)
[19:51:34.648647] [NR_RRC] A (rrc_gNB_create_ue_conte:230) [--] (cellID 0, UE ID 1 RNTI ffff) Create UE context: CU UE ID 1 DU UE ID 4294967295 (rnti: ffff, random ue id ffffffffffffffff)
[19:51:34.648659] [NR_RRC] A (set_UE_security_algos:692) [--] (cellID 0, UE ID 1 RNTI ffff) Selected security algorithms: ciphering 0, integrity 2
Reimplement nFAPI message exchange between L1 and L2 following the
changes in parent commit removing msgDataTx.
Avoid direct calls and use NR_IF_module fptrs to avoid linking problems.
allowing to remove some function definitions that are not needed.
Note: after this commit, monolithic works but nFAPI operation is broken
and fixed in the next commit, to keep the changes small(er). All
simulators work.
This commit removes the use of msgDataTx's intermediate buffers for FAPI
messages and the call of the "Schedule response". The latter incurs an
additional copy of FAPI messages for the TX chain (for the RX chain, it
is and will remain there) which we can avoid.
Instead, it uses an NR_Sched_Rsp_t-typed variable sched_response to
store the results of the scheduler when called from tx_func(). Thus, the
scheduler remains unchanged (it gets a pointer to where to put FAPI
messages), but we don't call nr_schedule_response() to then copy FAPI
messages into the L1, but have them in a local variable sched_response.
sched_response on on the data segment, as it is big and would overflow
the stack; at the same time, this is ok because only one tx_func() runs
at a time.
Since we don't use allocate_sched_response() anymore, we don't need
deref_sched_response().
clear_slot_beamid() is moved to tx_func(), as it was called in
nr_schedule_response().
Since the "intermediate" NR_gNB_DLSCH_t structure groups both the
DL_tti_pdsch and TX_data.req structures, a pointer has been created to
point to pdsch_pdu. This affects a number of simulators, as they have to
put some messages on the stack:
- nr_dlschsim: put the corresponding variable on the stack
- nr_pbchsim: a new array for the SSB PDUs has been introduced
Further, these changes are now necessary:
- nr_dlsim: there were variables "rel15" and "pdsch_pdu_rel15" that
point to the same PDSCH PDU. At least "rel15" would not exist, as the
corresponding pointer is now populated in phy_procedures_gNB_TX(), and
we therefore refer to the single PDSCH PDU variable with
"pdsch_pdu_rel15", but at the place where "rel15" used to be
initialized.
- nr_ulsim: use nr_save_ul_tti_req() to load PDUs into the RX chain
instead of nr_schedule_response(), which does not exist anymore.
The next commit will remove msgDataTx. We can therefore not use
msgDataTx to retain the PDSCH/DLSCH variables, and move them to the gNB.
Note that the only reason for NR_gNB_DLSCH_t after this commit is to
hold various large buffers (c, b, f). Future work could be done to
remove this, in which case the array inside PHY_VARS_gNB could be
deleted.
On this occasion, clean up the use of init_DLSCH_struct() and
reset_DLSCH_struct() (renamed destroy_DLSCH_struct()) and centralize
their call in phy_init_nr_gNB()/phy_free_nr_gNB(), and correct
simulators accordingly.
TS 38.331 clause 5.3.7.4 specifies to apply the configuration defined in 9.2.1 for SRB1 at UE side.
This implies that the gNB also has to apply sn_field_length = 12, but there are no implications on the other RLC parameters.
As wrong timer values break SRB1 e.g. for long RTT NTN scenarios, this commit switches to using the RLC timer values provided in the configuration file.
Currently we still set poll_pdu, poll_byte and max_retx_threshold to the values defined in 9.2.1, but this can be changed.
Cleanup phy_procedures_gNB_uespec_RX
phy_procedures_gNB_uespec_RX is too long function with too long lines of code,
this commit only shorten lines and improve a bit the readability
[MAC] Add UL total/used aggregated MAC stats; [E2 agent] Properly calculate
used UE PRBs in KPM; [CI] Simplify and improve the Undeploy_Object() and
implement Stop_Object()
- Create common dlul_mac_stats_t struct for both DL and UL total/used aggregated
PRBs
- Use correct unit [%] for RRU.PrbTotDl and RRU.PrbTotUl , instead of [PRBs]
- Use correct unit [Mb] for DRB.PdcpSduVolumeDL and DRB.PdcpSduVolumeUL [kb]
- Implement Stop_Object() (docker compose stop = SIGTERM)
- Simplify the Undeploy_Object() function
- Improve the logging for Deploy/Undeploy_Object() functions
- OAI-FlexRIC CI: properly stop all the containers (one by one or a subgroup of
running containers), and rename oai-flexric to nearRT-RIC container
CI: Increase tested UL throughput on Aerial pipeline using 2L UL
The goal of this MR is to activate the use of 2-layer uplink by enabling SRS
and to increase the tested UL throughput in CI.
The new format left-aligns the component name and enforces a minimum width
of 7 (log component) characters, padding shorter names with spaces after
the closing "]".
Example output:
[14:05:43.395376] [E1AP] I releasing UE 1
[14:05:43.395400] [GTPU] I [91] UE ID 1: Delete all tunnels (1 tunnels)
[14:05:43.395414] [NR_RRC] A [DL] (cellID bc614e, UE ID 1 RNTI 8e27) Send RRC Release
[14:05:43.395431] [RRC] I UE 1: received bearer release complete
[14:05:43.424551] [RLC] W Remove UE 36391
[14:05:43.424597] [NR_RRC] I removed UE CU UE ID 1/RNTI 8e27
[14:05:43.424773] [NR_RRC] A [--] (cellID bc614e, UE ID 1 RNTI 8e27) Remove UE context
[14:05:43.425205] [NR_MAC] I Remove NR rnti 0x8e27
[14:05:43.582158] [HW] W Lost socket
^C
** Caught SIGTERM, shutting down
Returned from ITTI signal handler
[14:05:43.948721] [GNB_APP] I stopping nr-softmodem
[14:05:43.948746] [PHY] I Killing gNB 0 processing threads
[14:05:44.574818] [PHY] I Stopping RU 0 processing threads
[14:05:44.575000] [PHY] I RU 0 RF device stopped
[14:05:44.575006] [GNB_APP] I turned off RU rfdevice
Prior to this change, when no "level" option is given to the logging
module, we see
[PHY] RU 0 RF started cpu_meas_enabled 0
[HW] No connected device, generating void samples...
with three spaces, which is too much. This change reduces the amount of
spaces to 1 without log level.
Co-authored-by: Robert Schmidt <robert.schmidt@openairinterface.org>
We probably almost never care about the date, but it takes a lot of
space. Remove it; if somebody needs the full time stamp including the
date, we could still add it with a new option.
1. Rename oai-flexric to nearRT-RIC. FlexRIC is a project combining nearRT-RIC, xApps, and E2 agent emulators.
2. Instead of undeploying all the containers at the same time, and not checking the logs for xApps and nearRT-RIC, do the following:
- Stop containers (docker compose stop) - one or subgroup of running containers in the following order:
a) xapp-kpm-moni
b) xapp-kpm-rc
c) xapp-gtp-mac-rlc-pdcp-moni
d) oai-nr-ue oai-nr-ue2
e) oai-gnb
f) nearRT-RIC
- Undeploy containers (docker compose down), collect and analyze all the logs.
For some test cases, we might want to stop a service earlier. This
functionality is done by StopObject().
Test log collection is still done by UndeployObject(), which will
collect the logs of all services (at that point, stopped or not).
GetRunningServices() was returning all services, running or stopped.
Hence, rename to reflect what this function does, and rewrite slightly
to better capture what is actually happening. Also, don't return the
container ID, as we don't use it.
Call stop on all services, as we will down the deployment right after.
The list of services is still used to retrieve logs.
Remove a stray "return False", which would sometimes prevent us from
seeing all error messages.
Collection of small fixes
A few fixes needed while testing FHI libraries
- set subcarrier spacing in PUSCH PDU in NRUE
- a set of two LOG_Ds that prints out the PUSCH allocation on gNB & UE
[NGAP] Fix incorrect AMF Set ID type (uint8 → uint16) causing AMF lookup failure
This PR fixes issue #1012 , a data type issue related to the AMF Set ID used
during UE RRC reestablishment. The AMF Set ID was mistakenly declared as uint8_t
instead of uint16_t, even though it is a 10-bit field as specified in 3GPP TS
23.003 section 2.10.1. As a result, AMF Set IDs greater than 255 were truncated,
leading to failed AMF lookups and the following warning: No matching AMF found
for PLMN (MCC=%03d MNC=%0*d) and AMF SetID=%u.
Verified reestablishment succeeds with AMF Set IDs >255.
DLSCH encoding is not concerned with HARQ processes directly. Instead,
it gets the redundancy version and encodes a specific redundancy version
for a given TB. The rest is up to the MAC, the L1 is stateless in that
regard. Hence, remove the HARQ type and put it into DLSCH, which also
simplifies the code elsewhere.
Similarly to the parent commit, simplify the array type to the FAPI PDU
towards further refactoring, and encapsulate the code in a function for
easier reuse in a later refactoring step.
Note on ZP-CSI: after this commit, we continue treating CSI PDUs. The
prior code was returning, which I think is wrong (as this information is
only for the currently treated CSI-RS PDU).
There is no point in tracking the "active" state: the SSB PDU will be
sent from MAC to L1, encoded, and then "discarded" (by marking the
number of SSB PDUs as 0). Hence, remove this intermediate type.
According to TS 38.211 section 6.4.1.4.3, the frequency domain shift value n_shift
is from higher-layer parameter freqDomainShift.
The quantity n_RRC is given by higher-layer parameter freqDomainPosition.
Also corrected k_0_overbar_p calculation formula to align with standard.
Problem:
- GTP-U logs showed negative TEID values (e.g., -1943516315) due to signed/unsigned
conversion. Due to wrong conversion from uint32_t to int and overflow caused negative values.
- TEID values were inconsistently formatted across different log statements, due to
mixed use of %d, %u, %x formats for TEID logging. Made debugging and troubleshooting difficult
Changes:
1. Fixed signed/unsigned conversion bug: use teid_t. Prevents overflow when TEID values exceed int range.
2. Standardized TEID logging format: all TEID values now use '0x%x' hexadecimal format.
Consistent 'TEID' capitalization throughout
According to TS 38.463 - clause 9.2.2.4 and 9.3.3.12.
Also, fix response message by encoding choice IE only
with presence of modified PDU sessions.
Co-authored-by: rmagueta <rmagueta@allbesmart.pt>
Both (DL) PDCCH and UL PDCCH PDU types are fundamentally of the same
type, so correct the array's type to facilitate refactoring later (a
later commit will reuse a single "generate DCI" function for both
cases).
gNB: fix MAC TA command scheduling if measurement gaps are configured
In the current implementation, if UE transmission is interrupted via
nr_mac_interrupt_ue_transmission(), UE_sched_ctrl.ta_frame is modified to be
the previous frame avoiding TA scheduling in the measurement gap. So the next
scheduled TA is shifted to be in 99 frames. As there are other measurement gaps
before that, the scheduled TA is always shifted, but actually never reached,
effectively disabling the MAC TA commands.
To fix this, UE_sched_ctrl.ta_frame is changed to not indicate the last TA
command transmission, but the next one. This allows to check in
nr_mac_interrupt_ue_transmission() if the next TA command transmission is within
the measurement gap and if so shift it to just after that gap.
DCI 00 alt size fix
DCI size for format 00 and 10 should be equal so we need to compute the size of
the alternative format when computing the size of DCIX0. There was a bug where
the alt_size input (0 in that case) was taken into account also when computing
that alternative size, resulting in an alt_size of 0. Possibly easier to
understand by looking at the code then reading this description.
For now, only DL/UL MAC stats.
This commit fixes the "RRU.PrbTotDl" and "RRU.PrbTotUl" measurement calculation
to align with the TS 28.552 specifications.
DL stats (aggregated total and used PRBs) previosuly used only for O1 interface,
now finds the purpose for E2 interface as well.
New UL stats (aggregated total and used PRBs) serve for E2 interface only.
Co-authored-by: Teodora Vladić <teodora.vladic@openairinterface.org>
SDAP: guard RX header parsing with enable_sdap and init per-entity
!3519 (merged) refactored the SDAP to use the QFI from the header rather than
pass it to the rx function and got rid of the initialization of QFI to -1.
However, entity roles are stored into the drb2qfi table, and the indexing
implies that the QFI is known.
While in TX it is not an issue since packets are forwarded based on the QFI,
in RX the QFI can only be parsed from the header, therefore if headers are
disabled (--enable_sdap) the QFI is not there and it is wrong to access the
header (buf[0]) and looking for it.
This commit adds enable_sdap to nr_sdap_entity_t and initialize it in
nr_sdap_add_entity() from sdap->role (disabled when NO_SDAP_HEADER).
In nr_sdap_rx_entity(), only parse buf[0] for QFI and derive sdap_ul_rx/
sdap_dl_rx when enable_sdap is true; otherwise, keep offset=0 and forward
payload unchanged.
NTN: Fixing variable ULDLduplex issue for NTN bands
- Duplex is assumed to be static but for NTN bands (and also for some non NTN
bands), it is not static.
- Tx-RX Duplex is defined in section 5.4.4 of 38.101-5 (for NTN) specs v1809
- For example: In NTN-OTA testing, the GEO satellite operator configured in
band 256 the DL, UL frequencies with duplex of 185Mhz.
Using nFAPI introduces additional delays. At the same time, RFsim does
not run in real-time, and we can allow a low sl_ahead, as RFsim will
"wait" for the gNB.
Therefore, reduce sl_ahead to ensure that the response window does not
run out during handling of RA in nFAPI.
In the current implementation, if UE transmission is interrupted via nr_mac_interrupt_ue_transmission(),
UE_sched_ctrl.ta_frame is modified to be the previous frame avoiding TA scheduling in the measurement gap.
So the next scheduled TA is shifted to be in 99 frames. As there are other measurement gaps before that,
the scheduled TA is always shifted, but actually never reached, effectively disabling the MAC TA commands.
To fix this, UE_sched_ctrl.ta_frame is changed to not indicate the last TA command transmission, but the
next one. This allows to check in nr_mac_interrupt_ue_transmission() if the next TA command transmission
is within the measurement gap and if so shift it to just after that gap.
!3519 refactored the SDAP to use the QFI from the header rather
than pass it to the rx function and got rid of the initialization
of QFI to -1.
However, entity roles are stored into the drb2qfi table, and the
indexing implies that the QFI is known. While in TX it is not an
issue since packets are forwarded based on the QFI, in RX the QFI
can only be parsed from the heaedr, therefore if headers are
disabled (--enable_sdap) the QFI is not there and it is wrong to
access the header (`buf[0]`) and looking for it.
This commit adds `enable_sdap` to `nr_sdap_entity_t` and initialize
it in `nr_sdap_add_entity()` from `sdap->role`
(disabled when `NO_SDAP_HEADER`). In `nr_sdap_rx_entity()`, only
parse `buf[0]` for QFI and derive `sdap_ul_rx`/`sdap_dl_rx` when
`enable_sdap` is true; otherwise, keep `offset=0` and forward
payload unchanged.
Integration `2025.w45`
* !3736 fix bugs in scope for pdcch, and optimize cpu cost of pdcch decoding
* !3743 NR UE: fix PDCCH LLR indexing for different search space RB sizes
* !3739 Bugfix: save old tunnel info to remain the user plane connection while rolling back to source DU due to handover failure
* !3742 Simplify node management in CI, handle SIGINT
* !3670 PRS bug fix and CI Integration
* !3746 Fix unsigned to signed decoding parameters to allow for 'no affinity'/'no pin' threads to CPUs
* !3738 CI: Add new Jenkinsfiles
Closes#984 and #1021
See merge request oai/openairinterface5g!3744
CI: Add unified Jenkinsfile for all test pipelines
This MR introduces a single Jenkinsfile to cover all current CI test pipelines
Improvements:
- correct reporting of the start timestamp in the HTML report
- harmonize log collection - always collect as test_logs_${env.BUILD_ID}.zip
Fix unsigned to signed decoding parameters to allow for 'no affinity'/'no pin'
threads to CPUs
By default, 'L1_rx_thread_core', 'L1_tx_thread_core', 'ru_thread_core' are set
to '-1' but the values were decoded from config file as unsigned instead of
signed types, thus, it was not allowing to set them with '-1' from config file.
PRS bug fix and CI Integration
- Fix the bug in PRS channel estimation while copying memory to compute the
impulse response
- Integrate PRS testing to CI
Simplify node management in CI, handle SIGINT
- Make a single <node> XML step entry common to all XML steps to harmonize code
- Handle SIGINT to make it possible to more easily stop the CI script.
Bugfix: save old tunnel info to remain the user plane connection while rolling
back to source DU due to handover failure
This MR closes issue #984 that UE lost the data plane connection while rolling
back to the source DU due to handover failure.
NR UE: fix PDCCH LLR indexing for different search space RB sizes
After !3603 (merged), when multiple search spaces have different CORESET
configurations (different number of RBs), the LLR buffer stride must be
calculated based on the maximum RB size across all search spaces, not the
current search space's RB size.
The LLR buffer is allocated with size based on get_pdcch_max_rbs(), but the
demapping function was using coreset_nbr_rb (current search space) for symbol
stride calculation, causing incorrect LLR extraction when search spaces have
different RB configurations.
This MR tries to fix it.
Closes#1021
Set the subcarrier_spacing field in nfapi_nr_ue_pusch_pdu_t from MAC
to PHY. This has no consequence for the NR UE Softmodem operation as this
field is never read, but prevents a potential future bug in case L1 was
modified to read it.
By default, 'L1_rx_thread_core', 'L1_tx_thread_core', 'ru_thread_core' are set to '-1' but the values were decoded from config file as unsigned instead of signed types, thus, it was not allowing to set them with '-1' from config file
This commit inputs several distances at once and obtain the summary of
successful and failed tests. We look for the number of successful tests
that are geater than 0. We do that here since we sometimes dont receive
a response for a telnet command from the rfsim although the command
is applied. This is related to the queing telnet commands in the rfsim.
The script for the distances 50, 100 and 150 are called as follows,
./set-and-verify-distance-prs.sh 50 100 150
The summary can be viewed as follows,
==================== SUMMARY ====================
Total tests run : 3
Successful tests: 3
Failed tests : 0
=================================================
Set RFsim (DL) distance and use PRS to estimate the new distance. This
is verified by comparing the distance set in RFsim with the distance
reported through ToA estimation at the UE.
Note that since RFsim telnet output is asynchronous (it uses a queue
internally), we use grep --max-count 1 to wait for the matching line,
together with ncat --idle 0.3 to keep ncat open for some time. The
--max-count option will terminate grep after the first occurrence. For
this to work reliably, we need to use grep <(echo | ncat) as opposod to
simply echo | ncat | grep, as the latter does not seem to reliably
make grep exit after the occurrence.
Co-authored-by: Robert Schmidt <robert.schmidt@openairinterface.org>
fix bugs in scope for pdcch, and optimize cpu cost of pdcch decoding
fix bugs in scope for pdcch, and optimize cpu cost of pdcch decoding by not
processing useless samples in one symbol
When multiple search spaces have different CORESET configurations
(different number of RBs), the LLR buffer stride must be calculated
based on the maximum RB size across all search spaces, not the
current search space's RB size.
The LLR buffer is allocated with size based on get_pdcch_max_rbs(),
but the demapping function was using coreset_nbr_rb (current search
space) for symbol stride calculation, causing incorrect LLR extraction
when search spaces have different RB configurations.
Handle SIGINT and mark any subsequent steps as failed. Receiving SIGINT
a second time will abort the script immediately (as is the case before
this commit).
Note that Python seems to relay the signal to the "controlled" process
(e.g., Ping), which would return immediately with an error. So some
steps like Ping will abort immediately, others (e.g., IdleSleep) will
finish their step, and then the present logic will mark subsequent steps
as failed.
Some CI tasks/commands like Iperf(), Ping() get multiple nodes (via XML
parameter "nodes") to potentially run UEs on different nodes (hosts) at
the same time. However, I argue that this is not good:
- we don't actually use this -- where we specify multiple UEs, it's
always "localhost localhost..."
- it is inconsistent, as we typically have a single "node", not nodes,
and there is a possibility to harmonize (see also next commit)
- if we needed it, there would be better ways to achieve the same.
First, for hardware-based UEs, the ci_infra.yaml can specify different
UEs. For simulated UEs, it would be feasible to have multiple XML
steps run in parallel, e.g., in the XML <parallel> tag, which would
clarify that multiple UEs on different hosts run in parallel
- it reduces code.
Hence, make a single <node> for these XML steps.
Created Jenkinsfiles:
- Jenkinsfile: for stadard test pipelines
- Jenkinsfile-oc: for deployments with OC
These 2 Jenkinsfiles covers all current test pipelines.
Previously, we were using int16_t for the variable ch_tmp which was later harmonized to use c16_t while leaving <<1. This introduced the bug while accessing the address of the element at first_half of the ch_tmp variable.
Integration `2025.w44`
* !3721 improvements in formatting and LOGs in DMRS common functions at MAC
* !3725 Handle GTP receiver errors, fix memory leaks, add CU-UP test
* !3726 fix for CSI payload sizes in PUCCH structure at UE
* CI: Adjust attenutation for HO setup
* !3728 Fix for scenario with no CSI report configured for CSI-RS
* !3731 CI: ensure clean iperf3 server startup
* !3592 Refactor PRACH handling at the gNB
* !3682 Refactor DLSCH scheduler
* !3733 Clarify whitespace
* !3706 Change registry name env var content
Closes#1015 and #1014
See merge request oai/openairinterface5g!3727
Change registry name env var content
Currently setting REGISTRY="" in a .env file results in docker failing to find
/image-name:tag. This corrects that, so it looks for local images named
image-name:tag.
Following the change to use:
image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop}
the REGISTRY variable must now include the trailing slash.
Refactor DLSCH scheduler
Refactor the DLSCH post processor similarly to what has been done in
!3521 with the goal of saving an additional iteration through all UEs,
hopefully making the DLSCH scheduler faster.
It further includes changes to make working with and debugging multi-UE
operation easier:
- add some measurements in L1 (for total TX/RX time)
- a new option MACRLCs.[0].stats_max_ue to limit the number of UEs in
the periodic output (default: 8, 0=disable)
- avoid stack overflow in the MAC
- fix the writing of stats to nrMAC_stats.log and nrL1_stats.log when
the written output reduces by truncating the files
- avoid to schedule retransmission with 0 RBs.
This slightly speeds up the scheduler (it e.g., does not need to check
for UEs that have retransmissions), and harmonizes with pf_ul(), which
evaluates (UL) BSR at a similar place within the scheduler.
Check and return, if necessary, that we have enough resources to make
retransmissions. Without, we can asserts in L1, such as
Assertion (NPRB>0 && (NPRB + RBstart <= BWPsize)) failed!
In PRBalloc_to_locationandbandwidth0() openairinterface5g/common/utils/nr/nr_common.c:506
Illegal NPRB/RBstart Configuration (0,51) for BWPsize 51
which indicates that the scheduler requested a transmission with 0 PRBs,
which does not make sense.
Refactor PRACH handling at the gNB
- Remove race conditions by correctly setting mutexes
- Fix a bug when having multiple RACH occasions
- Reduce memory footprint by removing global memory, which should also
fix potential memory data races in FHI 7.2
- Additional fixes, see commit messages
a bit difficult to understand: sl_ahead=6 => we systematically miss the
rach detection in the scheduler because the scheduler runs more than 6
slots ahead the rx slot processing (here > 11 slots because 6 (DL and UL
slots) + 4 (RU_RX_SLOT_DEPTH, so UL only))
so, reducing sl_ahead works better than large sl_ahead because the idea
behind is: the scheduler of slot+sl_ahead will never create work to do
in a UL slot before slot+sl_ahead+X (as minimum k2 is X, in the 24PRB CI
test: 6)
saves about 600MB of memory allocation
Move the definition of PRACH items and the PRACH list to the
defs_nr_commons.h file.
Do not re-write the entire structure in nr_schedule_rx_prach(), as it is
quite large now.
Call the post-processor when the allocation is "fixed" (i.e., nothing
changes anymore), instead of having a final loop across all UEs that
might potentially be costly.
In order to calculate the PF metric, note that the statistics "reset" is
moved into pf_dl() instead of the post-processing loop, as it has to be
done on each slot.
See also: dd98030202 ("Refactor to call post-processor in place")
Similarly to parent commit(s), assign sched_pdsch in a single place
instead of relying on sched_ctrl. In a follow-up commit, the
post-processor will be called in a single place.
Similarly to parent commit(s), refactor the use of NR_sched_pdsch.
Instead of using nr_mac->sched_ctrlCommon, put the NR_sched_pdsch_t on
the stack.
This also refactors update_rb_mcs_tbs() to update the existing
NR_sched_pdsch instead of updating individual fields.
This also reduces the extend to which sched_ctrlCommon is used.
Assign NR_sched_pdsch to sched_ctrl->sched_pdsch in one place, where the
post-processing functionality will be called in a follow-up commit. This
should result in no functional change.
It seems to be assumed that curInfo actually has the currently active
number of layers/PMI. However, I am not sure this would always be true
(e.g., UE might not have been scheduled for some slots, but number of
layers decreased as reported by CSI). Instead, recalculate the info
from scratch when necessary.
PF uses MCS and average throughput to decide which UE to schedule. Thus,
the first loop decides on MCS, whereas the second does the "main UE
allocation" after sorting by the PF metric.
A follow-up commit will remove sched_pusch from NR_UE_sched_ctrl_t.
Thus, we cannot rely on sched_ctrl to store the MCS in the first loop,
and look it up from there in the second. Instead, store it as part of
the UE iterator data, and take it from there.
See also: f3068caa37 ("Store selected MCS in UE iterator", for UL)
Introduce a struct with information on FAPI structures to save resource
and data allocation into. It's in nr_mac_gNB.h because the next commits
will reuse this for all preprocessors.
Especially in pf_dl()/pf_ul(), we use a first loop using
UE_iterator(), then iterate over a subset of UEs. It has happened a
couple of times that I was using variable "UE" (from the iterator), when
it should only be used in the first UE_iterator() loop.
Rewrite UE_iterator() to effectively limit the scope of the iterator
variables to the body of the UE_iterator. This should also make it
possible to reuse multiple UE_iterator()s with the same variables in
sequence.
CI: ensure clean iperf3 server startup
- Resolves issue with iperf3 test failure in RFSim5G multiue test
- Minor fix of iperf3 test descriptions in RFSim5G pipeline
Fix for scenario with no CSI report configured for CSI-RS
After changes in !3714 (merged), if we select to measure RSRP on SSB and not
CSI-RS (default option) and there is a single antenna port (so no MIMO report
either) we won't schedule any CSI-RS measurements for the UE. In that case
ideally we shouldn't set do_CSIRS = 1 in configuration file but still the
option is possible. So the fix is to not perform any measurements at UE on
that CSI-RS but not asserting.
Closes#1015
1. Create a free_ru_session_list() function to free the memory allocated for the connected RUs
before closing the nr-softmodem.
2. xmlReadMemory() and xmlNodeGetContent() were causing serious memory leakages,
and now all is properly freed using xmlFreeDoc() and xmlFree().
This struct is used in multiple source files.
Previously, when stopping the nr-softmodem, the ru_session_list "disappears"
and the M-plane wasn't terminated properly (num_rus = 0 even though DU connected to at least one RU).
MIMO mode is defined by setting separate carriers to different antenna ports.
Benetel v1.2.2 does not support MIMO mode to be set via M-plane, and therefore
we only created one Tx and one Rx carrier.
Benetel v1.4.1 supports MIMO mode setting via M-plane.
Therefore, this commit introduces the adaptation based on the number of supported carriers by a DUT RU.
These 3 states: "oper-state", "admin-state", "availability-state" are optional,
but shall be checked in order to activate the carriers. If an O-RU doesn't support it,
we assume the expected values:
- "oper-state" = "enabled"
- "admin-state" = "unlocked"
- "availability-state" = "NORMAL"
Implement retrieval of the hardware states if O-RU supports, i.e. Benetel release v1.4.1.
Duplex is assumed to be static but for NTN bands, it is not static.
TxRX Duplex is defined in section 5.4.4 of 38.101-5 (for NTN) specs v1809
n256 190 MHz, 165 to 215 MHz
n255 -101.5 MHz, -72.5 to -130.5 MHz
n254 862 - 885 MHz
The function rx_nr_prach become autonomous, it doesn't read anymore global variables
So, it can become (later) a threadpool work, that will send a message when it finishes
rx_nr_prach_ru() still use some global variables, but it is executed in sequence, inside the ru main loop, that limits the probability of race conditions
Before starting a new iperf3 server instance in CI tests, explicitly kill any existing
iperf3 processes bound to the same port. This prevents conflicts or failures caused by
leftover iperf3 servers from previous runs that did not terminate properly or on time.
The cleanup is performed using `pkill` before launching the new server.
Handle GTP receiver errors, fix memory leaks, add CU-UP test
- Fix use-after-free bugs in GTP by properly stopping the receive thread(s)
- Fix a bug from !3519 (merged): QFI 0 is a valid QFI
- Fix multiple memory leaks in CU-UP, E1, CU-UP load tester, SCTP
- Add a (conservative) functional CU-UP test that verifies that the load tester
and CU-UP work. Test only a low throughput, as it will run in parallel with
other tests.
Use the CU-UP load tester to test the functionality of the CU-UP and
its loader tester. The requirements on this load test are intentionally
low, as it will be run with other unit tests in parallel, and should
still pass.
It uses an existing configuration file for the CU-UP. The test script
runs the CU-UP, runs the load tester, stops the CU-UP, and returns the
load tester return value as test result (which will be 0=success if all
packets have been received).
Note that this strdup has been intentioally created for debugging
purposes in core files.
See also: 1ab3b8dd8e ("add version signature in core files...")
Direct leak of 8 byte(s) in 1 object(s) allocated from:
#0 0x7f7bc7ee68a3 in calloc (/lib64/libasan.so.8+0xe68a3) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
#1 0x0000004abfa6 in calloc_or_fail /home/richie/oai/common/utils/utils.h:74
#2 0x0000004abfa6 in decode_e1ap_cuup_setup_request /home/richie/oai/openair2/E1AP/lib/e1ap_interface_management.c:219
#3 0x00000046a9f5 in e1apCUCP_handle_SETUP_REQUEST /home/richie/oai/openair2/E1AP/e1ap.c:187
#4 0x000000470b35 in e1ap_handle_message /home/richie/oai/openair2/E1AP/e1ap.c:109
#5 0x000000470b35 in e1_task_handle_sctp_data_ind /home/richie/oai/openair2/E1AP/e1ap.c:120
#6 0x00000047717b in E1AP_CUCP_task /home/richie/oai/openair2/E1AP/e1ap.c:832
#7 0x7f7bc7e28ee5 in asan_thread_start(void*) (/lib64/libasan.so.8+0x28ee5) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
Direct leak of 8 byte(s) in 1 object(s) allocated from:
#0 0x7f7bc7ee68a3 in calloc (/lib64/libasan.so.8+0xe68a3) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
#1 0x0000004ac30c in calloc_or_fail /home/richie/oai/common/utils/utils.h:74
#2 0x0000004ac30c in decode_e1ap_cuup_setup_request /home/richie/oai/openair2/E1AP/lib/e1ap_interface_management.c:194
#3 0x00000046a9f5 in e1apCUCP_handle_SETUP_REQUEST /home/richie/oai/openair2/E1AP/e1ap.c:187
#4 0x000000470b35 in e1ap_handle_message /home/richie/oai/openair2/E1AP/e1ap.c:109
#5 0x000000470b35 in e1_task_handle_sctp_data_ind /home/richie/oai/openair2/E1AP/e1ap.c:120
#6 0x00000047717b in E1AP_CUCP_task /home/richie/oai/openair2/E1AP/e1ap.c:832
#7 0x7f7bc7e28ee5 in asan_thread_start(void*) (/lib64/libasan.so.8+0x28ee5) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
Direct leak of 100 byte(s) in 1 object(s) allocated from:
#0 0x7f6585ee6f2b in malloc (/lib64/libasan.so.8+0xe6f2b) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
#1 0x000000414a0d in malloc_or_fail /home/richie/oai/common/utils/utils.h:86
#2 0x0000004061c9 in main /home/richie/oai/tests/nr-cuup/nr-cuup-load-test.c:544
#3 0x7f6585211574 in __libc_start_call_main (/lib64/libc.so.6+0x3574) (BuildId: 48c4b9b1efb1df15da8e787f489128bf31893317)
#4 0x7f6585211627 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3627) (BuildId: 48c4b9b1efb1df15da8e787f489128bf31893317)
#5 0x000000413034 in _start (/home/richie/oai/build/tests/nr-cuup/nr-cuup-load-test+0x413034) (BuildId: 8af0132792b03fa12ba95b5623865c9a8a5625a3)
Direct leak of 100 byte(s) in 1 object(s) allocated from:
#0 0x7f6585ee6f2b in malloc (/lib64/libasan.so.8+0xe6f2b) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
#1 0x000000414a0d in malloc_or_fail /home/richie/oai/common/utils/utils.h:86
#2 0x0000004061ff in main /home/richie/oai/tests/nr-cuup/nr-cuup-load-test.c:546
#3 0x7f6585211574 in __libc_start_call_main (/lib64/libc.so.6+0x3574) (BuildId: 48c4b9b1efb1df15da8e787f489128bf31893317)
#4 0x7f6585211627 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3627) (BuildId: 48c4b9b1efb1df15da8e787f489128bf31893317)
#5 0x000000413034 in _start (/home/richie/oai/build/tests/nr-cuup/nr-cuup-load-test+0x413034) (BuildId: 8af0132792b03fa12ba95b5623865c9a8a5625a3)
Free memory including the "base pointer". Fix two places in which it was
on the stack to harmonize. The only stack variable is in reception of
new E1 messages (e1ap_handle_message()), which uses
ASN_STRUCT_FREE_CONTENTS_ONLY().
This fixes bugs similar to these logs:
Direct leak of 40 byte(s) in 1 object(s) allocated from:
#0 0x7f418f4e68a3 in calloc (/lib64/libasan.so.8+0xe68a3) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
#1 0x00000049e367 in calloc_or_fail /home/richie/oai/common/utils/utils.h:74
#2 0x00000049e367 in encode_e1_bearer_context_release_command /home/richie/oai/openair2/E1AP/lib/e1ap_bearer_context_management.c:1235
#3 0x000000482951 in e1apCUCP_send_BEARER_CONTEXT_RELEASE_COMMAND /home/richie/oai/openair2/E1AP/e1ap.c:546
#4 0x000000482951 in E1AP_CUCP_task /home/richie/oai/openair2/E1AP/e1ap.c:856
#5 0x7f418f428ee5 in asan_thread_start(void*) (/lib64/libasan.so.8+0x28ee5) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
Direct leak of 40 byte(s) in 1 object(s) allocated from:
#0 0x7f418f4e68a3 in calloc (/lib64/libasan.so.8+0xe68a3) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
#1 0x00000049380a in calloc_or_fail /home/richie/oai/common/utils/utils.h:74
#2 0x00000049380a in encode_E1_bearer_context_setup_request /home/richie/oai/openair2/E1AP/lib/e1ap_bearer_context_management.c:578
#3 0x00000047f6a2 in e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST /home/richie/oai/openair2/E1AP/e1ap.c:378
#4 0x0000004829f8 in E1AP_CUCP_task /home/richie/oai/openair2/E1AP/e1ap.c:846
#5 0x7f418f428ee5 in asan_thread_start(void*) (/lib64/libasan.so.8+0x28ee5) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
Direct leak of 40 byte(s) in 1 object(s) allocated from:
#0 0x7f418f4e68a3 in calloc (/lib64/libasan.so.8+0xe68a3) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
#1 0x00000046ede7 in calloc_or_fail /home/richie/oai/common/utils/utils.h:74
#2 0x00000046ede7 in encode_e1ap_cuup_setup_response /home/richie/oai/openair2/E1AP/lib/e1ap_interface_management.c:305
#3 0x00000047e412 in e1ap_send_SETUP_RESPONSE /home/richie/oai/openair2/E1AP/e1ap.c:167
#4 0x000000482a68 in E1AP_CUCP_task /home/richie/oai/openair2/E1AP/e1ap.c:836
#5 0x7f418f428ee5 in asan_thread_start(void*) (/lib64/libasan.so.8+0x28ee5) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
QFI 0 is a valid QFI: don't check for qfi <= 0, as uint8 cannot be
negative. Also, correctly use SDAP_MAP_RULE_EMPTY for a DRB ID (which
need to be larger than 0).
The gNB will stop the periodical logging of UEs in MAC Info level after
a configurable number of UEs have been printed, by default 8.
Set it to 17 in some CI tests to ensure we still get all UEs for the
time being, as the CI might depend on this.
improvements in formatting and LOGs in DMRS common functions at MAC
DMRS LOGs at MAC were misleading. This MR tried to improve them (and also
adds some formatting fix).
The call to snprintf() as was used is wrong: we use the return value to
advance output, but the man page says
> The functions snprintf() and vsnprintf() do not write more than size
> bytes (including the terminating null byte ('\0')). If the output was
> truncated due to this limit, then the return value is the number of
> characters (excluding the terminating null byte) which would have been
> written to the final string if enough space had been available.
> Thus, a return value of size or more means that the output was
> truncated.
Thus, output could go beyond end, and we get a stack overflow. Instead,
encapsulate the call to snprintf() checking this condition, and only
advancing output as intended, limiting to 0 if we are at the end of the
buffer. This avoids this error:
==964825==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7be799f51988 at pc 0x7fe7d66b0d39 bp 0x7be79b825ef0 sp 0x7be79b8256c0
WRITE of size 3 at 0x7be799f51988 thread T24
#0 0x7fe7d66b0d38 in vsnprintf (/lib64/libasan.so.8+0xb0d38) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
#1 0x7fe7d66b2d44 in snprintf (/lib64/libasan.so.8+0xb2d44) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
#2 0x0000008fe7c6 in dump_mac_stats /home/richie/w/refactor-dlsch/openair2/LAYER2/NR_MAC_gNB/main.c:183
#3 0x00000092071a in gNB_dlsch_ulsch_scheduler /home/richie/w/refactor-dlsch/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c:200
#4 0x0000008f8f78 in run_scheduler_monolithic /home/richie/w/refactor-dlsch/openair2/NR_PHY_INTERFACE/NR_IF_Module.c:399
There is the (global) sched_lock that prevents concurrent access. A
dedicated UE lock does not make sense in that case. Worse, this lock
does not prevent all concurrent UE accesses (e.g., there are many loops
over UEs that are not protected), so it's also wrong.
truncate resets the file size to 0. Without this, e.g., when
disconnecting a UE, the old UE remains at the end and is not
overwritten, which is confusing.
- Corrected AMF Set ID data type in ngap_gNB_nnsf_select_amf_by_amf_setid() from uint8_t to uint16_t.
- AMF Set ID is a 10-bit field as per 3GPP TS 38.413 §9.3.3.12.
- The incorrect data type caused truncation for AMF Set IDs >255, leading to lookup failures during RRC reestablishment.
- Verified successful reestablishment with large AMF Set IDs after the fix.
Reason for fix: AMF lookup using AMF Set ID was failing because the 10-bit AMF Set ID was truncated to 8 bits.
Closes#1012
Stop the receive thread before closing the socket, which avoids an error
message when stopping the GTP softmodem:
[GTPU] [91] Recvfrom failed (Bad file descriptor)
[GTPU] exiting thread
On error, exit the GTP thread after printing a diagnostic message. This
avoids also an error flagged by address sanitizer for use-after-free.
[GTPU] [91] Recvfrom failed (Bad file descriptor)
=================================================================
==285377==ERROR: AddressSanitizer: heap-use-after-free on address 0x7cd7b7fe5590 at pc 0x0000006a9e18 bp 0x7b97ad4e1d50 sp 0x7b97ad4e1d48
READ of size 4 at 0x7cd7b7fe5590 thread T8
=================================================================
==285377==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 160 byte(s) in 1 object(s) allocated from:
#0 0x0000006a9e17 in gtpv1uReceiver /home/richie/oai/openair3/ocp-gtpu/gtp_itf.cpp:1346
#1 0x7f97b9a28ee5 in asan_thread_start(void*) (/lib64/libasan.so.8+0x28ee5) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
#2 0x7f97b8e7ff53 in start_thread (/lib64/libc.so.6+0x71f53) (BuildId: 48c4b9b1efb1df15da8e787f489128bf31893317)
#3 0x7f97b8f0332b in __clone3 (/lib64/libc.so.6+0xf532b) (BuildId: 48c4b9b1efb1df15da8e787f489128bf31893317)
#0 0x7f97b9ae60cb in memalign (/lib64/libasan.so.8+0xe60cb) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
#1 0x000000471039 in newNotifiedFIFO_elt /home/richie/oai/common/utils/threadPool/notified_fifo.h:75
#2 0x000000471039 in tx_func /home/richie/oai/executables/nr-gnb.c:107
#3 0x000000471039 in L1_tx_thread /home/richie/oai/executables/nr-gnb.c:167
#4 0x7f97b9a28ee5 in asan_thread_start(void*) (/lib64/libasan.so.8+0x28ee5) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
0x7cd7b7fe5590 is located 336 bytes inside of 400-byte region [0x7cd7b7fe5440,0x7cd7b7fe55d0)
freed by thread T0 here:
SUMMARY: AddressSanitizer: 160 byte(s) leaked in 1 allocation(s).
Integration: `2025.w43`
* !3605 Support beam index in OAI 7.2 Fronthaul Interface
* !3709 Fixes for T-Tracer to work with NR-UE
* !3712 Restore UE Capability IE after RRCReestablishment
* !3716 Remove unused ULSCH measurements at gNB
* !3603 UE symbol based PDCCH receiver
* !3708 Add monolithic N2 handover test pipeline with B210 and Quectel
* !3719 Remove Benetel-specific radio drivers
* !3710 [CI] Update the Push to DockerHub Stage
* !3711 CI: Multiple adjustments
* !3717 Initialize NCC=0 on NGAP Initial Context Setup (3GPP TS 33.501 §6.9.2.1.1)
* !3720 fix direct bugs of not used RU_RX_SLOT_DEPTH defined constant
* !3714 Improve handling of selection of RSRP/SINR report via configuration file
* !3519 Refactor SDAP adaptation work for QoS
* !3698 Other CSI measurement fixes
* !3699 Updates for Feature Set
Closes#1008
See merge request oai/openairinterface5g!3713
Other CSI measurement fixes
Errors fixed in this MR:
- UE currently sends empty CSI measurement report resulting in invalid
cqi_idx 0, default to MCS 9 at gNB because mismanagement of new L1
measurement structure at MAC UE
- nrofReportedRS not updated after UE capability reception at gNB
- multiple RSRP reports multiplexed / de-multiplexed in wrong order
Refactor SDAP adaptation work for QoS
This MR is an adaptation of the code introduced in !2703.
The goal is a cleanup and functional refactor of the SDAP/PDCP
integration, that is:
- centralize SDAP configuration logic
- simplify entity creation
- improve robustness of role-based SDAP handling
- prepare the codebase for clean support of DRB reconfiguration and
teardown flows
More concretely:
1. New sdap_config_t and get_sdap_Config()
- Introduced an internal struct sdap_config_t to abstract SDAP config
input
- Centralized SDAP config parsing into new get_sdap_Config() function
that translates ASN.1 NR_SDAP_Config into this internal
representation. This is called during RRC triggered
(re)configuration procedures.
- Enable mapping of number of QoS flows > 1
2. Unified role handling with bitmasks
- Added a bitmask-based entity_role field to track SDAP directions:
SDAP_UL_RX, SDAP_UL_TX, SDAP_DL_RX, SDAP_DL_TX: header presence was
determined by simple direction (UE vs gNB) and individual
is_sdap_rx/tx() checks, however nr_sdap_rx_entity behaves
differently depending on the direction of the RX entity (DL/UL),
therefore this change can help enable a more accurate SDAP header
handling across directions and node types.
- Replaces old helpers is_sdap_rx() / is_sdap_tx() with internal
checks against the role bitfield
- QFI-to-DRB mapping is now annotated with direction for both data and
control PDUs
3. Simplified DRB and SDAP setup
- add_drb() in PDCP API now delegates SDAP config processing cleanly
- new_nr_sdap_entity() is used consistently to register a fresh SDAP
context for the UE and PDU session.
- Also, re-use and reconfigure existing SDAP entity if already
exists.
- logging has been added to trace mapped QFIs from RRC and resulting
table entries
4. Improved QFI-to-DRB management
- Refactored nr_sdap_qfi2drb_map_update() to register QFIs based on
parsed config
- Ensures control PDUs are correctly routed even after reconfiguration
- Extended nr_sdap_ue_qfi2drb_config: perform UL QoS flow to DRB
mapping configuration for a SDAP entity has already been established
according to TS 37.324, 5.3 QoS flow to DRB Mapping, 5.3.1
Configuration Procedures. Handle both UL QoS Flows mapping rules to
add and to remove. QFIs will now be properly unmapped if specified
via mappedQoS_FlowsToRelease, this might prevent stale QFI mappings
from being used incorrectly.
- nr_sdap_qfi2drb() and sdap_map_ctrl_pdu() now strictly fallback to
default_drb only if a QFI mapping is missing. Missing default DRB
now triggers LOG_E() (previously silent or misrouted to DRB 0).
5. Other cleanup
- Remove dependencies from legacy rb_id_t
Improve handling of selection of RSRP/SINR report via configuration file
In current develop, the selection of SSB or CRI RSRP depends on the
do_CSIRS flag being activated. That's not wanted. CRI report for now it
is never handled, while we need SSB RSRP report for beam switching
regardless of CSI-RS configuration.
This commit refactors the SDAP entity QoS flow to DRB mapping functionality
to improve code organization and enhance maintainability.
Key changes:
- Split nr_sdap_qfi2drb_map_update into focused functions:
* nr_sdap_add_qos_flows_to_drb: handles QFI addition to DRB
* nr_sdap_rm_qos_flows_from_drb: handles QFI removal from DRB
* nr_sdap_ue_control_pdu_config: handles UE control PDU generation
- Consolidate add/modify logic into reusable nr_sdap_addmod_entity function
- Remove entity existence checking and updating from new_nr_sdap_entity:
this function should only add SDAP entities
- Improve function separation of concerns: do SDAP entity add or update
separately and improve modularity by splitting operations in self
contained functions
- At SDAP creation, do only add of QFI to DRB mapping
- rename new_nr_sdap_entity to nr_sdap_add_entity for function naming consinstency
- Remove rb_id parameter from nr_sdap_tx_entity() function signature
- Update tx_entity function pointer
- Remove rb_id parameter from sdap_data_req() function signature
- Remove unused rb_id variable from sdap_tun_read_thread
The rb_id parameter was redundant since SDAP determines DRB ID
from QFI mapping via entity->qfi2drb_map(entity, qfi). This
simplifies the interface.
Each QFI should always be mapped to a DRB. If that is not the case, we
have an undefined behavior. This should not occur. This commit prints
an error in tx_entity and returns.
The TX/RX entity should have different behavior according to
5.2.1, 5.2.2, 3GPP TS 37.324, depending on whether it is UL and DL.
The gNB can play a role both as UL RX entity and DL TX entity, while
the UE can play a role both as UL TX entity and DL RX entity.
The goal of this commit is to extend the information stored in the
SDAP entity as the current code is just marking the entity as TX/RX.
The commit introduces a bitmap to store the role of the
entity, which can be DL RX, DL TX, UL RX and UL TX. Based on this
the TX SDAP entity knows whether a DL/UL PDU should be build, and
the RX SDAP entity knows whether a DL/UL PDU should be processed.
See also Figure 4.2.2-1.
SDAP headers are present only if enable_sdap option is used.
nr_sdap_qfi2drb_map_update function pointer should
process QFIs to add and release from the entity mapping, therefore
a new function pointer for QFIs to add was introduced and
the function pointer to release the QFIs was called in the same function.
Now the nr_sdap_qfi2drb_map_update is:
(1) looping through the QFIs to add/update and store in the qfi2drb_table
(2) looping through the QFIs to release and delete from qfi2drb_table
Also:
* Update the function signature to use sdap_config_t and nr_sdap_entity_t
* log error when the update fails
* limit the scope of the function
* clang-formatted
* removed limit on table entries set by AVLBL_DRB, replaced with MAX_DRBS_PER_UE
The function nr_sdap_ue_qfi2drb_config should do UL QoS flow to DRB mapping configuration
for a SDAP entity has already been established according to TS 37.324, 5.3 QoS flow to
DRB Mapping, 5.3.1 Configuration Procedures. It should handle both mapping rules to add and to remove.
To this purpose:
* Simplify function signature by passing the sdap config.
* Improve readability of the function.
* Move handling of sdap.mappedQFIs2ReleaseCount (in nr_reconfigure_sdap_entity)
inside the function.
* Simplify end-marker control PDU mapping function by removing unused
DRB ID input parameter (the function is fetching the DRB ID based on the input
map type)
* use int instead of legacy rb_id_t
* limit scope of functions whenever necessary
The goal of this function is to return the DRB ID mapped to the input QFI, for both DL and UL.
The function looks up the DRB that is mapped to the QFI, if no mapping rule exists
returns the default DRB. Returns 0 If no mapping and no default DRB exists for that QFI
The function should not update the stored mapping rules, that is done when receiving
a new SDAP configuration. In this function it was removed.
See TS 37.324, 5.2.1 Uplink
> If there is no stored QoS flow to DRB mapping rule for the QoS flow as specified in the subclause 5.3,
> map the SDAP SDU to the default DRB else, map the SDAP SDU to the DRB according to the stored QoS flow to DRB mapping rule.
* change function signature: pass the sdap_config_t
* update qfi2drb mapping when receiving a configuration for an already existing SDAP entity
* always update mapping rules, not only for default DRB
* use get_sdap_Config to process sdap_Config
* move SDAP config logic to the scope where it is relevant
* add SDAP entity direcly in RRC, not from PDCP
* replaced nr_pdcp_add_drbs with single add_drb call: it was no longer
efficient to keep it in the new logic. The addMod list can be looped directly in RRC.
* add specific function to add bearers from addMod list in E1, NSA, and UE
fix direct bugs of not used RU_RX_SLOT_DEPTH defined constant
with this commit, the gNB can work if we change RU_RX_SLOT_DEPTH to
another value than 4 but it remain not well designed
Initialize NCC=0 on NGAP Initial Context Setup (3GPP TS 33.501 §6.9.2.1.1)
The nhcc should be initialized to 0 upon Initial Context Setup.
Also, remove unused kgnb_ncc: nh_ncc is already there.
Closes#1008
[CI] Update the Push to DockerHub Stage
This MR addresses two cases:
1. Error Handling: Ensures subsequent Image Test Processes stages
continue to run even if the preceding Push to DockerHub stage fails
(applies when the condition is PUSH event and doBuild is true).
2. Introduces conditional logic to correctly handle multi-architecture
images: Images built for both AMD64 and Jetson ARMv8 (oai-gnb,
oai-nr-ue, oai-nr-cuup) use docker buildx imagetools for push to
DockerHub.
All other AMD64 images are pushed using standard Docker commands.
Related MR !3691
Add monolithic N2 handover test pipeline with B210 and Quectel
The goal of this MR is to provide an automated end-to-end N2 HO
validation with real RF (B210) and Quectel UE.
During the testing phase a post-HO assertion failure due to
uninitialized selected_plmn_identity was found: this was also fixed.
CI: Add monolithic N2 handover test pipeline (B210 + Quectel)
- New XML pipeline for N2 HO testing
- Docker Compose for two monolithic gNBs (gNB1/gNB2)
- Handover sequence: gNB1 → gNB2 → gNB1 with 5s controlled attenuation
(RC4DAT).
- Channel mapping: ch1-2 gNB1, ch3-4 gNB2
- Telnet server enabled for CI commands
- Clean-up/reset of attenuator state included
NGAP
- fix PLMN/cell location for Initial UE and Uplink NAS
- Prevents assertion in ngap_gNB_nas_uplink() due to uninitialized
selected_plmn_identity
- Initial UE Message: pass UE-selected PLMN and NR cell ID from RRC to
NGAP
- Uplink NAS Transport: use PLMN, TAC, and cell ID from the message
- Build NR CGI as gNB ID + cell ID
- Store UE-selected PLMN only in RRC UE context (for later NAS); stop
storing PLMN in NGAP UE context.
- PLMN validation when processing handover requests from the source gNB:
when PLMN validation fails, the target gNB now properly sends
NGAP_HANDOVER_FAILURE
- Store serving PLMN for later use in UE context
UE symbol based PDCCH receiver
This is a partial rebase/rewrite of !2895
The goal of this MR is to check how we can merge this.
The eventual result is stated in !2895. The way forward is to modify UE
RX procedures to work symbol by symbol by extracting the symbol loop out
of RX procedures. After all channels are modified this way, the main
thread can be modified to work symbol by symbol.
At this point only PDCCH was modified.
This change is needed due to the previous addition of the function nfapi_stop_l1() in gnb_config.c which in turn calls 2 functions that do not exist in the simulators, since they're not linked against the nfapi libraries
This implements the STOP.request/indication for all 3 transport mechanisms, the VNF will send the STOP.request to the PNF, indicating it will disconnect, and await a STOP.indication from the PNF
The WLS VNF is reworked to be able to start before the PNF, by calling call rte_eal_init and rte_dev_probe to determine if dpdk has been initialized properly, before calling rte_eal_init in the intended process when it is appropriate to do so
The WLS VNF is reworked to be able to start before the PNF, by calling call rte_eal_init and rte_dev_probe to determine if dpdk has been initialized properly, before calling rte_eal_init in the intended process when it is appropriate to do so
- Push both AMD64 & ARMv8 Jetson images together for images built on both using `docker buildx imagetools`
- Use standard 'docker pull and push' for images built only on AMD64.
This allows access to the VNF configuration in the various transport mechanisms straight from config, without this, the transport specific thread would cause a segmentation fault when trying to access the pack/unpack function pointers.
Add 2 functions to access the P5 and P7 VNF structures, to avoid having to always cast user_data and p7_vnfs
Prevent assertion in ngap_gNB_nas_uplink() due to uninitialized selected_plmn_identity:
the selected_plmn_identity field was not being set during N2 handover,
causing the assertion ((plmn->mnc_digit_length == 3) || (plmn->mnc_digit_length == 2))
to fail when processing subsequent NAS messages. The issue is that the Serving PLMN
is not stored by RRC. During N2 mobility, RRC can get this info from GUAMI.
When receiving the Handover Request the target gNB knows from GUAMI
which serving PLMN is the AMF belonging to. In current design, allowed PLMNs
are stored in rrc.configuration. The incoming PLMN needs to be validate
against the PLMNs in the list, then stored in the UE context as Serving PLMN.
This change adds PLMN validation when processing handover requests from the source gNB.
The validation is needed because:
- Target gNB must verify that the PLMN from the GUAMI in the handover request
is allowed by its configuration before accepting the handover to prevent handover
to unsupported PLMNs.
- When PLMN validation fails, the target gNB now properly sends NGAP_HANDOVER_FAILURE
- UE Context must store serving PLMN for later use
This commit is removing the storage of selected PLMN in NGAP UE context.
We store the Serving PLMN in the RRC UE context instead.
The Selected PLMN is the PLMN that the UE chose (or was directed to) for registration
and it is sent in the RRCSetupComplete. This is different from the selected
PLMN mentioned in the NG INITIAL UE MESSAGE for network sharing.
Selected PLMN: determines which core network and AMF the UE is registered with
GUAMI = Identifies the serving AMF and includes the PLMN of that AMF
Serving PLMN: the PLMN that is currently serving the UE (e.g. contained in GUAMI)
The AMF’s PLMN may match the selected PLMN, or not (especially in network sharing or roaming).
Regardless, the UE always have a Serving PLMN.
Initial UE message does not have a TAI IE per se, but TAI is a mandatory
member of the mandatory UserLocationInformation CHOICE.
NR CGI is also mandatory and carried inside UserLocationInformation:
in network sharing, the PLMN ID in TAI takes on additional
significance: RAN is shared but CN are different, so in this case PLMN in TAI is
needed for the AMF route the message to the correct operator’s core.
If network sharing applies (e.g., shared RAN between PLMN-A and PLMN-B):
the UE or network may select PLMN-B instead, and that PLMN identity
is included in the Initial UE Message’s TAI IE.
Conclusion:
1) UE always sends the selected PLMN during the registration,
regardless of whether it is shared or not.
2) Selected PLMN Identity is an actual IE sent in the RRCSetupComplete
while in NGAP there's no Selected PLMN Identity IE, only PLMN Identity
IEs in both TAI and NR CGI. It is a subtle difference.
3) The serving PLMN of the UE needs to be stored in RRC UE Context for
later use in NAS procedures. e.g. at initial registration it matches
the Selected PLMN
4) No need to store PLMN in NGAP UE Context, params are passed by RRC
5) TAI and NR CGI, which contain the PLMN identity, are mandatory in
UserLocationInformation IE CHOICE, and should reflect current status
Changes
- Initial UE Message: pass UE-selected PLMN and NR cell id from RRC to NGAP
- Uplink NAS Transport: use PLMN, TAC, and cell id provided by the message;
- Build NR CGI from gNB ID + cell id
- Store UE-selected PLMN only in RRC UE context at NAS_FIRST_REQ for later
Uplink NAS, stop storing PLMN in NGAP UE context
- Add XML pipeline for N2 handover testing
- Add Docker compose for two monolithic gNBs
- Features:
* Two monolithic gNBs (gNB1, gNB2) with proper CU+DU parameters
* Gradual attenuation control using RC4DAT attenuator (5s duration)
* N2 handover sequence: gNB1 → gNB2 → gNB1
* Proper channel mapping: ch1-2 for gNB1, ch3-4 for gNB2
* Telnet server configuration for CI commands
* Handover-specific neighbor configuration
* Clean test state management with attenuator reset
Update based on !3645
Note: For some test configurations we still need to provide
ra_ResponseWindow, for more details, check commit message of
41d14b571c
1. Refactor PDCCH PHY functions to take rxdataF of one OFDM symbol and
produce LLR for each search space. The modified functions take
rxdataF in a different format than that produced by nr_slot_fep(). So
for now a memcpy is used to change the array structure. Once
nr_slot_fep() is modified, this memcpy will no longer be needed and
will be removed.
2. Modify DCI functions to decode DCI in the last PDCCH symbol and
inidcate to MAC once.
3. Fix PDCCH monitoring for start symbol > 0.
4. Fix multiple PDCCH monitoring within slot.
Co-authored-by: Sakthivel Velumani <mail@sakthi.me>
1.Create new funtion nr_symbol_fep() to do OFDM demod of one symbol on
all antennas. This is called by nr_slot_fep() for now. In the
upcoming MR, this function will be called directly after reading
each OFDM symbol from the radio.
2.Removed redundant memory alignment. DFT function performs memory
alignment if the input memory is not aligned.
Fixes for T-Tracer to work with NR-UE
Fixes to align NR UE events with their definitions in T_messages.txt and
match the expected format in the tracer GUI parser.
Also fixes DL SNR to work in tracer GUI.
Support beam index in OAI 7.2 Fronthaul Interface
This branch supports beam index in OAI 7.2 Fronthaul Interface.
- For CP DL (PDSCH), nBeamIndex of the corresponding prbMapElm is set
when sending IQ data in oran_fh_if4p5_south_out. nBeamIndex of the
corresponding prbMapElm is set when sending IQ data in
oran_fh_if4p5_south_out.
- For CP UL (PUSCH and PRACH), nBeamIndex of the corresponding prbMapElm
is set in oran_fh_if4p5_south_out.
In addition, it fixes a couple of issues
- XRAN hardcodes nBeamIndex of PRACH to zero. Modify XRAN to support
setting of nBeamIndex of PRACH and update xran F release patch.
- Fix the bug in calculating fh_config->neAxc where num_beams_period is
multiplified twice
Testing methodology: Use Benetel O_RU for testing even though it does
not support beamforming. With successful registration and data transfer,
one could check the pcap on the fronthaul interface to see if CP packets
are with the right beam index.
Results:
1. Verified that CP-packets for SSB, DCI, PDSCH, PRACH, PDSCH, PUSCH,
CSI-RS and SRS are with the right beam index
2. Verified that there is no side-effect on Benetel O_RU. UE could
register properly.
3. Verified 4 SSB with ssb_PositionsInBurst_Bitmap = 85. Could see SSB
and PRACH with 4 different indices.
Handle CP UL packet at xran_fx_tx_send_slot() instead of
xran_fh_rx_read_slot(), as the latter would set this information too
late (on reception on samples, but it needs to be filled in the CP
packet prior to reception).
Initialize ru_info structure with beam information, and set beams on TX
direction. Initialize the number of antennas for both RX/TX in both
cases for completeness.
By configuring the Jenkins pythonExecutor to match the test machine, we can use
localhost as the node for running individual test cases. This change makes it
easy to move tests across machines, as the only adjustment needed is updating
the pythonExecutor in Jenkins.
By configuring the Jenkins pythonExecutor to match the test machine, we can use
localhost as the node for running individual test cases. This change makes it
easy to move tests across machines, as the only adjustment needed is updating
the pythonExecutor in Jenkins.
By configuring the Jenkins pythonExecutor to match the test machine, we can use
localhost as the node for running individual test cases. This change makes it
easy to move tests across machines, as the only adjustment needed is updating
the pythonExecutor in Jenkins.
1. Fix UE_PHY_PDSCH_IQ event
2. Fix UE_PHY_PDCCH_ENERGY event
3. Fix UE_PHY_PDSCH_ENERGY event
4. Fix UE_PHY_MEAS event
All fixes align NR UE events with their definitions in T_messages.txt and match the expected format in the tracer GUI parser.
Integration `2025.w42`
* !3623 Optimization of PDSCH precoding operation
* !3691 \[CI\] Ensure multi-arch DockerHub Push after successful image build
* !3696 asn1c doesn't follow c99 variables alias rules, it needs to be compiled this...
* !3685 Assign antenna ports correctly for 1 and 2 layers for aerial.
* !3495 Type0 PDSCH frequency allocation at L1 UE
* !3686 Remove NR L2 simulator code from UE
* !3693 Remove B200-specific clock-rate setting
* !3701 OAI UE: add shared RSRP Table 10.1.6.1-1 mapping function to helpers and adopt it RRC UE
* !3662 RRC UE file cleanup
* update doc/README.md
* !3608 use common scale channel functions for DLSCH and ULSCH
* !3694 fix non initialized DMRS port value in case of DCI00 at UE
* !3702 Extend F1 rfsim CI test
* !3704 remove unused global queues, dead code
* !3673 CI: Aerial: Add an UL-heavy pipeline test
* !3651 CI: Upgrade HO setup to use an attenuator
* !3695 CI: Upgrade Aerial setup to 25-2.1
Closes#940
See merge request oai/openairinterface5g!3700
CI: Upgrade Aerial setup to 25-2.1
The purpose of this MR is to upgrade the cuBB image in the Aerial setup to
release 25-2.1 and update the doc/Aerial_FAPI_Split_Tutorial.md accordingly.
CI: Upgrade HO setup to use an attenuator
The goal of this MR is to upgrade HO CI setup to include a digital attenuator
that will allow us to trigger handover by attenuating the signals on the DUs.
Doing this before using set_master_clock_rate() on the B200 seems to
invalidate synchronization setting.
[HW] USRP clock set to 1759836386.000000 sec
[...]
[HW] current pps at 3.286750, starting streaming at 4.286750
In other words, the current time setting was reset. With this change
now, we see
[HW] USRP clock set to 1759929873.000000 sec
[...]
[HW] current pps at 1759929873.000000, starting streaming at 1759929874.000000
This is because changing clock sources (I assume setting the master
clock rate impacts the clock) can result in changing the time. From the
documentation of [1]:
> Note: When changing clock sources, a previously set time will most
> likely be lost. It is recommended to set the time after changing the
> clock source. Otherwise, an unexpected time may line up with future PPS
> edges.
[1] https://files.ettus.com/manual/classuhd_1_1usrp_1_1multi__usrp.html#a99254abfa5259b70a020e667eee619b9
- main.py: replace %%workspace%% with CONTAINERS.eNBSourceCodePath in Custom_Command and Custom_Script
Co-authored-by: Guido Casati <hello@guidocasati.com>
- Add band mismatch check in valid_du_in_neighbour_configs function
- Ensures neighbor cell band matches serving cell band
- Prevents invalid neighbor configurations for handover
The code only checked that Msg3 would be scheduled during UL, but in
some combinations, e.g., with DSUUU, the current slot can very well be
UL as well => we would schedule DCI in UL slot.
Update cuBB image to cubb-build:25-2.1_srs-ul-heavy (release 25-2.1 with
changes in the L1 config to test heavy ul)
Co-authored-by: Reem Bahsoun <reem.bahsoun@openairinterface.org>
fix non initialized DMRS port value in case of DCI00 at UE
When transmitted PUSCH is neither scheduled by DCI format 0_1 with CRC
scrambled by C-RNTI, CS-RNTI, SP-CSI-RNTI or MCS-C-RNTI, nor
corresponding to a configured grant, the UE shall use [...] DM-RS port
0.
In UE code it was not set in case of DCI00 and that was leading to ULSCH
failures in some scenarios.
- Trigger handover
- IdleSleep 2s
- Ping ext-dn from NR-UE
- Verify UE(1) connected to DU-PCI1
Validate absence of heap-use-after-free ASAN error found in !3600.
Closes#940
OAI UE: add shared RSRP Table 10.1.6.1-1 mapping function to helpers and adopt
it RRC UE
- Add to common/utils/nr/nr_common remove from NR_MAC_UE/nr_ue_procedures.c
- Adopt in asn1_msg.c for MeasurementReport: this solves the following possible
assert:
Assertion (enc_rval.encoded > 0) failed!
In do_nrMeasurementReport_SA() /oai-ran/openair2/RRC/NR/MESSAGES/asn1_msg.c:898
ASN1 message encoding failed (MeasResultServMOList, 18446744073709551615)!
Motivation: unify RSRP-to-index mapping across layers and fix NR RRC
MeasurementReport encoding failures due to out-of-range values by reusing the
validated mapping.
Note: NR_RSRP-Range.c constraint: /* (0..127) */
Also refactored MeasurementReport to improve the code.
Remove B200-specific clock-rate setting
Avoid this clock-rate setting, as we already do it around usrp_lib.cpp:1121, so
it is superfluous. For instance, we also do not set a master clock rate for N3xx
either. This also enables us to synchronize B200 for handover settings,
e.g., for !3651.
See the commit message for more information about synchronization.
- Simplify do_nrMeasurementReport_SA API (encoder allocates local report)
- Adopt asn1cCalloc consistently
- Minor init cleanup for UL_DCCH message struct
- Add to common/utils/nr/nr_common remove from NR_MAC_UE/nr_ue_procedures.c
- Adopt in asn1_msg.c for MeasurementReport: this solves the following assert:
Assertion (enc_rval.encoded > 0) failed!
In do_nrMeasurementReport_SA() /oai-ran/openair2/RRC/NR/MESSAGES/asn1_msg.c:898
ASN1 message encoding failed (MeasResultServMOList, 18446744073709551615)!
Motivation: unify RSRP-to-index mapping across layers and fix NR RRC MeasurementReport
encoding failures due to out-of-range values by reusing the validated mapping.
Note NR_RSRP-Range.c constraint:
{ APC_CONSTRAINED, 7, 7, 0, 127 } /* (0..127) */
Remove NR L2 simulator code from UE
This MR removes NR (SA and NSA) L2 simulator from the codebase. The code, at
least at the UE side, was done at a time where there was no clear L2/L1 split
leading to a complex implementation that never worked as expected. The L2
simulator has been broken and removed from testing for long time and, once it
needs to be revived, it would require a complete new implementation.
Assign antenna ports correctly for 1 and 2 layers for aerial.
With this change aerial successfully decodes PUSCH with 2 UL layers.
The code should use sched_pusch->dmrs.num_dmrs_cdm_grps_no_data == 1 rather
than NFAPI_MODE != NFAPI_MODE_AERIAL, but that will make the changes a bit
more extensive.
Prior to this change, sending antenna_ports.val = 2 with rank 2 would tell
the UE to transmit on DMRS ports 2,3 rather than 0,1 causing it to not decode.
[CI] Ensure multi-arch DockerHub Push after successful image build
This merge request improves the CI script to ensure that the DockerHub-Push
stage executes whenever:
- All Image Build stages succeed &
- doBuild is true &
- The event is a PUSH
This behavior ensures that Docker images are published whenever the image build
stages succeed, regardless of any failures in the Image Test stages.
Jetson ARM64/V8 and AMD64 images will now be published on DockerHub under the
same tag (develop or WEEK_TAG) to provide multi-architecture images.
Optimization of PDSCH precoding operation
x86/aarch64 optimizations for precoding, more complete timing reporting in
nr_dlsim. Timing report in nr_dlsim now shows the total PDSCH generation time
and is broken down into Layer mapping, resource mapping and precoding.
The optimizations for x86 are basically reorganizing loops (for AVX512,AVX2,
NEON but not SSE2) to minimize repetitive instructions when formatting of the
precoder weights, and creation of inline functions for complex multiply-add.
AVX512 optimization was added. requiring AVX512BW. Detection of up to 4 PRBs
with common PMI for efficiency with AVX512 (was 2 in develop for AVX2).
For aarch64, native coding of the precoder to avoid inefficient SIMDe
translations for this operation.
nr_dlsim now uses default precoding indices depending on the scenario instead
of 0 which doesn't do precoding at all.
See merge request description for nr_dlsim test results.
- On PUSH events, if image build stages succeed, trigger DockerHub push stage
- Build the images, then trigger the Push to DockerHub stage
- Publish Jetson (ARM64/v8) and AMD64 images under the same tag on DockerHub
Doing this before using set_master_clock_rate() on the B200 seems to
invalidate clock settings:
[HW] USRP clock set to 1759836386.000000 sec
[...]
[HW] current pps at 3.286750, starting streaming at 4.286750
In other words, the current time setting was reset. With this change
now, we see
[HW] USRP clock set to 1759929873.000000 sec
[...]
[HW] current pps at 1759929873.000000, starting streaming at 1759929874.000000
This is because changing clock sources (I assume setting the master
clock rate impacts the clock) can result in changing the time. From the
documentation of set_time_next_pps() [1]:
> Note: When changing clock sources, a previously set time will most
> likely be lost. It is recommended to set the time after changing the
> clock source. Otherwise, an unexpected time may line up with future PPS
> edges.
[1] https://files.ettus.com/manual/classuhd_1_1usrp_1_1multi__usrp.html#a75b1c5375549e6a446d686ee7d9b4e14
The next commit introduces an "UL-heavy" configuration to be tested with
Aerial. To avoid waiting for the CN, start&stop it once at the beginning
of the CI run.
Reduce throughput requirement, as this fails once two DUs are connected
to a UE, which creates more load on the machine and frequently fails
with low throughput.
CI: Enable Physim threshold check for tests on Caracal and GH
This MR adds support for configurable timing threshold files in PhySim
tests.
- Introduces a new CMake cache variable PHYSIM_CHECK_FILES to specify
one or more timing threshold files (semicolon-separated).
- Enables optional enforcement of timing thresholds check in PhySim
tests without changing existing test definitions.
- Defines timing thresholds for LDPC encoding/decoding in nr_ulsim,
nr_dlsim and ldpctest on Caracal and GH machines.
SRS noise power
This MR implements the calculation of the noise power based on SRS in a
different way, and check whether SNR is more accurate or not. This MR is
built on top of the MR: !3460
A graph was added in T_Tracer to observe UL-SNR calculated using SRS.
See merge request description for measurement results.
Replace the previous add_timed_physim_test() macro with add_physim_test()
to use a single, unified function for defining physim tests. This simplifies
the test configuration and removes redundant macro definitions while keeping
all existing functionality.
This change follows up on the earlier addition of support for including
custom timing threshold files (PHYSIM_CHECK_FILES).
Update existing tests accordingly.
Add missing timinig analysis scripts to RHEL9 physim docker image. These files
are now copied from the build stage to /oai-ran/openair1/SIMULATION/tests/,
where they are expected by ctest.
Resolves following issue when running ctest in docker container:
CMake Error: Error processing file: /oai-ran/openair1/SIMULATION/tests/RunTimedTest.cmake
For some physical simulators, we have multiple SNR iterations.
The previous version of the script correctly retained only the last
measurement, but if a previous measurement condition set RC=1, the
script would fail although the final "good" run might fulfil the
measurement condition (IOW, it would show SUCCESS, but still fail on the
check).
Instead, check if all measurement lines finish on SUCCESS, which handles
the above case.
The awk script in analyze-timing.sh used syntax that works with gawk but fails
on systems where mawk is the default implementation, producing errors such as:
awk: /dev/fd/3: line 6: syntax error at or near ,
-- test command finished with SIGPIPE
Concretely, the match(text, pattern, variable) function does not exist
in mawk, as it cannot capture matches in variables. Work around by
substituing strings, and force a numeric comparison.
Fixes to prevent assertion due to 0 PRB allocation
Assertion (NPRB>0 && (NPRB + RBstart <= BWPsize)) failed!
In PRBalloc_to_locationandbandwidth0() /home/user/openairinterface5g/common/utils/nr/nr_common.c:506
Illegal NPRB/RBstart Configuration (0,51) for BWPsize 51
Probably caused by missing safeguards to prevent computing TBS with 0 PRB
as input.
Fix OAI UE memory leaks
Fix 1: Replaced asn1cFreeStruc with ASN_STRUCT_FREE in MAC layer to properly
free nested ASN.1 structures in cell group configuration.
Fix 2: Removed premature nullification of dedicatedNAS_Message->buf in
dlInformationTransfer processing to allow proper ASN.1 cleanup.
Fix 3: Fixed memory ownership in nr_rrc_process_dedicatedNAS_MessageList by
copying OCTET_STRING data instead of transferring ownership, preventing
ASN.1 cleanup from losing track of allocated memory
Closes#828
fix RSRP computation at UE
Conflicts between !3595 (merged) and !3596 (merged) leading to double conversion
of RSRP into index in L1 and L2. With this fix it is only converted in L2.
Replace int16 min when obvious
INT16_MIN doesn't have a opposite value on 16 bits, so SIMD abs (absolute()), or
simple C operations doesn't make the expected result.
example:
(gdb) p (short)-(short)-32768
$4 = -32768
(gdb)
This MR replaces constants INT16_MIN by -INT16_MAX (so -32767) in places where
it used for mathematical operations. This is not perfect, nevertheless reduces
overflow probability.
We saw in some places a dirty case: code do first calls to _mm_adds_epi16
(or subs), so because of the saturated operations, the probability to reach
32767 and -32768 is higher than the other numbers but, _mm_abs_epi16(), or
negate operations (conjugate) can follow, that is making strong error as
abs(-32768)=-32768
Also, don't use "set -x" debugging for oc login command:
ci-scripts/cls_cmd.py:242 sets BASH_XTRACEFD=1, which makes that all
"set -x" output is in stdout, leading to a redirect to the file into
which we redirect. This would lead to the following error with
unsuccessfull oc login:
error: You are not a member of project "****-core-for-ci-ran".
Error from server (Forbidden): imagestreams.image.openshift.io "oai-physim"
is forbidden: User "system:anonymous" cannot get resource "imagestreams" in
API group "image.openshift.io" in the namespace "****-ran"
This fixes basically two problems. First, remove "set -e", which leads
to the script exiting on error. For instance, there was the sleep which
should account for the time of the pod being in "ContainerCreating", but
might not be enough. In that case, the script would exit, leaving the
pod deployed.
Second, a fixed time is not good, as it can be too short and unduly
prolong waiting time. Replace with a loop.
- Remove unnecessary NULL assignment for dedicatedNAS_Message->buf
- The original buffer is copied and transfered to NAS, so it can be properly freed by ASN.1 structure cleanup
Root cause: Code was nullifying dedicatedNAS_Message->buf pointer before ASN.1 cleanup could free the original allocation, causing the leak from OCTET_STRING_decode_uper.
AddressSanitizer leak trace (FIXED):
Direct leak of 119 byte(s) in 3 object(s) allocated from:
/#0 0x7ec2a42b4c38 in __interceptor_realloc
/#1 0x555fade852e0 in OCTET_STRING_decode_uper
/#9 0x555fadb48b11 in nr_rrc_ue_decode_dcch.
The leak was caused by improper memory ownership handling in the
dedicatedNAS_MessageList processing. The function was transferring
buffer ownership to NAS messages and then preventing ASN.1 cleanup
from freeing the original allocations by setting
list.count = 0, causing a memory leak.
Leak trace:
Direct leak of 40 byte(s) in 1 object(s) allocated from:
/#0 0x7f2ce3ab4a57 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
/#1 0x567907083f0f in OCTET_STRING_decode_uper /cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/OCTET_STRING_uper.c:89
/#2 0x5679070ed5e6 in SET_OF_decode_uper /cmake_targets/ran_build/build/openair2/RRC/NR/MESSAGES/constr_SET_OF_uper.c:70
/#3 0x56790707b6dc in SEQUENCE_decode_uper /cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/constr_SEQUENCE_uper.c:118
/#4 0x56790707b6dc in SEQUENCE_decode_uper /cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/constr_SEQUENCE_uper.c:118
/#5 0x56790709a403 in CHOICE_decode_uper /cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/constr_CHOICE_uper.c:84
/#6 0x56790707b6dc in SEQUENCE_decode_uper /cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/constr_SEQUENCE_uper.c:118
/#7 0x56790709a403 in CHOICE_decode_uper /cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/constr_CHOICE_uper.c:84
/#8 0x56790709a403 in CHOICE_decode_uper /cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/constr_CHOICE_uper.c:84
/#9 0x56790707b6dc in SEQUENCE_decode_uper /cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/constr_SEQUENCE_uper.c:118
/#10 0x56790708b5f1 in uper_decode /cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/uper_decoder.c:83
/#11 0x567906d44b4b in nr_rrc_ue_decode_dcch /openair2/RRC/NR_UE/rrc_UE.c:2212
/#12 0x567906d520a3 in rrc_nrue /openair2/RRC/NR_UE/rrc_UE.c:2615
/#13 0x567906d5f77e in rrc_nrue_task /openair2/RRC/NR_UE/rrc_UE.c:2501
/#14 0x7f2ce2494ac2 in start_thread nptl/pthread_create.c:442
Fix:
- Copy OCTET_STRING data instead of transferring ownership
- Allow ASN.1 cleanup to properly free original allocations
This fixes the leak that occurred during rrcReconfiguration
message processing when dedicatedNAS_MessageList was present.
Closes#828
- Replace asn1cFreeStruc with ASN_STRUCT_FREE in MAC layer cleanup
- Fixes improper memory management of NR_CellGroupConfig structures
Root cause: asn1cFreeStruc only calls ASN_STRUCT_RESET + free(), which doesn't properly free nested ASN.1 allocations. ASN_STRUCT_FREE frees all nested structures completely.
AddressSanitizer leak trace:
Direct leak of 288 byte(s) in 1 object(s) allocated from:
/#0 0x7fb72bab4a57 in __interceptor_calloc
/#1 0x593752b28d0d in SEQUENCE_decode_uper
/#2 0x593752b9a546 in SET_OF_decode_uper
/#3 0x593752b2863c in SEQUENCE_decode_uper
/#4 0x593752b47363 in CHOICE_decode_uper
/#5 0x593752b2863c in SEQUENCE_decode_uper
/#6 0x593752b2863c in SEQUENCE_decode_uper
/#7 0x593752b2863c in SEQUENCE_decode_uper
/#8 0x593752b2863c in SEQUENCE_decode_uper
/#9 0x593752b2863c in SEQUENCE_decode_uper
/#10 0x593752b38551 in uper_decode
/#11 0x5937527d859f in nr_rrc_ue_process_masterCellGroup
/#12 0x5937527d9408 in nr_rrc_process_reconfiguration_v1530
/#13 0x5937527dd5bb in nr_rrc_ue_process_rrcReconfiguration
/#14 0x5937527f5e6b in nr_rrc_ue_decode_dcch
/#15 0x5937527ff003 in rrc_nrue
/#16 0x59375280c6de in rrc_nrue_task
Integration: `2025.w40`
* !3672 \[ci\] Fix MissingPropertyException - COTS-UE by binding OAI_Registry globally
* !3609 BWP with no PRACH occasions
* !3657 do not assert for mismatched TBS in phy-test mode
* !3667 CI: Updates for HO and AW2S pipeline
* !3674 NR UE: remove function get_nr_RSRP() and get_nr_rx_total_gain_dB() for cleanup
* !3478 NR UE: add UCI (HARQ-ACK/NACK) on PUSCH support at PHY
* !3664 modulation LUTs size was wrong, and remove inconsistent test of SSE2 enable
* !3665 Make all targets compile
* !3554 Handle failures in RRCReconfiguration encoding gracefully
* !3655 Improvements to N2 handover
* !3678 Add OAIUE longrun pipeline
* !3628 Update documentation
Closes#979, #726, #959, #967, and #930
See merge request oai/openairinterface5g!3676
Add OAIUE longrun pipeline
Add a new XML file for OAIUE longrun.
- Test description:
* 40 MHz BW, n78
* gNB with USRP N310, UE with USRP N310
* CN deployed on OC
- Test duration: 1 hour
- Test scenario: 3x DL 10 min test (20 Mbps) + 3x UL 10 min test (5
Mbps)
pods deployed through helm occasionally take more time, leading to
errors such as
Error from server (BadRequest): container "physim" in pod "oai-physims-4g-sczvl" is waiting to start: ContainerCreating
Give a bit more time before checking the logs. We cannot wait too much,
as the container will just end on FINISHED in running state, so the logs
will always be there.
Make all targets compile
This MR enables us to compile all targets, and does that in one CI test. This
closes#726. Now, this should work:
cd ~/openairinterface5g
mkdir build && cd build
cmake .. -GNinja && ninja
To achieve this, I did the following:
- some targets have been fixed (warnings, errors)
- some targets have been removed when they did not seem to serve a good purpose
(e.g., an almost empty test)
- some targets have been commented (e.g., LTE simulators, some unitary tests)
which we maybe want to revive in the future
- some targets built when just building with ninja, but not all. For instance,
telnetsrv_enb would typically build, but it was missing a dependency. Doing
cmake .. -GNinja && ninja telnetsrv_enb would show this (in develop)
To help with the last bullet point, there is a script compile_targets.sh that
can compile targets independently (and in parallel, to not wait for ages) to
show that targets compile properly compile-targets.patch.
In almost all cases, the problem is that a specific module uses the logging
module, which depends on T, which needs to dynamically create headers. The way
to do this is to have a dependency, and many targets use generate_T or {T_LIB}
({} intentional: T might be absent, so then it evaluates to nothing). However,
not all do this, and those that depend on T actually don't depend on T, but on
the logging module, which in turn depends on T. So in many places, a simple
dependency onto log_headers fixes this problem, and generate_T or {T_LIB}
simplifies the dependency (but not always). The commits should have more info.
Note that at least the targets in FlexRIC do not all compile, at least in the
configuration that we use in docker/Dockerfile.build.ubuntu. So for the latter,
we cannot build with a simple ninja, but FlexRIC seems to be the only one that
does not compile. Since FlexRIC is a separate repository, that needs to be
addressed in the corresponding repository.
Previously, the script attempted to directly merge ${merge}, which could f
ail if the branch was not already available locally. This update explicitly
fetches the branch from origin and then merges FETCH_HEAD with --ff, ensuring
the merge works even when the branch is missing locally.
- Move 'What is a gNB neighbor?' explanation from rrc-usage.md to handover-tutorial.md where it belongs
- Replace generic parameter names with actual configuration parameter names and specific descriptions (e.g. gNB_ID, nr_cellid)
- Add example configuration structure showing proper syntax
- Add missing 'band' parameter that was not listed before
- Provide concrete examples and exact constraints for each parameter
- Cross-reference between documents for better organization
This addresses documentation issues where generic parameter descriptions were
not useful for developers configuring neighbor cells.
- Remove extensive traffic testing before HO (iperf tests 030001, 030002)
- Do 1 ping test after attachment
- Reduce ping packet count from 100 to 50 packets for remaining connectivity test
Time savings: ~2-3 minutes by removing traffic validation overhead
Split monolithic e1_send_bearer_updates into three focused functions:
- e1_send_bearer_updates(): DRB setup from F1 UE Context Modification Response
- e1_request_pdcp_status(): Request PDCP status during inter-CU handover
- e1_notify_pdcp_status(): Notify CU-UP with PDCP status during handover
Extract common helpers:
- append_e1_drb_mod_req(): Common DRB-to-mod for bearer request logic
- e1_send_bearer_modification_request(): Common sending step
Bug fixes:
- Fix loop bounds (i < n instead of i == n)
- Fix array access bounds checking
- Fix DRB ID consistency
Memory management:
- Add missing free_e1ap_context_mod_request calls
- Improve error handling with early returns
In the process:
- Simplify cuup_notify_reestablishment with FOR_EACH_SEQ_ARR loop
- Adopted all callers to use new consolidated functions
Improves maintainability and eliminates complex conditional logic.
Replace field-by-field assignment with struct copy for plmn_identity.
Both source and destination use identical plmn_id_t type, making
this change safe and more maintainable.
- Reduces lines of code
- More readable and less error-prone
- Single memory copy operation instead of multiple field assignments
- ngap_gNB_handover_notify: Fix misleading error message from 'Failed to encode'
to 'Failed to find UE context' for better clarity
- ngap_gNB_handle_ul_ran_status_transfer: Standardize error message format
from 'Could not find' to 'Failed to find' for consistency across functions
This ensures consistent and accurate error reporting across all NGAP handover functions.
- Update encoder functions in ngap_gNB_mobility_management.c to use calloc_or_fail
- Provides zero-initialized memory and consistent error handling
- Prevents uninitialized fields and improves memory safety
Also:
- Update NG Setup Request to use calloc_or_fail
- Replace inefficient 'allocate, extract, free' pattern with direct value extraction
- Remove unused functions get_gap_config_from_smtc() and get_gap_config()
- Add extract_gap_config_from_smtc() that extracts values directly without allocation
- Eliminates use-after-free risk and improves performance
- No allocation overhead, no memory leaks
- Add missing ASN_STRUCT_FREE for NR_MeasGapConfig in create_measgap_config
- Fix 48-byte measurement gap config leak in get_gap_config_from_smtc
AddressSanitizer backtrace:
Direct leak of 48 byte(s) in 1 object(s) allocated from:
/#0 0x7d32adab4a57 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
/#1 0x5751f99cbb79 in calloc_or_fail /home/guido/repo/openairinterface5g/develop/common/utils/utils.h:74
/#2 0x5751f99cbb79 in get_gap_config_from_smtc /home/guido/repo/openairinterface5g/develop/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c:4164
/#3 0x5751f99cbb79 in create_measgap_config /home/guido/repo/openairinterface5g/develop/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c:4310
/#4 0x5751f9964abe in ue_context_setup_request /home/guido/repo/openairinterface5g/develop/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c:709
/#5 0x5751f979e568 in nr_initiate_handover /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB_mobility.c:218
/#6 0x5751f97a637f in nr_rrc_trigger_n2_ho_target /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB_mobility.c:526
/#7 0x5751f9703608 in rrc_gNB_process_e1_bearer_context_setup_resp /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB.c:2641
/#8 0x5751f9706b7b in rrc_gnb_task /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB.c:3020
/#9 0x7d32ac494ac2 in start_thread nptl/pthread_create.c:442
Root cause: create_measgap_config allocated NR_MeasGapConfig via get_gap_config_from_smtc()
but never freed it after extracting the needed values to populate the measgap_config_t
return structure.
- Add missing handover context cleanup in rrc_CU_process_ue_context_release_complete
- Fix 16-byte handover context leak in N2 handover source gNB trigger path
AddressSanitizer backtrace:
Direct leak of 16 byte(s) in 1 object(s) allocated from:
/#0 0x7fee67cb4a57 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
/#1 0x58059e33454b in calloc_or_fail /home/guido/repo/openairinterface5g/develop/common/utils/utils.h:74
/#2 0x58059e33454b in alloc_ho_ctx /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB_mobility.c:47
/#3 0x58059e339e4d in nr_rrc_trigger_n2_ho /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB_mobility.c:556
/#4 0x58059e33ae93 in nr_HO_N2_trigger_telnet /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB_mobility.c:611
Root cause: Handover context allocated in N2 handover source gNB trigger path (nr_rrc_trigger_n2_ho)
for any successful N2 handover but not properly freed in all handover completion scenarios.
The UE context release complete handler was missing cleanup for handover context.
Solution: refactor handover context cleanup
- Move nr_rrc_finalize_ho() call to rrc_delete_ue_data() for centralized cleanup
- Remove redundant nr_rrc_finalize_ho() calls from handover failure paths:
* rrc_CU_process_ue_context_release_request() - UE not deleted yet
* invalidate_du_connections() - UE will be deleted later
- Keep nr_rrc_finalize_ho() calls in handover success paths where UE continues operating
- Ensures handover context is cleaned up exactly once when UE is actually deleted
- Prevents potential double-free and use-after-free issues in handover cleanup
This centralizes all UE data cleanup in rrc_delete_ue_data() and ensures
handover context is properly managed throughout the UE lifecycle and cleaned up
when UE delete happens.
NR UE: add UCI (HARQ-ACK/NACK) on PUSCH support at PHY
Add UCI (HARQ-ACK/NACK) on PUSCH support at nrUE PHY, the multiplexing procedure
can be found in TS 38.212 section 6.2.7.
Verified with 3rd-pary gNB for cases when HARQ payload bits length is 1, 2 or 3.
Closes#959 and #967 .
- Add missing ASN_STRUCT_FREE for NR_MeasurementTimingConfiguration in ue_context_setup_request
- Fix 64-byte MTC sequence leak in get_nr_mtc → SEQUENCE_decode_uper
AddressSanitizer backtrace:
Direct leak of 64 byte(s) in 1 object(s) allocated from:
/#0 0x7dcfcb8b4a57 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
/#1 0x591fcc59b67d in SEQUENCE_decode_uper /home/guido/repo/openairinterface5g/develop/cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/constr_SEQUENCE_uper.c:37
/#2 0x591fcc57eaa1 in uper_decode /home/guido/repo/openairinterface5g/develop/openair2/RRC/LTE/MESSAGES/uper_decoder.c:83
/#3 0x591fcbdbedeb in get_nr_mtc /home/guido/repo/openairinterface5g/develop/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c:4216
/#4 0x591fcbd58188 in ue_context_setup_request /home/guido/repo/openairinterface5g/develop/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c:635
/#5 0x591fcbb92568 in nr_initiate_handover /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB_mobility.c:218
/#6 0x591fcbb9a37f in nr_rrc_trigger_n2_ho_target /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB_mobility.c:526
/#7 0x591fcbaf7608 in rrc_gNB_process_e1_bearer_context_setup_resp /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB.c:2640
/#8 0x591fcbafab7b in rrc_gnb_task /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB.c:3019
/#9 0x7dcfca294ac2 in start_thread nptl/pthread_create.c:442
Root cause: ue_context_setup_request allocated NR_MeasurementTimingConfiguration via
get_nr_mtc() but never freed it after creating the measurement gap configuration.
The create_measgap_config function only reads from the structure and doesn't take
ownership, so the caller must free it.
- Replace heap allocation with stack allocation for seq_arr_t structures
- Use proper seq_arr_free() with free functions for ASN.1 structures
- Remove unnecessary malloc/free calls for sequence containers
- Improve memory safety and performance with automatic cleanup
Fixes 128-byte memory leak:
Direct leak of 128 byte(s) in 2 object(s) allocated from:
/#0 0x7e7f39ab4a57 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
/#1 0x56df8b07312d in SEQUENCE_decode_uper /home/guido/repo/openairinterface5g/develop/cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/constr_SEQUENCE_uper.c:37
/#2 0x56df8b056551 in uper_decode /home/guido/repo/openairinterface5g/develop/cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/uper_decoder.c:83
/#3 0x56df8a896b1b in get_nr_mtc /home/guido/repo/openairinterface5g/develop/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c:4216
/#4 0x56df8a82feb8 in ue_context_setup_request /home/guido/repo/openairinterface5g/develop/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c:635
/#5 0x56df8a66a298 in nr_initiate_handover /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB_mobility.c:218
/#6 0x56df8a6720af in nr_rrc_trigger_n2_ho_target /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB_mobility.c:526
/#7 0x56df8a5cf338 in rrc_gNB_process_e1_bearer_context_setup_resp /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB.c:2633
/#8 0x56df8a5d28ab in rrc_gnb_task /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB.c:3012
/#9 0x7e7f38494ac2 in start_thread nptl/pthread_create.c:442
- Add early check for existing UE context by AMF UE NGAP ID at beginning of rrc_gNB_process_Handover_Request
- Add dedicated function to get UE context by AMF UE NGAP ID: rrc_gNB_get_ue_context_by_amf_ue_ngap_id()
- Send handover failure with appropriate cause if UE context already exists
- Remove redundant ho_context NULL check that could never be true for newly created UE contexts
- Prevents duplicate handover processing and resource leaks
Move UE context creation and storage to after successful PDU encoding
to prevent memory leaks if encoding fails. Also add proper PDU cleanup
when AMF fetch fails and use consistent NULL check style.
This ensures UE context is only stored when the operation is guaranteed
to succeed, improving error handling and memory management.
In the current memory management the caller wasn't responsible for freeing
memory they allocate. The ngap_gNB_encode_pdu function was taking ownership
of PDU contents by calling ASN_STRUCT_FREE_CONTENTS_ONLY, while callers
also expected to manage the same memory. This created unclear ownership semantics and
potential double-free bugs.
- Remove ASN_STRUCT_FREE_CONTENTS_ONLY from ngap_gNB_encode_pdu to prevent double-free
- Remove unnecessary ASN_STRUCT_FREE when encode function returns NULL
- Add proper ASN_STRUCT_FREE cleanup for heap-allocated PDUs in ngap_gNB.c functions
- Add ASN_STRUCT_FREE_CONTENTS_ONLY cleanup for stack-allocated PDUs in NAS and context management functions
- Ensure consistent memory cleanup patterns across all NGAP encoder callers
- Fix potential memory leaks in all ngap_gNB_encode_pdu call sites
This prevents double-free bugs and ensures proper cleanup of ASN.1 structures
in both heap and stack allocation scenarios.
Add check for cu_exists_f1_ue_data() before calling cu_get_f1_ue_data()
to prevent assertion failure when telnet command 'ci fetch_du_by_ue_id'
is used for UEs that have been handed over via N2 (and no longer have
F1 UE data).
This fixes the crash:
Assertion (ret == HASH_TABLE_OK && data != ((void *)0)) failed!
In get_hashtable_data() /oai-ran/openair2/F1AP/f1ap_ids.c:36
element for ue_id 1 not found
The function now returns NULL gracefully when F1 UE data is not available.
Co-authored-by: Guido Casati <hello@guidocasati.com>
- Add proper cleanup of allocated ASN.1 structures in all return paths
- Fix early returns that were leaking NR_HandoverPreparationInformation
- Fix early returns that were leaking NR_RRCReconfiguration
- Add cleanup at end of successful function execution
This prevents memory leaks when processing handover preparation information
during N2 handover procedures.
- Add UE context cleanup before sending handover failure message
- Prevents memory/resource leak when PDU session establishment fails during handover
- UE context was created but never cleaned up on failure path
This fixes a bug where UE contexts would accumulate over time
when handovers failed after context creation.
Since there is no UCI on PUSCH implementation in gNB, it is good to test
UE's implementation with matlab.
This commit allows to test with matlab in two ways:
1. generate OFDM waveform from ulsim and decode it in matlab using
uci_on_pusch_decode.m
2. generate codeword in matlab using uci_on_pusch_encode.m read it in
ulsim and compare the bits. ulsim option -o is used
When the codeword has UCI multiplexed with data, we need to handle UCI scrambling according to 38.211 section 6.3.1.1.
Especially when O_ACK <= 2 there are x and y placeholder bits for UCI.
Get beta offset, alpha scaling and other parameters to calculate rate matching information for UCI on PUSCH,
then use the rate matching info to encode UCI and re-encode PUSCH, call nr_uci_on_pusch to get final multiplexed codeword for scrambling.
NR UE: remove function get_nr_RSRP() and get_nr_rx_total_gain_dB() for cleanup
The function get_nr_RSRP() and get_nr_rx_total_gain_dB() are not used anywhere
in the code, removing for cleanup.
CI: Updates for HO and AW2S pipeline
This MR introduces several CI updates:
- Change center frequency from 3439 MHz (n78) to 4185 MHz (n77) in HO setup to
prevent interference with other lab setups.
- Enable attaching multiple AmariUEs simultaneously in the AW2S pipeline - save
~25s.
- Update RX gain configuration on AmariUE - improve DL throughput.
BWP with no PRACH occasions
This MR includes fixes at gNB and UE in case the current BWP has no PRACH
occasions, i.e. we need to switch to initial BWP.
`def` creates a variable local to the script object, not automatically visible inside helper functions.
This fixes the following exception in Jenkins:
Found unhandled groovy.lang.MissingPropertyException exception:
No such property: OAI_Registry for class: groovy.lang.Binding
These libraries depend on the logging module, so add the right
dependency log_headers. Indirectly, this will fulfill the condition of
T. I consider the prior usage of generate_T or {T_LIB} incorrect,
because basically none of these libraries actually, actively use T, but
rather only the logging module, which pulls in T. The dependency of
log_headers will also take care of generating and including T headers,
which is a dependency of the logging module.
For conf2uedata and related, fulfill the dependency
through conf2uedata_lib (on which the rest depends).
These libraries have no dependencies on UTIL, so it's better to omit it.
However, then the test is missing symbols for the config (which likely,
indirectly came through UTIL -> LOG -> CONFIG_LIB, so add it now onto
the test.
These libraries have an (indirect) dependency on T, either by using the
logging module (which in turn depends on T), or through other includes.
The easiest is to depend on the logging module, which will fulfil also
the T dependency.
It would equally be feasible to use the utils target (which in turn
depends on log_headers), but this would necessitate to compile, and does
not seem to be necessary.
Since E2 agent uses the config library, include it directly. This also
makes the dependency on T obsolete, because
- it is the logging headers that are needed, and
- the T dependency is fulfilled through the log_headers.
It seems that many compilation units include T.h through the config
module (as evidenced when taking out T.h from
config_load_configmodule.h). This is strange, because T.h is only used
in the logging headers. Hence, move it to there, where it is used.
coding_defs.h included defs_common.h, which pulls in many dependencies,
e.g., the logging module, which pulls in T. However, it does not use
anything of this. So remove, and include stdbool.h instead (because bool
is used in coding_defs.h.
nr_polar_defs.h relied on some includes done in coding_defs. Use
includes for pthreads and SIMD to define types that are used in
nr_polar_defs.h.
We don't use JER. This avoids compilation problems, such as:
/usr/bin/ld: openair3/NRPPA/MESSAGES/libasn1_nrppa.a(INTEGER_jer.c.o): in function `INTEGER_decode_jer':
tmp.MtrwVDhQqY/openair3/NRPPA/MESSAGES/INTEGER_jer.c:186:(.text+0x5b8): undefined reference to `jer_decode_primitive
XNAP is asn1c compiled with -no-gen-BER. Correspondingly, no
ber_decoder.h file is created. However, when running cmake followed by
ninja, it notices the absence of this file:
ninja explain: output openair2/XNAP/MESSAGES/ber_decoder.h doesn't exist
which triggers a complete rebuild of XNAP ASN.1. Without this file, the
targets are not marked as dirty.
This constant seems to be an analogon to NUMBER_OF_UE_MAX; replace with
the latter, as it does the same. (NBIoT does not work, anyway)
Fix dependencies of the NB_IoT target so it compiles.
Remove, because
1) it does not compile (the asn1c generated code should be prepend with
LTE_ etc, nobody did that)
2) a shared module makes no sense
3) the configuration is trivial to recreate
Link E2_AGENT libraries directly into nr-softmodem/lte-softmodem instead
of L2/L2_NR/F1AP. Doing that ensures that simulators, e.g.,
nr_dlsim/nr_ulsim do still compile. It also simplifies the code.
Prior to this, compiling nr_ulsim with E2_AGENT, for instance, resulted
in the following errors, fixed in this commit:
FAILED: nr_ulsim
/usr/bin/ld: openair2/E2AP/RAN_FUNCTION/libe2_ran_func_du_cucp_cuup.a(ran_func_rc.c.o): in function `send_aper_ric_ind':
/home/oai/robert/cleanup-t-dependency-cmake/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc.c:643: (.text+0xee6): undefined reference to `async_event_agent_api'
/usr/bin/ld: /home/oai/robert/cleanup-t-dependency-cmake/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc.c:643:(.text+0x11ca): undefined reference to `async_event_agent_api'
/usr/bin/ld: /home/oai/robert/cleanup-t-dependency-cmake/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc.c:643:(.text+0x1485): undefined reference to `async_event_agent_api'
/usr/bin/ld: /home/oai/robert/cleanup-t-dependency-cmake/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc.c:643:(.text+0x159c): undefined reference to `async_event_agent_api'
/usr/bin/ld: /home/oai/robert/cleanup-t-dependency-cmake/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc.c:643:(.text+0x16b1): undefined reference to `async_event_agent_api'
[...]
warning: ‘genericPowerPerAntena’ defined but not used [-Wunused-function]
warning: ‘graph.text’ is used uninitialized [-Wuninitialized]
warning: ignoring return value of ‘read’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
Lower the RX gain used by the Amarisoft UE in CI tests to prevent DL signal
saturation. This resolves an issue with low DL throughput observed in CI.
RX/TX signal levels on the Amarisoft UE can be checked with "t spl" command
in lteue; MAX values should not approach 0.
Data and control multiplexing procedure is defined in 38.212 section 6.2.7.
Step 3 (CSI1 and CSI2 mapping) is not implemented, only HARQ-ACK.
PUSCH frequency hopping is not supported.
Use betaOffset and alpha scaling etc. to get rate matching information of UCI on PUSCH (e.g. max bit capacity of encoded UCI and encoded ULSCH)
according to TS 38.212 section 6.3.2.4 and 6.2.7.
38.212 section 5.3.3.1 and 5.3.3.2 describe how to encode 1-bit and 2-bit information.
This is needed when typically HARQ-ACK will be transmitted on PUSCH.
38.212 section 5.4.3 also describes how to do rate matching for channel coding of small block lengths.
- Replace error handling for impossible ID mismatches with DevAssert statements
- If ngap_get_ue_context() succeeds, returned context must have matching NGAP gNB UE IDs by definition
- This catches potential bugs in the lookup function immediately
- Affects: handover_required, handover_notify, handover_cancel, ul_ran_status_transfer
These checks were logically impossible since we looked up the context using
the same IDs we were then checking for mismatch.
- Fixed incorrect log messages that said 'PCI=%lu' when printing nr_cell_id
- Now prints both NR Cell ID and PCI when DU is found
- Provides better debugging information for handover requests
- Add _E1_EQ_CHECK_OPTIONAL_PTR checks for pdcp_config, sdap_config, UP_TL_information, and securityIndication
- Fix bug in eq_pdu_session_to_mod_item where a->UP_TL_information was compared with itself instead of b->UP_TL_information
- Fix eq_security_ind call to properly handle return value with early return pattern
- Improve consistency with existing macro usage patterns in the codebase
- Provide better error reporting for optional pointer field mismatches
Replace result &= pattern with consistent early return pattern:
- Fix mixing of logical (&&) and binary (&) operators
- Use consistent 'if (!eq_()) return false;' pattern throughout
- Fix bug in eq_bearer_context_mod_response where drbModA was compared with itself
- Remove unused 'bool result = true;' variables
- Always return true at the end of equality functions
This makes the code more consistent with the rest of the codebase
and provides better error reporting through the existing _E1_EQ_CHECK macros.
Integration `2025.w39`
* !3582 replace bad DCI by specific message for each case and add checks for bad...
* !3595 Implementing the option to have more than 1 RSRP in CSI report
* !3640 Code cleanup (SRS, config files and more)
* !3654 Extend t300 in multi_ue rfsim testcase
* !3650 NR UE improvements for scheduling ACK/NACK for MSG4
* !3652 In ReconfigurationWithSync, make sure epochTime_r17 present if there is a ntn_Config_r17
* !3653 NR UE: in nr_ue_scheduler.c set LCID_buffer_remain to 0 if RLC indicates not more bytes in buffer
* !3549 Switch to new (internal) registry
* !3513 Improvements to RRC PDU session and DRB handling logic
Closes#995 and #997
See merge request oai/openairinterface5g!3658
Improvements to RRC PDU session and DRB handling logic
This merge request introduces a major simplification and cleanup of the gNB RRC
PDU Sessions and DRBs handling logic. The core goals of this work are to:
- Replace fixed-size PDU Session, DRBs and QoS arrays with dynamic containers
- Simplify and modularize helper functions for session/DRB management
- Prepare for further refactoring of the PDU Session state machine
- Improve code safety and maintainability through better bounds checking
common/utils/threadPool/measurement_display.c:55:14 warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 3 has type ‘long long unsigned int’ [-Wformat=]
- Replace simple counter-based DRB ID assignment with actual DRB ID lookup
- Add nested loop to iterate through DRBs for each PDU session to be release
- Improve logic flow with early continue for non-matching PDU sessions
This ensures DRB release list contains correct DRB IDs that correspond to actual DRB entities
* There is no IE corresponding to PDU sessions failed to release
in the PDU SESSION RESOURCE RELEASE RESPONSE message. This was removed
and the corresponding code was refactored and cleaned up.
* In the Release Command handler, only established PDU Session are set to be
released. The Response message is filled accordingly.
Motivation:
The previous architecture had several issues:
- Duplicate DRB generation logic in generateDRB() and generateDRB_ASN1()
- Embedded SDAP/PDCP configs in drb_t created tight coupling
- No clear separation between RRC internal state and ASN.1 encoding
- Maintenance burden due to duplicated configuration logic
New Architecture:
- drb_t now only stores DRB-specific data (ID, PDU session ID, PDCP config)
- SDAP configuration moved to PDU session level (following PDCP design pattern)
- ASN.1 encoding helpers (nr_rrc_build_*_config_ie()) handle conversion
- Single source of truth for DRB creation in RRC via nr_rrc_add_drb()
Key changes:
- Store nr_sdap_configuration_t per PDU session
- Simplified drb_t structure: removed embedded SDAP/PDCP configs, added pdusession_id
- New helper: nr_rrc_build_sdap_config_ie()
- Updated createDRBlist() to use new helper functions and proper DRB ID lookup
- Refactored trigger_bearer_setup() to use nr_rrc_add_drb() and fill_e1_drb_to_setup()
- Removed generateDRB() and generateDRB_ASN1() functions
- Updated set_bearer_context_pdcp_config() to return config by value
- Added SDAP configuration header file for type definitions
This eliminates code duplication, improves maintainability, and creates
a cleaner separation between RRC state management and ASN.1 encoding.
- Move QoS-related enums and structures from ngap_messages_types.h to 5g_platform_types.h
- Replace ngap_* QoS types with generic qos_* types for better reusability
- Update field names from allocation_retention_priority to arp for consistency
- Update all references across RRC and NGAP modules to use new type names
- Remove duplicate QoS type definitions from NGAP-specific header
This improves code organization by centralizing QoS parameter definitions
in a common platform types header and eliminates NGAP-specific naming
in favor of more generic, reusable type definitions.
The maximum number of QoS flows is 64.
- Replace QOSFLOW_MAX_VALUE with MAX_QOS_FLOWS constant
- Move MAX_QOS_FLOWS definition to common/platform_constants.h
- Remove duplicate QOSFLOW_MAX_VALUE definition from ngap_messages_types.h
This improves maintainability by centralizing the QoS flow limit constant
and eliminates duplicate definitions across different header files.
- Limit scope of get_default_rbconfig function: from asn1_msg.c/.h to rrc_gNB_nsa.c where it's used
- Create new rrc_gNB_asn1.c/h files for ASN.1 utility functions: they can be used in other RRC files
- Add nr_rrc_build_pdcp_config_ie function for building PDCP configuration IEs
- Update get_default_rbconfig to use the new PDCP config builder
- Add rrc_gNB_asn1.c to CMakeLists.txt build configuration
The previous DRB management relied on a fixed-size array (established_drbs[MAX_DRBS_PER_UE])
and manual status tracking using DRB_ACTIVE/INACTIVE flags. This approach was inefficient,
and made assumptions about DRB ID allocation that do not generalize well
to dynamic procedures like bearer modification or removal.
* Replace fixed-size array established_drbs[] with dynamic
seq_arr_t *drbs in gNB_RRC_UE_t
* Refactor get_drb() and added nr_rrc_add_drb() with clean abstractions
using find and seq_arr lib
* Updated all DRB-related logic (e.g., generateDRB,
F1AP/E1AP tunnel config, reestablishment, mobility) to use seq_arr.
* Removed status field and DRB_ACTIVE/INACTIVE logic: list presence implies active
* DRB ID allocation now tracked via seq_arr size : simplifies DRB management and
avoids DRB ID–indexed assumptions: code assumed DRB IDs mapped directly to
array indices: established_drbs[drb_id - 1]. This could break when:
DRB IDs are not sequential, DRBs are removed and re-added, or there are gaps in IDs
The RRC PDU Session struct is converted from a fixed-size array
to a dynamically sized seq_arr. This improves flexibility and
simplifies session management by eliminating arbitrary size limits
and enabling dynamic addition/removal of PDU sessions.
Helper functions and loops have been adapted to use the seq_arr API.
This change is a step toward more robust and maintainable handling
of PDU sessions in the gNB RRC layer.
The "status" state machine remains untouched in this commit and
is refactored in a later commit.
Also:
* add macro to push to seq_arr and return the new element
* move initialization of xid (RRC PDU Session struct) to
find_pduSession (temporary, will be finalized in a later
commit) since with the new seq_arr design the initialization
is no longer possible in the UE context generation (also
does not belong to it, initialize when adding a new PDU Session)
The function was printing a "not found" error message even in the case
the return value was set to "true". Return directly true/false.
This is relevant in PDU Session Release procedures.
- Process all PDU sessions in handover request instead of only the first one
- Add DevAssert for bounds checking on nb_of_pdusessions
- Fix logic error where multiple PDU sessions were ignored in handover scenarios
Previously, the RRC layer was incorrectly allocating stack memory for the ho_required_transfer field and passing it to NGAP, however it was not used. The IE is mandatory but contains only 1 optional IE, therefore is encoded in the NG message with empty content.
Changes:
- Remove unnecessary ho_required_transfer field from pdusession_resource_t definition, the IE is encoded anyway with empty content. If Direct Forwarding Path Availability is needed at any stage in the future it can be added to pdusession_resource_t and filled in RRC.
- Add clarifying comment about empty HandoverRequiredTransfer structure
NR UE: in nr_ue_scheduler.c set LCID_buffer_remain to 0 if RLC indicates not
more bytes in buffer
If the RLC indicates that there is no more data in the buffer, also the
scheduler's LCID_buffer_remain should be set to 0. Else the UE sends BSR
indicating it has data to be transmitted. The gNB would then unnecessarily
schedule UL for this UE, which would not be used, as there is no actual data
to be transmitted.
Extend t300 in multi_ue rfsim testcase
Extend t300 to 1000 to increase the time the gNB has to handle MSG3. Hopefully
this prevents the UEs from timing out after MSG3. Add UE id to timer timeout
LOGs so the UE behavior can be traced through the stack.
Code cleanup (SRS, config files and more)
- Remove deprecated elements from some configuration files (also closes#997)
- Improve SRS code with a better separation between common code and gNB/UE code
- Other minor compilation improvements
Implementing the option to have more than 1 RSRP in CSI report
In collaboration with NI/Emerson.
The standard allows up to 4 RSRP measurements in CSI report (1 full and the other
differential). In current OAI, we just configure 1 RSRP report for the strongest
SSB. This MR allows to configure at gNB more than 1 RSRP report (depending on
config file, number of SSBs and UE capabilities) and makes changes at the UE to
send this report.
replace bad DCI by specific message for each case and add checks for bad...
Replace bad DCI by specific message for each case and add checks for bad
pointers, or sanitize detected warnings. Then fix several issues in DCI
decoding. With this MR, LTE UE has less bad DCI, and each bad DCI has a
reason better diagnosis.
If the RLC indicates that there is no more data in the buffer, also the scheduler's
LCID_buffer_remain should be set to 0. Else the UE sends BSR indicating it has data
to be transmitted. The gNB would then unnecessarily schedule UL for this UE, which
would not be used, as there is no actual data to be transmitted.
Correctly handle unpacking of the first RSRP report and its resource ID before processing additional reports.
Use the initial RSRP value as the reference for differential RSRP calculations in subsequent reports.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.