Reads mac->antenna_state to count active TX ports via
__builtin_popcount(nr_get_tx_antenna_bitmask). Caps the partner-search
while-loop bound to (active_tx - 1), so:
active_tx = 4 -> up to 4-way MU-MIMO (3 partners)
active_tx = 3 -> up to 3-way (2 partners)
active_tx = 2 -> up to 2-way (1 partner)
active_tx = 1 -> SU-MIMO only (0 partners)
This couples antenna muting (the existing PHY-side socket control on
port 9999) to spatial parallelism in the MU-MIMO scheduler. Muting a
chain reduces the codebook's orthogonal codeword count, which is the
right semantic for our antenna-muting research: muting reduces the
number of UEs co-scheduled per slot, not the per-UE rate.
Verified runtime behavior on rfsim (30s windows per state):
TX mask 0x0F: 4-way 952 3-way 484 2-way 333 (full 4-TX)
TX mask 0x03: 4-way 2 3-way 8 2-way 5935 (2-TX -> 2-way)
TX mask 0x01: 4-way 0 3-way 0 2-way 11 (1-TX -> SU-MIMO)
Antenna-control commands tested via existing test interface:
echo "SET TX MASK 0x03" | nc -w 2 localhost 9999
Extends the partner search from 1 partner to up to MAX_MU_MIMO_PARTNERS=3
partners, totalling 4 UEs per slot — one per orthogonal x2 class of the
4-port Type I rank-1 codebook.
Orthogonality test relaxed: any distinct x2 (with same x1) is accepted.
The 4 codewords w_(x1,n) for n=0..3 are mutually orthogonal because
they share spatial vector v_x1 and differ only in co-phasing j^n;
<w_a, w_b> = 0 for any a != b.
Each partner gets a distinct DMRS port:
leader -> port 1000 (CDM group 0, mask 0x1)
partner 0 -> port 1001 (CDM group 0, mask 0x2)
partner 1 -> port 1002 (CDM group 1, mask 0x4)
partner 2 -> port 1003 (CDM group 1, mask 0x8)
numDmrsCdmGrpsNoData=2 reserves both DMRS groups.
Class-uniqueness tracked via classes_used bitmask: each successive
partner must be from an unused x2 class.
Pair log: "[nakaolab MU-MIMO] F.S N-way pair RNTI A (x2=0) + RNTI B
(x2=1) + ... on RBs [..]"
Result on rfsim with 9 UEs cycling 4 classes:
8069 total pairings observed
920 4-way (all 4 classes co-scheduled)
2756 3-way
4404 2-way
Phase 1 (rfsim): per-UE deterministic channel injection.
Each UE container sets OAI_UE_CHANNEL_CLASS=k (k in {0..3}). The rfsim
no-chanmod sample-mixing path applies a 4x4 channel:
H^(k)[r,a] = H_orig[r,a] * w_k[a]
where w_k is the k-th codeword of the Type I 4-port rank-1 codebook
(N1=2, N2=1). Multiplying by w_k rotates the channel's optimal PMI
direction to k while preserving the original symmetric kernel's
full-rank reception (so SSB sync still works on all UE classes).
10 UEs cycle through 4 classes (UE_index mod 4), giving 4 mutually
orthogonal PMI populations.
Phase 3 (scheduler): pf_dl partner search now scans connected_ue_list
(not just UE_sched). After leader UE A is allocated, iterate over all
connected UEs, run update_dlsch_buffer/dlsch_to_schedule per candidate,
and pair the first orthogonal-PMI partner that has data + free CCE/PUCCH.
This bypasses PF time-multiplexing — multiple UEs needn't be in
UE_sched simultaneously for MU-MIMO to fire.
Per-slot pairing tag (mumimo_paired_slot in NR_UE_sched_ctrl_t) prevents
double-allocation: incremented per pf_dl call, leader and partner both
tagged on success; subsequent leader iterations skip already-tagged UEs.
Results on rfsim with 10 UEs cycling 4 classes (10-min run):
17000+ pairings observed
Distribution by (leader_class, partner_class):
0->2: 6261 (XOR=2)
3->1: 4382 (XOR=2)
2->0: 2765 (XOR=2)
1->3: 1920 (XOR=2)
All pairs strictly orthogonal per Type I codebook rank-1 rule
(same x1, x2 differ by 2). 2-way MU-MIMO working end-to-end.
Also includes:
- ri_bitlen=0 fix in evaluate_cqi_report (uninitialized r_index)
- OAI_MU_MIMO=1 env to enable, OAI_MU_MIMO_RELAXED=1 for relaxed test
- Diagnostic logs every 200th call: ENTER + per-skip-reason
Two changes on top of the initial MU-MIMO patch (commit 766d0a4):
1. CSI-parse fix in evaluate_cqi_report path: when maxMIMO_layers=1
(and thus ri_Restriction has only one bit set, ri_bitlen=0),
evaluate_ri_report was being skipped, leaving r_index=-1 which
trips the DevAssert(ri>=0) inside evaluate_cqi_report. Fix: when
ri_bitlen=0, pick the single allowed RI directly from the
restriction bitmap. Affects all three reportQuantity branches
(cri_RI_PMI_CQI, cri_RI_LI_PMI_CQI, cri_RI_CQI).
2. MU-MIMO scheduler: relaxed-orthogonality flag and broader
partner search:
- OAI_MU_MIMO_RELAXED=1 bypasses the strict (same-x1, x2-diff-2)
orthogonality test for testbed validation on rfsim where the
symmetric channel makes all UEs report identical PMI.
- Partner search now scans the full UE_sched (skipping leader and
already-paired entries) instead of only iterator+1; this finds
candidates regardless of PF position.
- Diagnostic LOG_W messages on partner-search entry and per-skip
reason (capped to 20 events to avoid log flood).
Findings on this w17 build with 6 UEs at 5Mbps DL each:
- Patch compiles, deploys, gNB does not crash, scheduler reaches
partner-search block on a fraction of slots.
- However eligible_others=0 in every observed partner-search entry:
PF puts only one UE in UE_sched per pf_dl call almost always,
even at cell saturation. The other attached UEs are skipped
earlier (likely HARQ pids pending feedback). So the partner
search has nothing to pair.
- Architectural conclusion: forcing concurrent multi-UE scheduling
on OAI's PF + finite-HARQ scheduler likely needs scanning
connected_ue_list (not just UE_sched), and may need broader
refactoring to pre-allocate slot resources for MU-MIMO pairs.
Adds opt-in MU-MIMO downlink co-scheduling to the production
proportional-fair scheduler (pf_dl). When OAI_MU_MIMO=1 is set in
the gNB process env, after the leader UE is allocated we look ahead
in the PF-sorted candidate list for an orthogonal-PMI partner. If
found and the partner can secure its own CCE+PUCCH, both UEs share
the same RB allocation with distinct DMRS CDM groups (port 1000 vs
port 1001) and are forced to the same MCS/TBS.
Orthogonality test (4-port Type I rank-1 codebook, N1=2, N2=1):
same x1 (same beam), x2 differing by 2 (co-phasing pairs {0,2} or
{1,3}). Both UEs must report rank-1.
Default OFF — set OAI_MU_MIMO=1 to enable. Builds on the upstream
FAPI/PHY MU-MIMO plumbing (commits 3707d52c95, 498d241d75,
9952996c5d) which carries antenna-port and DMRS-CDM metadata down
to the PHY transmit path.
Brings the O-RAN compliant antenna muting feature (originally introduced
on the 'new' branch) onto the latest upstream 2026.w17 tag.
Files added:
openair1/PHY/NR_TRANSPORT/nr_antenna_state.{c,h}
openair1/PHY/NR_TRANSPORT/nr_antenna_control.{c,h}
Files modified (integration hooks):
CMakeLists.txt, executables/nr-gnb.c
openair1/PHY/INIT/nr_init.c, openair1/PHY/defs_gNB.h
openair1/PHY/MODULATION/{beamforming.c,nr_modulation.h,nr_beamforming.c}
openair1/SCHED_NR/nr_ru_procedures.c
openair2/LAYER2/NR_MAC_gNB/mac_proto.h
openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_{primitives,dlsch,uci}.c
Conflicts resolved:
- defs_gNB.h: kept upstream's new headers + appended antenna_state.h
- nr_init.c: dropped reference to upstream-removed nr_srs_info init,
kept nr_init_antenna_state() call
- beamforming.c: upstream moved nr_beam_precoding into new file
nr_beamforming.c; nr_beam_precoding_with_muting added there with
upstream's signature (no slot param)
- nr_modulation.h: aligned _with_muting decl to upstream signature
- nr_ru_procedures.c: muting check applied around upstream's new
fft_shift in nr_feptx, and around per-port memcpy in nr_feptx_prec
- gNB_scheduler_uci.c: SINR-based MCS hint uses get_dl_nrOfLayers(NULL,
sched_ctrl, ...) since nrmac is not in scope at the call site
- mac_proto.h: get_dl_nrOfLayers signature updated to take gNB_MAC_INST*
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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
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).
Fix EMA cold-start for noise and SNR/RSSI measurements
Initialize n0_subband_power and power control avg_snr/avg_rssi directly
from the first measurement instead of starting from zero.
Starting from zero causes the EMA to converge slowly, leading to
underestimated noise power at gNB startup. This results in inflated SNR
estimates, which triggers UE uplink power ramp-up, antenna saturation,
and a positive feedback loop of increasing noise.
L1 RX: use queues instead of arrays and linear search for PUCCH, PUSCH, SRS, PRACH
This MR is an attempt to reduce the time L1 RX searches in array for the
next job to process, and instead use a queue. This queue is a FIFO,
because the various jobs (FAPI messages) to process come in order, and
need to be processed in order. The MR (hopefully, to be measured)
reduces the amount of time spent searching for the next UE (because the
next job is always at the beginning of the queue), and should scale
better for many UEs.
It does the following:
- introduce two helper libraries for (1) Frame.Slot calculation (sfn_t),
already introduced in !3521 (merged) commit 3102068e, and (2) a ring
buffer with fixed size
- use sfn_t and ring buffer (gNB->pucch_queue) to remove the linear
array for PUCCH (gNB->pucch)
- use sfn_t and ring buffer (gNB->pusch_queue) for some PUSCH lookups.
Because we need to still store PUSCH contexts, gNB->pusch is still
there
- use sfn_t and ring buffer (gNB->srs_queue) to remove the linear array
for SRS (gNB->srs)
- use sfn_t and ring buffers (gNB->prach_ru_queue and
gNB->prach_l1rx_queue) to remove the linear array for PRACH
(gNB->prach_list)
- some minor cleanups, e.g., additional loops over the PUSCH array,
using const, using pointers instead of indices, etc
Miscellaneous code improvements
- A fix in a yaml config file as reported by @Abdo-Gaber
- proper positioning of static functions in a couple of gNB scheduler
files
- some effort to split NR from LTE code in compilation
- harmonization of macros for unused variables
at RRC we don't store CSI-MeasConfig information so in some scenarios (see #1063) we may not have the full pictures to understand if what RRC received is a valid configuration
we verify at L2 instead after updating CSI-MeasConfig and if it fails we send a message to RRC
Add encode/decode helpers and basic round-trip tests for NR SIB2, SIB3
and SIB4 in test_asn1_msg.cpp to ensure we produce decodable messages
with expected fields. Extend SIB4 coverage with an
inter_freq_carrier_freq_info_ranges test that exercises boundary and
out-of-range values for carrier reselection parameters and checks
encoder failures for invalid configurations.
Changes:
- Introduce encode_and_decode_sib2, encode_and_decode_sib3 and
encode_and_decode_sib4 helpers that call do_SIB2_NR, do_SIB3_NR,
do_SIB4_NR and uper_decode and assert non-empty, non-null byte
arrays and successful decoding.
- Add sib2_basic_encode_decode, sib3_basic_encode_decode and
sib4_basic_encode_decode tests that populate minimal but
representative NR_SIB2_t, NR_SIB3_t and NR_SIB4_t instances and
verify selected decoded fields match the originals.
- Add inter_freq_carrier_freq_info_ranges test that builds an NR_SIB4_t
with NR_InterFreqCarrierFreqInfo_t and varies different offsets and
thresholds to confirm valid combinations encode and invalid ones
are rejected.
- Add comprehensive documentation header explaining the structure's role
as single source of truth for neighbor cell information across multiple
protocols (NGAP/XnAP handover, measurement config, DU validation, SIB3/SIB4)
- Add detailed field comments documenting protocol-specific mappings:
* Core identification fields (gNB_ID, nrcell_id, physicalCellId)
* Frequency/RF parameters (absoluteFrequencySSB, subcarrierSpacing, band)
* Handover target identification (plmn, tac)
- Document NGAP/XnAP IE mappings for plmn and tac fields
Remove the isIntraFrequencyNeighbour field and all code that sets or
uses it, simplifying neighbour cell handling and avoiding redundant
state in the RRC gNB code. The flag duplicated information that can be
derived from the neighbour absoluteFrequencySSB and the serving cell
SSB ARFCN, and intra-frequency neighbours are logged in the SIB3
preparation flow.
Changes:
- Remove isIntraFrequencyNeighbour from nr_neighbour_cell_t in
openair2/RRC/NR/nr_rrc_defs.h
- Delete is_intra_frequency_neighbour() and
label_intra_frequency_neighbours() helpers from
openair2/RRC/NR/rrc_gNB_du.c
- Remove calls to label_intra_frequency_neighbours() from
rrc_gNB_process_f1_setup_req() and
rrc_gNB_process_f1_du_configuration_update() in rrc_gNB_du.c
- Stop setting .isIntraFrequencyNeighbour in the local
nr_neighbour_cell_t neighbourConfig initializer in
openair2/RRC/NR/rrc_gNB_mobility.c
Add SIB4 encode/decode helpers and populate SIB4 from configured
inter-frequency carriers and neighbour cells, wiring it into DU F1
Setup handling and MAC SystemInformation.
Changes:
- Add do_SIB4_NR() and NR_SIB4.h inclusion in asn1_msg.c/asn1_msg.h to
UPER-encode NR_SIB4_t into a byte_array_t.
- Extend nr_mac_configure_other_sib() in NR_MAC_gNB/config.c with an
NR_SIB_4 case that validates the SIB container, decodes NR_SIB4_t via
uper_decode, logs failures, and appends SIB4 to SystemInformation.
- Introduce build_inter_freq_carrier_from_cfg() and
get_sib4_inter_freq_neighbors() in rrc_gNB_du.c to build
NR_InterFreqCarrierFreqInfo_t and NR_SIB4_t from inter-frequency and
neighbour cell configuration, skipping invalid or empty carriers.
- Handle NR_SIB_4 in rrc_gNB_process_f1_setup_req() by deriving SIB4
from neighbour/inter-frequency configuration, encoding it with
do_SIB4_NR(), validating the resulting byte_array_t and adding the SI
message for the DU cell when encoding succeeds.
Introduce NR SIB3 encoding in RRC and wire SIB3 neighbour information
into CU–DU F1 Setup and DU SystemInformation. Extend MAC to decode NR
SIB3 from CU-provided SIB containers and attach the decoded SIB3 to the
DU SystemInformation structure.
Changes:
- Add NR_SIB3 ASN.1 include and a do_SIB3_NR() encoder in asn1_msg
so SIB3 can be serialized into a byte_array_t buffer.
- Introduce get_q_offset_asn1() and get_sib3_intra_freq_neighbors() in
rrc_gNB_du.c to build an intra-frequency neighbour cell list for SIB3,
mapping q_OffsetCell dB values to NR_Q_OffsetRange and optionally
filling q_RxLevMinOffsetCell and q_QualMinOffsetCell.
- Limit the number of intra-frequency neighbours in SIB3 to
NR_maxCellIntra, logging a warning and skipping additional cells when
the limit is reached.
- Hook SIB3 construction and encoding into rrc_gNB_process_f1_setup_req()
so SIB type 3 entries are added to the F1 Setup Response when
neighbour configuration and matching neighbours are available.
- Handle NR_SIB_3 in nr_mac_configure_other_sib() by validating the CU
SIB3 container buffer, decoding it with uper_decode into an NR_SIB3_t,
and attaching the resulting SIB3 to the MAC SystemInformation via
add_sib_to_systeminformation().
Introduce typed SIB3/SIB4 neighbour and inter-frequency carrier
configuration structures, wire them into the RRC neighbour and gNB
instances, and centralise parsing and bounds checking of per-frequency
SIB4 parameters from the gNB frequency list.
Changes:
- Define SIB3/SIB4 reselection and offset bound macros in gnb_config.c
and apply them when parsing SIB4 frequency_config and
per-carrier q_RxLevMin/t_ReselectionNR.
- Add add_inter_freq and parse_inter_freq_list helpers in gnb_config.c
to populate a shared inter_freqs seq_arr_t from gNB_CONFIG_STRING_GNB_LIST
frequency_list entries, enforcing unique (ARFCN,SCS) combinations and
logging duplicates.
- Extend neighbour cell parameters in gnb_paramdef.h with SIB3 per-
neighbour offset fields and define frequency_list/frequency_config
option names, descriptor tables, and index constants for SIB4 inter-
frequency configuration.
- Introduce nr_neighbour_cell_neighbor_offset_t, nr_neighbour_cell_sib3_t,
nr_neighbour_cell_sib4_freq_t, nr_neighbour_cell_sib4_t, and
nr_inter_freq_cfg_t in nr_rrc_defs.h, and extend nr_neighbour_cell_t
and gNB_RRC_INST with sib3/sib4 and inter_freqs members respectively.
- udpated fill_neighbour_cell_configuration to use GET_PARAMS_LIST
with params bound check
Introduce a typed SIB2 cell reselection configuration, load it from the
gNB configuration into the RRC gNB instance, and use it to build and
encode SIB2 instead of relying on a fixed SIB2 definition.
Validate SIB2 parameters against explicit bounds and make the SIB2
encoder consume a pre-built ASN.1 structure with safer error handling.
Changes:
- Add SIB2 mobility timer and q-HystSF enums plus SIB2 config structs
(`sib2_speed_state_reselection_pars_t`, `sib2_config_t`) and a
`sib2_config` field on `gNB_RRC_INST` in `nr_rrc_defs.h`.
- Define SIB2 configuration option names, defaults
(`GNB_CONFIG_STRING_SIB2_*`, `GNBSIB2PARAMS_DESC`)
in `gnb_paramdef.h` for q_Hyst, thresholds, mobility timers, scaling
factors and deriveSSB_IndexFromCell.
- Add `sib2_config` parameter keys, defaults, and range/value checks in
`gnb_paramdef.h` (`GNBSIB2PARAMS_DESC`).
- Add SIB2 `fill_sib2_configuration()` in `gnb_config.c` to read SIB2
parameters from the config file log the resulting configuration and
store it in `rrc->sib2_config` via `RCconfig_NRRRC()`.
- Add `get_q_hyst_asn1()` and `get_sib2_from_cfg()` in `rrc_gNB_du.c`, and
update `rrc_gNB_process_f1_setup_req()` to encode/add SIB2 from config with
explicit encode-failure handling and logging.
- Change `do_SIB2_NR` signature in `asn1_msg.h/.c` to
`byte_array_t do_SIB2_NR(const NR_SIB2_t *sib2)`, remove internal default
SIB2 construction, and add ASN.1 constraint/encode error logging.
Unify SIB container handling by introducing a typed SIB enum and storing
SIB payloads as byte_array_t across common NR types, F1AP helpers, MAC,
and RRC DU setup code.
Changes:
- Include byte_array support in nr_common.h, add nr_sib_type_t (NR_SIB_1–NR_SIB_21),
and change nr_SIBs_t to hold only nr_sib_type_t SIB_type.
- Switch f1ap_sib_msg_t in f1ap_messages_types.h to use a byte_array_t SI_container
instead of raw pointer and length fields.
- Update F1AP encode/decode, equality, copy, and free helpers in
f1ap_interface_management.c to work on SI_container.buf / SI_container.len and
use eq_byte_array, copy_byte_array, and free_byte_array.
- Adapt F1AP tests in f1ap_lib_test.c to build and inspect SIB containers via
SI_container.buf and SI_container.len.
- Replace magic SIB numbers with nr_sib_type_t values in gnb_config.c
(get_sys_info and fill_du_sibs) to validate and configure DU SIBs.
- Rework nr_mac_configure_other_sib in NR_MAC_gNB/config.c to decode SIB2
from a byte_array_t container, fix freeing by releasing the decoded sib2 on
failure, and use NR_SIB_2 / NR_SIB_19 for CU/DU SIB selection.
- Add an add_si_msg helper in rrc_gNB_du.c and refactor the SIB2 branch of
rrc_gNB_process_f1_setup_req to populate cell->SI_msg from encoded local
byte array while iterating SIBs with FOR_EACH_SEQ_ARR.
Tighten neighbour-cell config parsing by enforcing parameter constraints in
the descriptor and switching parsing code to name-based lookups with gpd.
Changes:
- Update `GNBNEIGHBOURCELLPARAMS_DESC` in `openair2/GNB_APP/gnb_paramdef.h`
to add checks for `physical id`, `absoluteFrequencySSB`, `scs`, `band`
`tracking_area_code`.
- Remove neighbour-cell parameter index macros.
- Refactor `parse_neighbour_cells_list` in `openair2/GNB_APP/gnb_config.c`
to use `gpd()` lookups for neighbour fields instead of fixed indexes.
- Extend `parse_neighbour_cells_list` with an `n_cell_params` argument and
update `fill_neighbour_cell_configuration` to pass
`sizeofArray(ncell_params)`.
Inline neighbour cell arrays into the RRC neighbour configuration and
update RRC/DU helpers to use const-aware access and shared iteration
helpers when walking neighbour lists and building measurement configs.
Changes:
- Change neighbour_cells in neighbour_cell_configuration_t from a
seq_arr_t * to an embedded seq_arr_t field.
- Initialize and populate the embedded neighbour_cells directly in
parse_neighbour_cells_list in gnb_config.c, dropping dynamic
allocation of the neighbour list container.
- Refactor get_neighbour_cell_by_pci and nr_rrc_get_measconfig in
rrc_gNB.c to access the embedded neighbour_cells via const pointers,
introduce a local meas_cfg and a3_event_list, and iterate neighbour
cells with FOR_EACH_SEQ_ARR.
- Treat neighbour cell configuration entries as const in rrc_gNB_du.c
(get_cell_neighbour_list, label_intra_frequency_neighbours,
valid_du_in_neighbour_configs) and iterate neighbour lists with
FOR_EACH_SEQ_ARR instead of index-based loops.
Outer gNB neighbour_list entries now only declare the serving cell
nr_cellid. The code resolves that field with gpd instead of a fixed column
index.
Changes:
- gnb_paramdef.h: remove unused NEIGHBOUR_CELL_PHYSICAL_ID from
GNB_NEIGHBOUR_LIST_PARAM_LIST (keep NRCELLID only).
- gnb_config.c: in fill_neighbour_cell_configuration, set nr_cell_id
from gpd
Refactor gNB configuration code to share PLMN extraction logic and to
split neighbour-cell configuration into smaller helpers with safer
allocation and clearer list handling.
Changes:
- Add `extract_plmn_from_params()` in `gnb_config_common.c` and declare
it in `gnb_config_common.h` to centralize PLMN extraction from
`paramdef_t`.
- Update `set_plmn_config()` to use `extract_plmn_from_params()` when
filling the PLMN array instead of duplicating field assignments.
- Refactor `fill_neighbour_cell_configuration()` in `gnb_config.c` to
delegate per-cell neighbour parsing to
`parse_neighbour_cells_list()` and sorting to
`sort_neighbour_configuration()`, simplifying the main loop.
- Use `extract_plmn_from_params()` when parsing neighbour PLMNs in
`parse_neighbour_cells_list()` and log each neighbour with its PLMN,
PCI, and other radio parameters before adding it to the sequence.
- Switch allocation of `rrc->neighbour_cell_configuration` in
`fill_neighbour_cell_configuration()` from `malloc` to
`malloc_or_fail()` to enforce consistent handling of allocation
failures.
Thread-pool support for TX symbol processing.
This MR adds thread-pool support for TX symbol processing. It allows modulation
/mapping/layer-precoding to run in parallel and offers a speedup of around 3
compared to single-thread execution. This is particularly important for large
bandwidths and 4 or more TX antenna ports where the precoding operation is quite
computationally-intensive.
Please see the description of !3489 for the performance comparison results and
the nr_dlsim timing measurements.
Fix for NULL pucch-ResourceCommon at MSG4
Field pucch-ResourceCommon, used for ACK of MSG4, in some scenarios was
overwritten by RRCSetup before being used. Storing it in advance prevents
the segfault. In addition there is a clenaup of similar procedures at gNB.
* Add option `--L1s.L1_num_tx_sym_per_thread` for the softmodems and `-Y` for `nr_dlsim`
to provide the number of symbols processed per thread.
It defaults to 0 which makes that every symbols are processed in one thread.
* The last symbol processing task is processed in the L1 TX thread.