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")
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
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.
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.
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.
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.
[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
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
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.
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>
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.
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.
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
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), 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.
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
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
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.
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