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).
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.
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.
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.
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>
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.
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.
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.
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.
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.
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>
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]
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=]
N2 handover
This MR introduces full support for N2 handover, covering handover
decision, preparation, execution, and notification between source and
target NG-RAN nodes.
Key features:
1. Handover Decision & Preparation:
- Implement N2 handover decision based on UE measurement reports.
- Generate the Handover Preparation Information message, including
RRCReconfiguration.
- Send Handover Required message from the source NG-RAN to the AMF.
2. Handover Execution:
- Decode and handle the Handover Request on the target NG-RAN.
- Process the Handover Command on the source gNB, triggering
RRCReconfiguration.
- Initiate Handover Notify after successful completion.
3 NGAP & RRC Enhancements:
- Implement NGAP encoding/decoding functions for Handover Required,
Handover Request, Handover Command, Handover Failure, and Handover
Notify (3GPP TS 38.413).
- Adds NG-RAN Status Transfer support (UL/DL) for PDCP COUNT
preservation during mobility:
- support for NGAP Uplink and Downlink RAN Status Transfer messages
(TS 38.413 §9.2.3.13-14) to enable proper PDCP COUNT value
transfer during handover or recovery: NGAP encoding/decoding for
RAN Status Transfer, PDCP helpers to extract and apply COUNT (HFN
+ SN) per DRB. This aligns with TS 38.300 §9.2.3.2.1 and TS 23.502
§4.9.1.3.3, ensuring PDCP status preservation in AM.
4. Testing:
- Introduce a Telnet command to manually trigger N2 handover using UE
ID and neighbor PCI.
- Add configuration file for testing N2 handover with a target gNB.
CI: build images on Jetson (armv8)
Add a new build pipeline for NVIDIA Jetson (armv8). Images have tag
prefix armv8_ to distinguish from gracehopper-built images prefixed arm_
(should have maybe been better with armv9_?)
Introduce a new timer for the use case where a UE should not be
scheduled anymore after a certain time. This is the case, for instance,
during handover, where the "source DU" forwards the RRCReconfiguration
and should stop scheduling this UE after some time.
Originally, transm_interrupt was introduced in 5c6d90aaff ("Use
NR_timer_t for UE transmission interrupt, e.g., RRC processing") to stop
scheduling a UE.
Commit 004403c84d ("Implement F1 UE Ctxt Modif Transmission Action
Indicator") reused this timer in an attempt to save code with an
"interrupt follow action".
In commit 89ebbb4192 ("Do not trigger ul failure in measgap scheduling
and standardize the verification if MAC is active in other scheduling
functions"), the transm_interrupt timer is used to not schedule a UE
through function nr_mac_ue_is_active(). This led to the UE not being
forwarded the RRCReconfiguration, effectively breaking handover, as the
message never reaches the UE. By using a new timer, the intended
functionality is restored.
Fixes: 89ebbb4192 ("Do not trigger ul failure in measgap scheduling
and standardize the verification if MAC is active in other
scheduling functions")
Remove this flag, as it is not used as of this commit, and introduces
confusion (see next commit: we reused the trans_interrupt timer for
the transmission action indicator stop action, where the UE should stay
active, while it is *not* when transm_interrupt is active).