Initialize the local NAS message container before it is used in the
RRCSetupComplete generation path to avoid undefined state from stack data.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Multi-QoS Handling and PDU Session Modify
This MR implements comprehensive QoS flows handling and PDU Session
Modify procedures in the RRC layer, enabling full support for multiple
QoS flows per DRB and dynamic QoS management per 3GPP specs. Key
changes:
1. Multi-QoS Flows Support
- Multiple QoS flows per DRB: Support for multiple QoS flows mapped to a
single DRB
- Intelligent QoS-to-DRB mapping: Implements resource-type-aware
multiplexing based on 3GPP TS 23.501 Table 5.7.4-1
- DC-GBR flows (5QI 82-90): Dedicated DRB, max 1 flow per DRB
- GBR flows (5QI 1-4, 65-67, 71-76): Max 2 flows per DRB
- Non-GBR flows (5QI 5-11, 69-70, 79-80): Max 5 flows per DRB
- Aggregate cap: Maximum 5 flows per DRB
- 5QI validation: Early validation of standardized 5QI values (1-9,
65-90) during QoS flow setup/modify
2. PDU Session Modify Procedures
- Complete E1AP/RRC integration: Full Bearer Context Modification
support with DRB lifecycle management
- DRB To Setup/Modify/Remove lists: Complete support for all DRB
operations in Bearer Context Modification
- QoS flow operations: Support for QoS flow add, modify, and release
operations
- QoS flow mapping: Proper handling of QoS flow modifications in
DRB To Modify List
- Automatic DRB management: DRB setup, modification, and removal
based on QoS flow changes. Reuse existing DRBs if the incoming QoS
flow is compatible.
- Delayed transactions: PDU Session Modify added to delayed
transactions list for proper sequencing
3. GTP-U Tunnel Refactoring
- Architecture alignment:
- N3 tunnels: 1 per PDU session with QFI marking, container for
multiple bearers, supporting multiple QoS flows
- F1-U tunnels: 1 per DRB without QFI marking
- SDAP ownership of QoS: move QoS management to be fully owned by
SDAP
4. QoS Enhancements
- Dynamic5QI support: Full support for Dynamic5QI with packet delay
budget and packet error rate
- GBR QoS flows: Support for Guaranteed Bit Rate QoS flows with
GFBR/MFBR parameters
- DRB QoS aggregation: DRB-level QoS computed from all mapped QoS
flows using ARP priority (not 5QI priority)
- QoS priority level refactoring: Proper type definitions per 3GPP
TS 23.501 (QoS Priority Level: 1-127, ARP Priority Level: 1-15)
Technical Changes
RRC Layer
- Refactored `nr_rrc_add_bearers()` to support intelligent QoS-to-DRB
mapping
- Added `nr_rrc_update_qos()` for QoS flow add/modify with automatic DRB
assignment
- Implemented `nr_rrc_update_pdusession()` for QoS flow release and DRB
cleanup
- Consolidated F1 UE Context Modification Request handling
- Simplified PDU status tracking by removing intermediate states
- Added QoS flow and DRB removal utilities
- Updated RRC bearers tests with comprehensive multi-QoS testing
- Adapted `nr-cuup-load-test.c` to new GTP design
NGAP Layer
- Extended PDU Session Resource Modify Request Transfer with QoS
add/modify/release lists
- Added proper type definitions (`pdusession_mod_req_transfer_t`,
`qos_flow_to_release_t`)
- Fixed NGAP PDU Session Modify transfer encoding
GTP-U Layer
- Refactored tunnel creation API: scalar fields instead of arrays
- Split tunnel creation into `n3_gtpu_create()` and
`f1_drb_gtpu_create()`
- Added bearer-to-QFI mapping structure (`gtpv1u_rb_t`)
- Implemented QFI de-duplication and one-to-one QFI-to-bearer mapping
- Reduced inter-dependencies between LTE and NR
SDAP Layer
- Fixed default DRB tracking: Only one default DRB per SDAP entity per
PDU session (TS 37.324)
- Set default DRB to first DRB added when creating bearers
F1AP Layer
- Added GBR QoS Flow Information IE handling in CU
- Implemented DRB QoS aggregation from multiple QoS flows
- Extended F1AP test cases to support multiple QoS flows
Code Quality Improvements
- Improved error handling throughout the stack
- Enhanced logging and debugging capabilities
- Added comprehensive unit tests for multi-QoS scenarios
- Improved type safety and validation
Testing
The code was validated with Open5gs v2.7.6, OAI CN5G and COTS UE.
How to reproduce with Open5gs:
1. Start Open5gs
2. From the Open5gs web UI: add multiple QFIs to the same DNN.
3. Restart Open5gs
4. Run gNB and UE
The user will see the following:
1. QoS flows arrive via NGAP PDU Session Setup/Modify requests, each
with a QFI and 5QI.
2. The gNB assigns each flow to a DRB, creating a new DRB or reusing an
existing one based on 5QI compatibility (compatible flows, i.e. same
5QI characteristics, share a DRB)
3. At the SDAP layer, packets are tagged with QFI headers; at the GTP-U
layer, uplink packets include QFI in the PDU Session Container for
core network mapping.
Documentation
- Added comprehensive QoS flows handling documentation with 3GPP
standards references
- Updated PDU Session Modify sequence diagrams
Note
* This implementation aligns with:
- 3GPP TS 23.501 (QoS framework)
- 3GPP TS 38.413 (NGAP)
- 3GPP TS 37.324 (SDAP)
- 3GPP TS 38.463 (F1AP)
- 3GPP TS 29.281 (GTP-U)
- 3GPP TS 38.331 (RRC)
* Multi-QoS and PDU Session Modify are both added to this MR since QoS
flows update is triggered by PDU Session Modify in some scenarios
(e.g. with Open5gs, used for validation).
* Core functional changes introduced by commits with prefix "QoS
Handling" or "PDU Session Modify"
* This MR replaces the old !2703.
* This MR adopts relevant CU changes from !2836, namely:
* Adds new shared QoS types
* Add standardized 5QI table and helper
* Dynamic5QI support + validation
* Computation of DRB QoS (aggregate QoS) and priority/GBR
* F1AP DRB-level QoS
* Closes#541 (5QI validation)
* Closes#1075 (Optional NAS-PDU in PDU Session Setup Request)
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Reviewed-by: Rakesh Mundlamuri <rakesh.mundlamuri@openairinterface.org>
Verify that a given cell's assoc_id (i.e., it's "host DU") is the
assoc_id of the currently treated DU to avoid treating a config update
of another (potentially malicious) DU.
Closes: #1081
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Issue:
With a commercial UE, NGAP traces showed the PDU Session Resource Modify
Response carrying a QoSFlowAddOrModifyResponseList that did not match the
preceding Modify Request: the gNB listed every QoS flow already stored on the
PDU session instead of only the flows present in QoS Flow Add or Modify Request
List for that modify.
e.g. QoSFlowAddOrModifyResponseList including QFI 1,2
QoSFlowAddOrModifyRequestList QFI 2
AMF ErrorIndication with semantic_error after modify
That breaks the intended semantics in TS 38.413, which
expects QoSFlowAddOrModifyResponseList to carry the QFIs from this
procedure’s QoS Flow Add or Modify Request List only.
Changes:
Add a per-flow ngap_pending flag set in nr_rrc_update_qos when a request
item is applied, clear it before each new modify, and build the response
from marked flows only.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
* Extend delay_transaction() and rrc_delay_transaction() to support NGAP_PDUSESSION_MODIFY_REQ
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
This commit extends PDU Session Modify handling with E1AP Bearer Context
Modification integration for QoS flow add/modify/release and DRB lifecycle
updates (setup, modification, removal).
E1AP Bearer Context Modification - DRB Setup Support:
- Extend CU-UP handler (e1_bearer_context_modif) to process DRBs to setup/to remove:
create F1-U tunnels, create/release PDCP-SDAP resources, and update QoS flow mappings
- Extend CU-CP response handler to process DRBs to setup: save F1-U tunnel info,
mark PDU sessions for RRC reconfiguration, and trigger F1 UE Context
Modification Request with both setup and release DRBs
- Update rrc_gNB_process_e1_bearer_context_modif_resp to collect DRBs to
setup/release from E1 response, send F1 UE Context Modification when needed,
and otherwise trigger direct RRC reconfiguration or NGAP modify response.
- Populate the E1AP Bearer Context Modification request with DRB-To-Setup and
DRB-To-Modify lists derived from QoS flow processing. For CP->UP E1 Bearer
Context Modification, Flow Mapping Information in DRB-To-Modify carries
the QoS Flow QoS Parameters List for that DRB: per TS 38.463, when present,
CU-UP replaces the previous mapping for that DRB, and this behavior is now enforced.
RRC PDU Session Modify - QoS and DRB Management:
- Add nr_rrc_apply_qos_add_modify() to process QoS add/modify and map flows to
existing or new DRBs
- Add nr_rrc_apply_qos_release() and nr_rrc_apply_pdusession_modify() to
process QoS release, build E1 DRB setup/modify/remove lists, and prepare
bearer-context modification.
- Refactor nr_rrc_update_qos() processing for QoS add/modify,
with DRB mapping to existing or new DRBs through the modify path helpers
- Extend nr_rrc_update_pdusession() with helpers for QoS
add/modify/release, building E1 DRB modify/setup/remove lists, and
sending bearer-context modification.
- Integrate E1 Bearer Context Modification into PDU Session Modify flow to
propagate DRB changes to CU-UP
- Update default DRB in SDAP configuration after QoS changes
- Add `nr_sdap_entity_update_qos_flows` to replace DRB flow
mappings from E1 flow information and clear stale SDAP role/mapping
state when QFIs are removed.
Code Refactoring:
- Add find_or_add_pdu_session_mod() to create/reuse session entries
in the E1 Bearer Context Modification request while building message.
- Add nr_rrc_send_e1_after_qos_update() to detect DRBs left without mapped
QoS flows, remove them from UE state, and append them to E1 DRBs-to-remove.
- Use rrc_gNB_generate_dedicatedRRCReconfiguration instead of
rrc_gNB_modify_dedicatedRRCReconfiguration, drop the old function
End-to-End PDU Session Modify Flow:
1. AMF -> CU-CP: NGAP PDU Session Resource Modify Request (QoS add/modify/release)
2. CU-CP (RRC): Process QoS flows -> map to DRBs (reuse existing or create new) ->
populate E1AP Bearer Context Modification Request (DRBs to setup/modify/remove)
3. CU-CP -> CU-UP: E1AP Bearer Context Modification Request
4. CU-UP: Create F1-U tunnels for new DRBs -> create/release PDCP-SDAP
resources -> update DRB/QFI mapping information
5. CU-UP -> CU-CP: E1AP Bearer Context Modification Response (F1-U tunnel info)
6. CU-CP: If DRB setup/release exists, send F1 UE Context Modification Request
7. CU-CP: Else if QoS/NAS requires it, send direct RRC Reconfiguration
8. CU-CP: Else complete modify directly with NGAP PDU Session Resource Modify Response
9. UE -> CU-CP: RRC Reconfiguration Complete
10. CU-CP -> AMF: NGAP PDU Session Resource Modify Response
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
This commit extends the PDU Session Resource Modify Request handling (within
PDU Session Modify) to fully support QoS Flow add/modify and release operations
(3GPP TS 38.413 section 9.3.4.3) via the Transfer IE. This is propagated to
RRC which performs PDU Session update, which occurs upon PDU Session Modify.
Refactoring was necessary since type `pdusession_transfer_t` and
`pdusession_resource_item_t` both for setup, were inaccurately used for the modify procedure.
The implementation adds proper type definitions, decoding logic,
and error handling for QoS flow management during PDU session modification transfer,
namely:
- Adds QoS add/modify and release lists to the NGAP Modify Request Transfer type
- Introduces QoS Flow With Cause IE
- Decode new IEs and propagate QoS changes to RRC session state
NGAP PDU Session Modify Request Transfer:
- Add qos_flow_to_release_t structure to represent QoS Flow to Release Items IE
with QFI and release cause (per 3GPP TS 38.413 section 9.3.1.13)
- Introduce pdusession_mod_req_transfer_t structure to properly represent
PDU Session Resource Modify Request Transfer IEs:
* QoS Flow Add or Modify Request List (mandatory)
* QoS Flow to Release List (optional)
- Add pdusession_resource_mod_item_t structure for PDU Session Resource
Modify Request Items, replacing pdusession_resource_item_t, which is for setup
- Update ngap_pdusession_modify_req_t to use the new type-specific structure
- Refactor decodePDUSessionResourceModify() to return
pdusession_mod_req_transfer_t instead of pdusession_transfer_t
- Implement proper decoding of QosFlowAddOrModifyRequestList IE
- Add decoding support for QosFlowToReleaseList (QosFlowListWithCause) IE:
* Extract QFI and cause for each QoS flow to be released
- Improve error handling throughout
ngap_msg_includes.h:
- Add includes for NGAP_QosFlowListWithCause.h and
NGAP_QosFlowWithCauseItem.h to support QoS flow release decoding
NGAP/RRC:
- Update nr_rrc_update_pdusession() function signature to accept
pdusession_resource_mod_item_t instead of pdusession_resource_item_t
- Remove references to unnecessary pdu_session_type and n3_incoming
fields that are not part of the Modify Request Transfer structure
- Update QoS flow update logic to use nb_qos_to_add_modify and
qos_to_add_modify fields from the new transfer structure
This implementation aligns NGAP with 3GPP TS 38.413 specifications
and provides a foundation for handling QoS flow modifications and releases
during PDU session resource modification procedures.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
- Update F1AP test cases to support multiple QoS flows
- Extend RRC bearers test with comprehensive multi-QoS testing
- Extend PDU sessions test to 2 PDU sessions per test
- Introduce template helpers to minimize duplicated code
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Refactor GTP-U tunnel and send APIs so QFI is handled when sending packets,
not stored in tunnel creation state. Update SDAP and CU-UP integration to
use PDU-session keyed N3 mappings and explicit QFI-marked sends.
This commit clarifies layering ownership: GTP-U stays transport-only (TEID
lookup, decapsulation, extension parsing, callback dispatch), while SDAP
owns QoS semantics (QFI handling, QoS-flow-to-DRB policy, default DRB behavior,
and mapping updates); GTP-U does not perform runtime QFI-to-DRB mapping or
synthesize QFI.
Changes:
- remove `outgoing_qfi` from `gtpv1u_gnb_create_tunnel_req_t` and stop storing
QFI as tunnel creation metadata; `newGtpuCreateTunnel(...)` now carries only
transport/tunnel identity parameters (incoming_bearer_id, outgoing_bearer_id,
outgoing_teid, remote address, callbacks)
- add `gtpv1uSendDirectWithQFI()` and pass QFI into `_gtpv1uSendDirect`
to build UL PDU Session Container extensions
- shift QFI handling from tunnel provisioning to per-packet TX APIs: QFI is passed
explicitly only when sending (`gtpv1uSendDirectWithQFI(...)`) and is absent from
non-SDAP/F1 sends (`gtpv1uSendDirect(...)`)
- align N3 tunnel request semantics with session-level keys by setting incoming_rb_id
to PDU session ID on N3 paths, while F1 paths keep DRB ID
- keep `gtpv1uSendDirect()` and `gtpv1uSendDirectWithNRUSeqNum()` on
`NO_QFI`, and enforce non-SDAP RX callback path only when QFI is absent
- update `nr_sdap_rx_entity` to extract/validate QFI from SDAP UL headers,
send UL data with `gtpv1uSendDirectWithQFI`, and use non-QFI send when
SDAP header is disabled
- add disabled-SDAP safety checks in SDAP entity setup/mapping to enforce
single-DRB and single-flow constraints per PDU session
- extend `test_gtp.cpp` with a `multi_qos_flows` scenario and QFI-aware send calls
- update `nr-cuup-load-test.c` bearer setup fields and tunnel creation calls
to match the new API
- update tests/nr-cuup/nr-cuup-load-test.c to set explicit PDU session and
QoS/SDAP parameters (sessionType, qosFlows[0], SDAP header flags), and to
migrate both N3 and F1 tunnel creation calls to the new newGtpuCreateTunnel(...)
signature (without outgoing_qfi)
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
GBR information is optional in F1AP and is only present for GBR flows
(5QI < 5 for NonDynamic5QI, or Dynamic5QI flows with GBR characteristics).
Changes:
- Add optional gbr_qos_flow_information field to f1ap_qos_flow_param_t
structure to propagate NGAP GBR QoS parameters to the DU, for scheduling
resource allocation via nr_rrc_get_f1_qos_flow_param.
- Add GBR QoS flow information IE enc/dec in F1AP lib:
- update encode_qos_flow_param() and decode_qos_flow_param()
- update cp/eq/free
- add GBR tests to f1ap_lib_test.c
This commit is a refactoring of commit 398ae02ab9 from !2836
Co-authored-by: Sriharsha Korada <sriharsha.korada@iis.fraunhofer.de>
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Model non-dynamic vs dynamic 5QI characteristics explicitly and propagate the
new layout through NGAP decode and RRC bearer/QoS handling.
Changes:
- Define `non_dynamic_5qi_t`/`dynamic_5qi_t`, PER/PDB bounds, and embed a
`qos_characteristics` union in `pdusession_level_qos_parameter_t`
- Populate the new QoS structures in `fill_qos()`, including optional
allocations for Dynamic 5QI `fiveQI` and NonDynamic `priorityLevelQos`
- Map QoS params to F1AP with `nr_rrc_get_f1_qos_flow_param()` and add range
validation for dynamic priority/PDB/PER and non-dynamic 5QI
- Populate E1 QoS characteristics from the new layout and update QoS modify
handling to manage optional pointer fields (`openair2/RRC/NR/rrc_gNB_NGAP.c`)
- Derive a numeric 5QI via `get_qos_fiveqi()`, handle missing-5QI dynamic flows
conservatively, and extend dedicated-DRB decisions to fall back to dynamic
characteristics
- Add a 5QI range assert in F1AP QoS encoding and extend bearer tests with a
Dynamic 5QI flow
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
DRB QoS IE (mandatory in DRB-Information IE) represents the DRB level QoS,
which shall be computed from multiple QoS flows mapped to the DRB instead
of using only the first QoS flow.
ARP is for admission control/preemption (1-15, 1 = highest priority) and
DRB-level QoS selection should use ARP for admission control decisions.
Changes:
- Use ARP priority (not 5QI priority) for selection (admission control decision)
- Iterate through all flows to find the flow with highest ARP priority (lowest ARP priority_level value
- Add fill_f1_drb_qos to return DRB QoS by value, i.e. QoS characteristics (5QI, priority, delay budget, error rate)
- Replace 'drb.nr.drb_qos = drb.nr.flows[0].param' with proper aggregation
Example: DRB with Flow1 (ARP=10) and Flow2 (ARP=5)
- Old: Would incorrectly use Flow1's QoS
- New: Correctly uses Flow2 (ARP=5) which has higher priority
This commit is a refactoring of commit 398ae02ab9 from !2836
Co-authored-by: Sriharsha Korada <sriharsha.korada@iis.fraunhofer.de>
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
According to 3GPP TS 37.324, there shall be only one default DRB per
SDAP entity (per PDU session). The previous implementation incorrectly
marked all DRBs as default, violating this requirement.
Changes:
- Add default_drb field to nr_sdap_configuration_t to track the default
DRB ID per PDU session
- Arbitrary set default DRB to the first DRB added when creating bearers in a
PDU session
- Update nr_rrc_build_sdap_config_ie() to accept defaultDRB (bool) parameter
instead of hardcoding true
- Use tracked default_drb value when building RRC SDAP Config IE
- Use tracked default_drb value when building E1AP DRB setup structure
Also:
- Fix include style in nr_sdap_configuration.h (<stdbool.h> instead of
"stdbool.h")
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Move 5QI validation from RRC reconfiguration message generation to
where QoS flows are actually added/updated, ensuring validation
happens early in the process.
Changes:
- Remove redundant 5QI validation from rrc_gNB_modify_dedicatedRRCReconfiguration():
that was checking values right before RRC message generation
- Add 5QI validation in add_qos() to reject unsupported 5QI values
during PDU session setup
- Add 5QI validation in nr_rrc_update_qos to skip unsupported 5QI
values during PDU session modify (continues to next flow)
- Add is_5qi_supported() function in rrc_gNB_radio_bearers.c:
validates standardized 5QI values (1-9, 65-90) per 3GPP TS 23.501
Table 5.7.4-1 and checks against the classification map
Also, remove remaining limit to 1 QoS flow per DRB.
Closes#541
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Implement QoS flow multiplexing logic that optimizes DRB usage by classifying
5QI values per 3GPP TS 23.501 Table 5.7.4-1 and applying resource-type-aware
multiplexing limits. The changes are adopted in nr_rrc_add_bearers, which
is the RRC function responsible for adding PDU Sessions and DRBs in RRC.
Key features:
- Classify 5QI by resource type (DC-GBR, GBR, Non-GBR)
- Reuse existing DRBs when QoS characteristics are compatible
- Dedicated DRBs for DC-GBR (5QI 82-90) and high-priority services
- Per-type multiplexing limits: DC-GBR=1, GBR=2, Non-GBR=5
- Aggregate cap: max 5 flows per DRB
Implementation:
- nr_rrc_get_5qi_resource_type():
Maps 5QI values to resource types using lookup table.
DC-GBR: 5QI 82-90, GBR: 5QI 1-4,65-67,71-76, Non-GBR: 5QI 5-11,69-70,79-80.
Unknown 5QIs default to Non-GBR with warning.
- nr_rrc_qos_dedicated_drb():
Identifies 5QIs requiring isolated DRBs (high priority, low-PER).
Includes: DC-GBR: 5QI 82-90, 5QI 4,6-10 (video), 5QI 70 (mission-critical),
5QI 71-73 (live streaming), 5QI 80 (low-latency).
- nr_rrc_count_qos_flows_by_type():
Counts QoS flows mapped to a specific DRB, grouped by resource type.
Used to check capacity and enforce multiplexing limits.
- nr_rrc_find_suitable_drb_for_qos():
Searches existing DRBs in the same PDU session for available capacity.
Checks resource type compatibility, per-type limits, and aggregate cap.
Returns DRB ID if suitable, -1 if new DRB needed.
DC-GBR flows always return -1 (require dedicated DRB).
- nr_rrc_assign_drb_to_qos_flow(), which either reuses a DRB
selected by nr_rrc_find_suitable_drb_for_qos() or creates a new DRB via
nr_rrc_add_drb, assigns its ID to the QoS flow
Note: this commit is multi-QoS ready.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
The new bearer context setup logic is looping through the PDU sessions
to be setup list first and then through the DRB to be setup list.
The function has still room for improvement since e1_bearer_context_setup
is calling a getter for NR_DRB_ToAddModList_t which has another nested
DRB loop. The goal of this commit is to further simplify the logic
by minimizing unnecessary nested loops, improving clarity and preparing
for reuse in Bearer Context Modification.
Main changes:
- Build DRB_ToAddMod list in the DRBs loop and centralize SDAP/PDCP configuration
- Add helpers to fill DRB to be setup and QoS flow handling, to improve organization
and enable reuse in bearer context modification procedures.
Implementation:
- Replace fill_DRB_configList_e1() with fill_rrc_drb_to_addmod()
* Build one NR_DRB_ToAddMod item per DRB from E1 DRB_nGRAN_to_setup
* Accumulate all DRBs into a single NR_DRB_ToAddModList_t per PDU session
- Call e1_add_bearers() once per PDU session with the aggregated list,
- Introduce fill_e1_qos_flows_setup() to populate DRB_nGRAN_setup_t
* Iterate E1AP QoS flows and copy QFIs into the E1 response
- Introduce fill_e1_drb_setup() to encapsulate DRB_nGRAN_setup_t filling
via fill_rrc_drb_to_addmod()
- Refactor e1_bearer_context_setup() to use new helper functions
Note: supports multiple QoS flows per DRB (TS 38.331 compliant)
* Move security parameters setup to caller scope
* Simplify DRB loop logic for better readability
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Refactor GTP-U tunnel creation to align for 3GPP architecture where N3
tunnels are created per PDU session (supporting multiple QoS flows) and
F1-U tunnels are created per DRB. This change simplifies the API and
prepares the codebase for supporting multiple DRBs and QoS flows per
PDU session.
This is the first step of a final design that will consist of:
- 1 GTP-U tunnel create call for each PDU session, each with a DRB mapping
- 1 GTP-U tunnel create call for each DRB (i.e. no QFI, no internal mapping)
API Changes:
- Convert gtpv1u_gnb_create_tunnel_req_t and gtpv1u_gnb_create_tunnel_resp_t
from array-based to scalar fields
* Remove num_tunnels field and array fields (outgoing_teid[], pdusession_id[], etc.)
* Use scalar fields: outgoing_teid, pdusession_id, incoming_rb_id, etc.
- Simplify gtpv1u_create_ngu_tunnel() to handle single tunnel per call
* Remove internal loop that processed multiple tunnels
* Call newGtpuCreateTunnel() once per invocation
* Update response handling to fill single tunnel response
Function Refactoring:
- Split generic drb_gtpu_create() into specialized functions:
* n3_gtpu_create(): Creates N3 tunnel (CU-UP to UPF/core network)
- callback assigned internally: nr_pdcp_data_req_drb, sdap_data_req
- One tunnel per PDU session
- QFI marking
- Supports multiple QoS flows per PDU session
* f1_drb_gtpu_create(): Creates F1-U tunnel (CU-UP to DU or DU side)
- callback assigned internally (cu_f1u_data_req or DURecvCb)
- One tunnel per DRB
- No QFI marking (QFI not used in F1-U)
- Each DRB can carry multiple QoS flows
- Update e1_bearer_context_setup() to loop over DRBs per PDU session
Each item in the PDU Session list contains a list of DRBs, thus
the function helper was adjusted to reflect that:
* Move DRB loop inside PDU session loop
* Create F1-U tunnel for each DRB individually
* Create single N3 tunnel per PDU session (outside DRB loop, with DRB mapping)
Also:
- Add comments to document and improve log messages for clarity
- Consistent error handling with AssertFatal checks
- Update NSA code path (rrc_gNB_nsa.c) to use new scalar API
Note: this commit is already taking into account the multi-QoS flows design
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
This header is pulled by both LTE and NR libraries, therefore is
advised to minimise cross dependencies in LTE/NR. With this change
the only include is common/platform_types.h
Also, remove redundant comments.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Replace incorrect mathematical range check with explicit bounds
validation in nr_sdap_delete_entity(). The previous condition
(pdusession_id) * (pdusession_id - NR_MAX_NB_PDU_SESSIONS) > 0
was mathematically incorrect and could fail to properly validate
PDU session IDs.
PDU session ID validation now correctly rejects values outside
the valid range [0, NR_MAX_NB_PDU_SESSIONS]
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
This is a mandatory IE.
Replace hardcoded ActivityNotificationLevel value with configurable field
in e1ap_bearer_setup_req_t structure, enabling proper encoding/decoding
and testability of different notification levels. ActivityNotificationLevel
is now properly encoded from message structure instead of hardcoded value,
enabling different notification levels (DRB, PDU Session, UE) to be
specified per bearer setup request.
Changes:
- Add activity_notification_level_t enum with values: drb, pdu_session, ue
- Add anl field to e1ap_bearer_setup_req_s structure
- Replace hardcoded E1AP_ActivityNotificationLevel_pdu_session with
dynamic value from msg->anl in encode_E1_bearer_context_setup_request
- Add ActivityNotificationLevel IE dec/eq/cp
- Update test and RRC call sites to initialize anl field
- Add E1AP_ActivityNotificationLevel.h include to e1ap_lib_includes.h
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Replace fixed-size PDU session arrays with dynamically allocated
pointers in E1AP bearer context request/response types to reduce
memory footprint and improve scalability.
Memory usage is now proportional to actual PDU session count
instead of always allocating for maximum capacity.
Impact:
- Callers must allocate and free PDU session arrays; E1AP decode/cp
allocate, free_e1ap_context_setup_request/mod_request free them.
Major changes:
- Request/response types (e1ap_messages_types.h): pduSession, pduSessionMod,
pduSessionRem as pointers in setup/mod request and setup/modif response structs.
- E1AP lib: decode allocates with bounds check; cp/eq/free handle pointer members;
e1ap.c frees setup request after handling.
- CU-UP (cucp_cuup_handler): allocate resp.pduSession and modif.pduSessionMod.
- CU-CP side (cuup_cucp_direct, rrc_gNB, rrc_gNB_NGAP): allocate at E1 request
build and call free after send where needed; rrc_gNB_NGAP includes E1AP free decls.
- Tests (e1ap_lib_test, nr-cuup-load-test): allocate PDU session arrays in helpers.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
When building E1AP PDU Session Resource To Modify items, create
dRB_To_Modify_List_NG_RAN only once if there are DRBs to modify, and add
modify items to that list.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Decode paths for PDU Session Resource To Setup and To Setup/Modify must
accept multiple DRB list entries, aligned with multi-DRB RRC behaviour.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Fix wrong bound in the setup list loop: Bearer Context Modification
Response encoding must populate dRB_Setup_List_NG_RAN from
DRBnGRanSetupList[0..numDRBSetup), not numDRBModified.
In encode_E1_bearer_context_mod_response(), change the DRB Setup List
encoding loop from pdu->numDRBModified to pdu->numDRBSetup.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Replace NGAP_MAX_PDU_SESSION and E1AP_MAX_NUM_PDU_SESSIONS with
shared NR_MAX_NB_PDU_SESSIONS constant. The value (256) is consistent
with both TS 38.331, TS 38.413 and TS 38.463
All protocol layers (NGAP, E1AP, RRC, SDAP) now use a single
shared constant for maximum PDU sessions per UE, ensuring
consistency across the codebase
E1AP_MAX_NUM_PDU_SESSIONS (was 4) is removed from e1ap_messages_types.h
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
- Remove PDU_SESSION_STATUS_DONE and PDU_SESSION_STATUS_REESTABLISHED
from enum and from get_pdusession_status_text().
- Add rrc_gNB_action_from_pdusession_status(): sets xid for all PDU
sessions and derives RRC transaction action from session status
(NEW, TOMODIFY, TORELEASE) or reestablishment. Add macro
ASSERT_PDU_ACTION_SINGLE to enforce at most one active status
(or reestablishment) per transaction.
- rrc_gNB_generate_dedicatedRRCReconfiguration: replace inline loop
and xid/action logic with a single call to the new helper; stop
transitioning NEW to DONE here.
- rrc_gNB_modify_dedicatedRRCReconfiguration: set xid at loop start;
bypass sessions with status != TOMODIFY (instead of >= DONE); remove
FAILED handling and DONE/xid assignments from loop; add xid to log.
- NGAP: INITIAL_CONTEXT_SETUP_RESP and PDUSESSION_SETUP_RESP check
NEW (not DONE) and set ESTABLISHED when reporting success;
PDUSESSION_MODIFY_REQ sets TOMODIFY (not NEW); PDUSESSION_MODIFY_RESP
checks TOMODIFY (not DONE), drops NEW/ESTABLISHED branch, improves
warning text; HANDOVER_REQUIRED considers only ESTABLISHED (drop DONE).
PDU sessions now move directly from NEW or TOMODIFY to ESTABLISHED in
the NGAP response handlers. One RRC reconfiguration corresponds to one
NGAP procedure (single active PDU session status per transaction).
rrc_gNB_modify_dedicatedRRCReconfiguration remains the separate
entry point for PDU Session Modify.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
PDU Session Modify procedures enable the teardown of a subset of DRBs
and, together with multi-QoS handling, of a subset of QoS flows.
Thus, it is necessary to introduce (1) `rm_qos` to remove a specific QFI
from the RRC list of QoS flows and (2) `nr_rrc_remove_drb_by_id`
to remove a specific DRB by ID, upon successful retrieval of the pointer
to its RRC list item.
- Add rm_qos() to remove QoS flows by QFI from PDU session QoS list
- Add nr_rrc_remove_drb_by_id() to remove DRBs by ID from UE DRB list
- Export find_drb_by_pdusession_id() as public functions for reuse
in PDU session modify procedures
These utilities enable QoS flow release and DRB cleanup operations
required for PDU Session Resource Modify Request handling.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
UE Context Modification Request can be triggered by either DRB setup
(from either PDU Session Setup or Modify) or modify (setup/release in PDU Session Modify).
The goal of this commit is to refactor the handling of UE Context Modification Request
messages by improving clarity and reducing code duplication.
Changes:
- Remove overlapping DRB release function `rrc_gNB_send_f1_drb_release_request` and replace with
unified `rrc_send_f1_ue_context_modification_request` that handles both DRB setup and release.
- Remove inefficient `rrc_gNB_generate_UeContextModificationRequest` and inline
its logic into callers using the new unified helper.
- Fix type safety in DRB release handling: change from `int *drb_to_release` to
`f1ap_drb_to_release_t *rel_drbs` to use proper struct type instead of raw int array.
- `rrc_send_f1_ue_context_modification_request` copies DRB arrays internally before freeing,
allowing safe use of stack-allocated arrays by callers.
- Update `rrc_gNB_process_e1_bearer_context_setup_resp` to use unified helper for DRB setup
when F1 context is already active.
- Update `rrc_gNB_process_e1_bearer_context_modif_resp` to DRB release in a single F1 UE
Context Modification Request call (will be later used for DRB setup, improving efficiency)
- Replace magic number `32` with `E1AP_MAX_NUM_DRBS` constant for better maintainability.
- Update E1AP procedures documentation to reflect unified function name.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
The current trigger_bearer_setup is mixing 2 functionalities: (1) setting up
RRC lists in the UE context (e.g. PDU Sessions, DRBs) (2) filling the E1AP
message to trigger Bearer Context Setup.
This commit is separating the two functionalities.
This is necessary to improve the readability of the code flow supporting
the setup of new bearers before the upcoming QoS-related changes.
* Introduce nr_rrc_add_bearers(rrc, UE, n, sessions) to populate UE context
lists (PDU Sessions, one DRB per session, one QoS per DRB).
* Early CU-UP rejection: apply early is_cuup_associated(rrc) checks at call
sites to fail fast before mutating UE context (this check is the reason
why the original function was a bool).
* trigger_bearer_setup goal is to fill Bearer Context setup message upon reception
of PDU sessions to setup, therefore it was changed to fill the bearer context setup
for all PDU session with status PDU_SESSION_STATUS_NEW.
Signature was changed to return void and read the lists from UE context.
The function is also deriving UP keys and building PDU Session and DRB items
to setup via helpers (e.g. fill_e1_pdusession_to_setup to fill PDU Session to
setup items).
* Enforce single DRB per PDU Session, will be updated in a later commit.
Impact
* Each function has now limited and self-conteined scope:
nr_rrc_add_bearers is responsible for update of RRC lists in the UE context.
trigger_bearer_setup is responsible for preparing the E1 Bearer Context message.
* E1 Bearer Context Setup construction is centralized and clearer.
* The flow is now following these steps:
1) receive NG request to setup PDU Sessions
2) check CUUP association first, early failure if check fails
3) add PDU Session and DRBs to UE context lists
4) trigger Bearer Context Setup Request
The same flow applies to PDU Sessions from the Initial Context Setup (initial_PDUs)
with the only difference that those are stored in a separate list (legacy behavior)
and to NG Handover Request processing.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Include NR_asn_constant.h in rrc_gNB_du.c so NR_maxCellIntra and NR_maxCellInter
are defined during compilation.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
- Common source in NR_PDCP_SRC and derive NR_PDCP_SRC_GNB (gNB) and
NR_PDCP_SRC_UE from it; UE no longer compiles cucp_cuup_handler,
cuup_cucp_if, cuup_cucp_direct, cuup_cucp_e1ap.
- NR_L2_SRC_UE uses NR_PDCP_SRC_UE so UE links only common PDCP sources.
- Add L2_NR compile definition PDCP_CUCP_CUUP; wrap nr_pdcp_e1_if_init
call in nr_pdcp_oai_api.c with #ifdef PDCP_CUCP_CUUP so UE does not
reference it.
UE build no longer depends on E1/CU-CP/CU-UP code or symbols; gNB
keeps full PDCP and E1 interface init.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
fix (F1 Handover): do not trigger when no DRB is configured
Prevent triggering F1 handover for UEs without any DRB, to align with
3GPP TS 38.473 clause 8.3.1.2 and avoid initiating an invalid UE Context
Setup Request in the F1 handover flow.
Changes:
- Add a preliminary check in nr_rrc_trigger_f1_ho() to verify at least
one DRB exists in ue->drbs
- Abort F1 HO trigger early when no DRB is present, with warning
Prevent triggering F1 handover for UEs without any DRB, to align
with 3GPP TS 38.473 clause 8.3.1.2 and avoid initiating an invalid
UE Context Setup Request in the F1 handover flow.
Changes:
- Add a preliminary check in `nr_rrc_trigger_f1_ho()` to verify at
least one DRB exists in ue->drbs
- Abort F1 HO trigger early when no DRB is present, with warning
Move the subframe scaling logic outside the PRACH slot loop to prevent the
subframe index from being incorrectly multiplied multiple times when there
are multiple PRACH slots per subframe.
ZMQ radio
This is a zmq radio implementation that attempts to integrate NR UE with
the ocudu project.
OAI integration status:
This can currently be used to connect OAI gnb and OAI UE.
Compilation:
cmake --build . --target nr-softmodem nr-uesoftmodem ldpc params_libconfig zmq_radio
Running
- gNB command:
sudo ./nr-softmodem -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf --gNBs.[0].min_rxtxtime 6 --device.name zmq_radio --zmq.[0].tx_channels tcp://127.0.0.1:4556 --zmq.[0].rx_channels tcp://127.0.0.1:4557
- UE command:
sudo ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --ssb 516 --device.name zmq_radio --zmq.[0].tx_channels tcp://127.0.0.1:4557 --zmq.[0].rx_channels tcp://127.0.0.1:4556
A new CI testcase for 2x2 configuration was added.
OCUDU integration status:
The OAI NR UE enters RRC Connected state.
For more details, please refer to the description of MR !3975.
L1 gNB type0 PDSCH
PDSCH type0 allows frequency allocation via PRB bitmap (type1 is via
start and number of PRBs) allowing for non contiguous allocation in
frequency domain
fix (RRC): do not trigger N2 HO when no active PDU sessions are present
Prevent triggering N2 handover when the UE has no active PDU session by
adding an early check in nr_rrc_trigger_n2_ho(), so we avoid building an
invalid HO Required. This aligns with 3GPP TS 38.413 (§9.2.3.1), where
HANDOVER REQUIRED carries a PDU Session Resource List with at least one
PDU Session Resource Item (range 1..maxnoofPDUSessions).
Relates to #1062 (closed)
Minor fixes/cleanup in NGAP lib
This MR is about a small NGAP-focused cleanup, mainly to reduce clang
warnings and remove dead code.
- Handle unused input parameters in ngap_gNB.c and ngap_gNB_handlers.c.
- Fix clang warning in common/utils/time_meas.h (extra semicolon).
- Removes unused NGAP trace/overload code and related references
(ngap_gNB_trace, ngap_gNB_overload).
Minor fixes to gNB/UE behavior in RFsim
While testing with RFsim thw following issues where found:
- gNB config: wrong PCI was printed during F1 Setup Request preparation
- UE PHY: missing rxdata allocation was causing a crash during intra-freq
measurements