without this fix, after sync is successful, RAR is not getting decoded.
PDCCH area also changes as SSB offset can change. if MAC configuration changes.
Actual problem is that SYNC does not happen on the target cell as frame parameters is not updated
and ssb start carrier is not correct in the UE frame parameters
function nr_get_ssb_start_sc to determine ssb_start_subcarrier
Configure CSI-RS according to beam_id used by UE
This MR is to configure CSI-RS according to beam_id used by UE and
reconfigure upon beam change.
It has been tested with RFSIM, Liteon and Microamp under multiple beams.
Fixes for Initial UE Context Setup
This MR fixes DRB aggregation from E1 so DRBs from multiple PDU sessions
are appended correctly into the F1 DRB array instead of overwriting
existing entries. It also makes NGAP Initial Context Setup skip PDU
sessions that are already established for the UE, only setting up new
sessions.
DRB aggregation from E1: Adjust fill_drb_to_be_setup_from_e1_resp to
pass &drbs[nb_drb] into fill_f1_drbs_from_e1, ensuring DRBs from later
PDU sessions are appended after the current count.
Duplicate PDU sessions in NGAP Initial Context Setup: In
rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ, detect requested PDU
session IDs that already exist with PDU_SESSION_STATUS_ESTABLISHED, log
a warning, and skip them so they are not added to UE->initial_pdus.
Remove L1 dependence from NR band number
L1 band information relied on get_band function that couldn't provide an
unambiguous result. Also there is no SCF compliant parameter for L1 and
generally we don't really need that information in L1.
The MR also remove a RU section that used nr_band but was never really
accessed in NR.
Ensure the CU-CP only sets up PDU sessions that are not already
established for the UE, skipping duplicates while keeping the NG UE
context valid. This aligns with 3GPP TS 38.413 PDU Session setup
semantics for duplicate session IDs
Changes:
- Change rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ to scan requested
PDU sessions and detect IDs that already exist in UE->pduSessions with
PDU_SESSION_STATUS_ESTABLISHED
- Log a warning and skip already established PDU session IDs so they are
not added to UE->initial_pdus
- Collect only non-established PDU sessions into a temporary stack array,
allocate UE->initial_pdus with the exact count, copy them in, update
UE->n_initial_pdu, and only refresh UE AMBR when there is at least one
session to set up
Ensure DRBs from multiple PDU sessions are appended into the F1 DRB array
without overwriting previously filled entries.
Update fill_drb_to_be_setup_from_e1_resp to call fill_f1_drbs_from_e1
with &drbs[nb_drb] so each PDU session’s DRBs are written after the
current count
print better message for rsrp: invalid doesn't mean it is not measured
print better message for rsrp: invalid doesn't mean it is not measured,
it means it is out of usable range
NR UE: fix PRACH k1 calculation at MAC when handover
The k1 for PRACH calculation in config_common_ue() should be the same as in
config_common_ue_sa(), otherwise k1 is wrong when handover to target cell if
msg1-FDM not 0 in reconfigurationWithSync.
Verified with 3rd-party gNB.
gNB: Reset NDI only after usage in case of disable HARQ
Solves this warnings seen in the UE trace:
NDI indicates re-transmission but computed TBS 3968 doesn't match with what previously stored 3368
Issue happens only if feature disable_harq is enabled. GNB resets the harq
process (including NDI) as PUCCH will not be sent for this harq process, but
before the harq process is used in DCI payload preparation.
Fix is to reset the harq process after harq process in case of no PUCCH.
NR Paging on CU
Implements the NR paging path on the CU:
- NGAP Paging is decoded and passed to RRC
- RRC builds F1AP Paging, and distributes it to DUs via F1 callback
Changes:
- Refactor and extend F1AP Paging encode/decode libraries
* add missing enc/dec/eq/cp functions
* add unit test
* IEs: CN UE 5G-S-TMSI, RAN UE I-RNTI; optional DRX/priority/origin)
- Refactor CU callback CU_send_Paging
- Refactor DU handler DU_handle_Paging
- Refactor old F1 callback for Paging indication, extend it and align
with existing F1 callbacks in stack
- Refactor and extend NGAP Paging encode/decode lib
* add missing enc/dec/eq/cp functions
* add unit test
* Fixes NGAP paging to accept Paging only on SCTP stream 0 per TS
38.412
- Includes supporting refactors (PDU session split, shared 5G-S-TMSI
helpers, NGAP/F1AP cleanups)
Testing
- NGAP and F1AP Paging lib unit tests (enc/dec)
- Stream-0 fix validated with Open5GS AMF
This MR does not address the DU changes besides the F1 handler. F1AP
Paging does not have an RRC container to pass the PCCH message to the
DU, and F1 DL RRC Message Transfer does not apply to PCCH. PCCH-Message
shall be built at DU per TS 38.331 §5.3.2, with padding as per §8.5 and
delivered as RLC SDU per §8.2. For each cell in Paging Cell List that
belongs to this DU, queue for MAC. MAC schedules at PF/PO per TS 38.304
§7.
Refs:
- F1AP 3GPP TS 38.473 version 16.21.0 Release 16
- NGAP 3GPP TS 38.413 version 16.17.0 Release 16
bugfix: add PCell to serving_cells in fallback path and refactor update logic
Fix assertion failure in rrc_gNB_send_NGAP_NAS_FIRST_REQ() when RRC
Reestablishment falls back to RRC Setup. The fallback path was not
adding the PCell to the UE's serving_cells array, causing
rrc_get_pcell_for_ue() to return NULL.
Major changes:
- Add rrc_update_ue_pcell() helper function that handles PCell updates
for both new UEs (fallback) and existing UEs (normal reestablishment)
- Refactor normal reestablishment path to use rrc_update_ue_pcell()
helper instead of manual cleanup + add sequence
- Add PCell update to fallback_rrc_setup path using the same helper
- Move C-RNTI validation after current_cell fetch to ensure current_cell
is initialized before fallback_rrc_setup label
- Change error handling: return instead of fallback when PCell add fails
in normal reestablishment path
Fixes CI failure in !3908
Fix race condition on double RA during RRC reestablishment
Sometimes, especially in poor channel conditions, a UE can trigger
multiple RA procedures during RRC reestablishment, causing
reconfigCellGroup to be overwritten with a CellGroup that already has
spCellConfig removed, leading to an assertion failure in
update_cellgroup_for_reestablishment(). See logs below
[NR_MAC] 456.13 UE 991d: Received Ack of Msg4. CBRA procedure succeeded (UE Connected)
[NR_MAC] Adding new UE context with RNTI 0x991d
[NR_PHY] [RAPROC] 461.9 Initiating RA procedure with preamble 8, energy 48.0 dB (I0 274, thres 130), delay 21 start symbol 2 freq index 0
[NR_MAC] 461.9 UE RA-RNTI 0081 TC-RNTI ecd8: initiating RA procedure
[NR_MAC] UE ecd8: Sync beam index 0
[NR_MAC] UE ecd8: Msg3 scheduled at 462.3 (461.18 TDA 2) start 0 RBs 8
[NR_MAC] UE ecd8: 461.18 Generating RA-Msg2 DCI, RA RNTI 0x81, state 1, preamble_index(RAPID) 8, timing_offset = 21 (estimated distance 820.3 [m])
[NR_MAC] 462. 3 PUSCH with TC_RNTI 0xecd8 received correctly
[NR_MAC] Received a MAC CE for C-RNTI with 991d
[NR_MAC] Remove NR rnti 0xecd8
[NR_MAC] 462. 3 RA with C-RNTI 991d complete
[NR_PHY] [RAPROC] 471.19 Initiating RA procedure with preamble 6, energy 51.0 dB (I0 276, thres 130), delay 21 start symbol 2 freq index 0
[NR_MAC] 471.19 UE RA-RNTI 010d TC-RNTI 022d: initiating RA procedure
[NR_MAC] UE 022d: Sync beam index 0
[NR_MAC] UE 022d: Msg3 scheduled at 472.13 (472.8 TDA 2) start 0 RBs 8
[NR_MAC] UE 022d: 472.8 Generating RA-Msg2 DCI, RA RNTI 0x10d, state 1, preamble_index(RAPID) 6, timing_offset = 21 (estimated distance 820.3 [m])
[NR_MAC] 472.13 PUSCH with TC_RNTI 0x022d received correctly
[NR_MAC] Received a MAC CE for C-RNTI with 991d
[NR_MAC] Remove NR rnti 0x022d
[NR_MAC] 472.13 RA with C-RNTI 991d complete
[NR_RRC] [UL] (cellID 1, UE ID 1 RNTI 991d) Received RRCReestablishmentComplete
[NR_RRC] UE 1 Processing NR_RRCReestablishmentComplete from UE
[NR_MAC] UE 991d: gNB-DU Configuration Query received, will include CellGroupConfig in response
Assertion (new_CellGroup->spCellConfig) failed!
In update_cellgroup_for_reestablishment() /phy/openairinterface5g/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c:666
This MR solves it by skipping the reconfigCellGroup overwrite when it
already holds a valid config with spCellConfig, and by replacing the
fatal assertion on missing spCellConfig with an early return.
Add a simple GTP unit test
Add a simple unit test for GTP that as of now tests the main
functionality, i.e., for a single UE, set up a bearer between two
endpoints and checking that traffic sending works. This is a start to
extend it further, e.g., with API changes, extensions to support new
functionality such as IPv6, and refactorings.
A number of supporting cleanup has been done as well.
The k1 for PRACH calculation in config_common_ue() should be the same as in config_common_ue_sa(),
otherwise k1 is wrong when handover to target cell if msg1-FDM not 0 in reconfigurationWithSync.
RRC now builds F1AP paging messages directly by calling F1AP/direct
callbacks and aligning the CU/DU intergace with the F1AP design in the CU.
Messages are forwarded based on TAI-based cell matching across DUs.
- Remove F1AP_PAGING_IND message def and f1ap_paging_ind_t.
RRC no longer sends ITTI F1AP_PAGING_IND; it builds f1ap_paging_t
and passes it to the DU path.
- rrc_gNB_process_PAGING_IND: new signature (rrc, instance, msg)
with const where appropriate; call in rrc_gnb_task() updated.
- NGAP handler logic: For each TAI, match (PLMN + TAC) to
rrc->configuration; collect matching TAIs. Build one f1ap_paging_t
(5G-S-TMSI via nr_construct_5g_s_tmsi(), identity type
F1AP_PAGING_IDENTITY_CN_UE, optional drx/priority/origin copied
from ngap_paging_ind_t), call rrc_send_paging_to_dus(), then
free_f1ap_paging(). Remove the previous AssertFatal stub, CC loop,
NODE_IS_CU branch, and UE lookup logic: it is now handled by
F1AP/direct CU callbacks.
- rrc_gNB_du: Add rrc_send_paging_to_dus(rrc, tais, n_tai, msg).
Iterate DUs with RB_FOREACH; for each DU, fill msg->cells from
du->cells whose (PLMN + TAC) matches any requested TAI, set
n_cells, then call rrc->mac_rrc.paging_transfer(du->assoc_id,
msg). Skip DUs with no matching cells. Prevents duplicate paging
when multiple TAIs map to the same PLMN.
Introduce paging_transfer in the mac_rrc_dl interface so the CU can pass
paging to the DU (F1 or direct). Use the F1AP paging lib on both CU and DU
for decode/free and to avoid leaking the message after send.
- Add f1_paging_transfer_func_t and paging_transfer to nr_mac_rrc_dl_if_s
(mac_rrc_dl.h, nr_rrc_defs.h).
- F1AP path: paging_f1ap() allocates F1AP_PAGING, copies with cp_f1ap_paging(),
sends via ITTI to TASK_CU_F1. Direct path: f1_paging_transfer_direct() stub
- CU task: call free_f1ap_paging() after CU_send_Paging() to release the message.
- DU: DU_handle_Paging() uses decode_f1ap_paging()/free_f1ap_paging() from lib,
returns on decode failure; remove inline ASN.1 IE parsing.
- cleanup outdated header comments in header files
- Left a TODO not in DU code to build PCCH (in F1 and direct paths)
- Add F1AP_PAGING message type and macro; F1AP defines Paging, not
Paging Indication. CU task now handles F1AP_PAGING instead of
F1AP_PAGING_IND.
- In CU_send_Paging(): take const f1ap_paging_t *; replace inline
ASN.1 encoding with encode_f1ap_paging(); refine memory management;
clean up in the process
Note: F1AP_PAGING_IND definitions left in place and still used in the
RRC callback - to be removed in a follow-up commit.
Add F1AP Paging library and new message type to follow the existing F1AP
library pattern and to support multi-cell paging and both RAN UE (I-RNTI)
and CN UE (5G-S-TMSI) paging identities at the library level per TS 38.473.
* New library (f1ap_paging.c/h, f1ap_lib_includes.h, CMakeLists.txt)
- Implement encode/decode/copy/eq/free for F1AP Paging (procedure 9.2.6).
- Add ASN.1 includes for Paging, PagingIdentity, CN/RAN UE identities.
- Enables unit testing of Paging enc/dec in f1ap_lib_test.c.
* New types in f1ap_messages_types.h (existing f1ap_paging_ind_t unchanged)
- f1ap_paging_t: UE Identity Index, paging identity (union + type enum),
optional paging_drx, paging_priority, paging_origin, and paging_cells[].
- f1ap_paging_cell_item_t, f1ap_paging_identity_type_t, f1ap_paging_identity_t
for multi-cell list and RAN/CN identity discrimination.
- Paging Origin IE is optional per F1AP 8.7.1.2.
Tests: test_f1ap_paging() roundtrip and copy for CN UE (5G-S-TMSI) and
RAN UE (I-RNTI) cases, with optional IEs.
- Refactor ngap_paging_ind_t (openair2/COMMON/ngap_messages_types.h):
- optional paging_drx and paging_priority as pointers
- TAI list as tai_list[] and n_tai
- add optional IEs: Paging Origin, Paging Attempt Information,
UE Radio Capability for Paging.
- Introduce nr_tai_t, ngap_paging_attempt_info_t, ngap_paging_origin_t;
- generate paging enums via FOREACH macros.
- Add NGAP Paging encode/decode/eq/free in openair3/NGAP/ngap_gNB_paging.c
(encode_ng_paging, decode_ng_paging, eq_ng_paging, free_ng_paging).
- Replace inline Paging decode in ngap_gNB_handle_paging() with
decode_ng_paging() and add error handling; add eq_ngap_plmn() in
ngap_common.
- Update rrc_gNB_NGAP.c to use tai_list/n_tai and optional paging_drx
when forwarding paging to F1AP.
- Add ASN.1 includes for Paging in ngap_msg_includes.h; register
ngap_gNB_paging.c in root CMakeLists.txt.
- Add NGAP unit test (openair3/NGAP/tests/ngap_lib_test.c): encode/decode
roundtrip for Paging; tests subdirectory and executable under
ENABLE_TESTS in openair3/NGAP/CMakeLists.txt.
TO_ENUM/TO_TEXT are already used in NAS, and can be adopted in NGAP.
To avoid duplication, the following changes are introduced:
* Move text_info_t, TO_ENUM, TO_TEXT to common/utils/utils.h
* Include utils.h include to ngap_messages_types.h, fgs_nas_utils.h, and fgmm_lib.h
* RRC establishment cause: refactor to FOREACH_RRC_ESTABLISHMENT_CAUSE macro
* Cause Group: refactor to FOREACH_CAUSE_GROUP macro
* Radio Network Cause: refactor to FOREACH_CAUSE_RADIO_NETWORK macro
* Protocol Cause: refactor to FOREACH_CAUSE_PROTOCOL macro
This change is preparatory to the introduction the paging lib with unit
tests, with the goal of reducing the inter-dependency between concurrent
NGAP libs.
This commit centralizes equality-check behavior and removes duplicated
macro implementations across protocol stacks.
Major changes:
- add `common/utils/eq_check.h` with shared `_EQ_CHECK_*`,
`EQ_CHECK_GENERIC`, and optional-IE pointer helpers
- replace E1AP/F1AP/NAS local equality macros and call sites with
the shared helpers
- remove duplicated layer-specific error/equality macro definitions from
common headers and switch includes to `eq_check.h`
- update CMake test flags to define `ENABLE_TESTS` for `e1ap_lib`,
and 5GS NAS libraries; drop `E1AP_LOG_ERRORS` - equality-check/error
printing is now consistently controlled by `ENABLE_TESTS`
Centralizes 5G-S-TMSI bit manipulation logic for consistency and
maintainability. All manual bit operations replaced with documented
helper functions following TS 23.003 bit layout specification.
- Add helper functions for 5G-S-TMSI operations:
* nr_construct_5g_s_tmsi_part1: 5G-S-TMSI construction is defined
in 3GPP TS 23.003 and relevant at both gNB and UE side
* Add helper functions to be later used in NG Paging
* Adopt in NAS UE
* nr_extract_5g_s_tmsi_part1() - extract Part1 (39 bits) from full
* nr_extract_5g_s_tmsi_part2() - extract Part2 (9 bits) from full
* nr_build_full_5g_s_tmsi() - reconstruct full from Part1+Part2
* nr_deconstruct_5g_s_tmsi() - deconstruct into components
- Refactor manual bit manipulation to use helper functions:
* asn1_msg.c: use nr_extract_5g_s_tmsi_part1() in RRCSetupRequest
* asn1_msg.c: use nr_extract_5g_s_tmsi_part2() in RRCSetupComplete
* rrc_gNB.c: use nr_build_full_5g_s_tmsi() when reconstructing from parts
* rrc_gNB.c: use nr_deconstruct_5g_s_tmsi() when extracting components
- Optimize nr_construct_5g_s_tmsi_part1() to reuse extract function
There is no such thing as NG Register message, the naming is
inaccurate, however the goal of this commit is only to clarify that
and major refactoring is not yet carried out.
Move rrc_update_ue_pcell() from static function in rrc_gNB.c to public
function in rrc_cell_management.c, making it reusable across RRC code
paths. Replace duplicate PCell addition logic in handover paths
(intra-CU and inter-CU) and RRCSetup path with calls to this shared
function.
This eliminates code duplication between handover and RRCSetup paths,
centralizes PCell update logic (including cleanup of old PCell's DU
serving cells) in a single reusable function and makes the function
available for future use in other RRC procedures
Fix assertion failure in rrc_gNB_send_NGAP_NAS_FIRST_REQ() when RRC
Reestablishment falls back to RRC Setup. The fallback path was not
adding the PCell to the UE's serving_cells array, causing
rrc_get_pcell_for_ue() to return NULL.
Major changes:
- Add rrc_update_ue_pcell() helper function that handles PCell updates
for both new UEs (fallback) and existing UEs (normal reestablishment)
- Refactor normal reestablishment path to use rrc_update_ue_pcell()
helper instead of manual cleanup + add sequence
- Add PCell update to fallback_rrc_setup path using the same helper
- Move C-RNTI validation after current_cell fetch to ensure current_cell
is initialized before fallback_rrc_setup label
- Change error handling: return instead of fallback when PCell add fails
in normal reestablishment path
Cleanup Cmake: remove some double compilation
Harmonize some cmake code to avoid double compilation, notably around
polar and smallblock. In develop, we just add their sources to other
targets, whereas now we define STATIC libraries (further changed to
shared library in !3856) to avoid double compilation.
With this command line:
cmake .. -GNinja -DENABLE_TESTS=ON && ninja
shows that before we compile 12631 files, where after it is 12583
there is additional supporting cleanup (move code, remove headers,
types, ...).
there is more harmonization to do, I limited myself to some easy wins.
For instance, we do the same with PDCP/SDAP, and this should be
refactored into STATIC libraries as well.
RRC: Multi-cell handling architecture
This MR implements a foundational multi-cell handling architecture for
RRC by separating DU management from cell management and establishing a
hierarchical cell organization within each DU container. The changes
enable proper multi-cell support where each DU can serve multiple cells,
addressing the previous limitation where DU and cell management were
tightly coupled with the assumption of one cell per DU.
Key Changes:
- Data Structure Separation: Separated for DU containers (DU-specific
info) from cell containers (cell-specific data)
- Global DU and Cell Trees: Cells are now stored in global RB trees in
RRC, similarly to DUs
- Du-specific cell seq_arr: within each DU container (du->cells) is
stored a seq_arr of cells belonging to the DU
- UE Cell Association Framework: Introduced serving_cells array to track
PCell and SCells for each UE with servCellIndex indexing
- Cell Management Library: Extracted cell management functions into
rrc_cell_management.c/h for better testability and maintainability
Other relevant changes:
- F1AP Refactoring: cell list definitions, heap allocation to prevent
stack overflow
- 5G-S-TMSI Helpers: Common helper functions for 3GPP TS 23.003
compliant construction
- Integration Tests: Comprehensive test suite for DU lookup, cell
lookup, and UE cell association
- Cell Duplication Checks: Validation in F1 DU configuration update to
prevent duplicate cells
- Documentation: Updated RRC developer documentation with multi-cell
architecture details
Validated with RFsim in re-establishment and handover scenarios.
openair2/COMMON/rrc_messages_types.h has mostly 4G types. The only 5G
(gNB) RRC type is gNB_RrcConfigurationReq, which we can move to a header
in the corresponding directory (where it is used).
This allows to separate 5G gNB RRC module from the 4G types in
rrc_messages_types.h in the next commit.