Add SRS LS and RSRP measurement logging for indoor positioning research
This MR adds measurement logging support for indoor positioning research
based on OAI gNB radio measurements.
The goal is to collect timestamped SRS LS channel estimates and averaged
RSRP values during experiments. These measurements are used offline for
Add T traces to store raw RSRP reports and SRS LS estimates
Reviewed-By: Francesco Mani <email@francescomani.it>
Reviewed-By: Robert Schmidt <robert.schmidt@openairinterface.org>
Reviewed-By: Rakesh Mundlamuri <rakesh.mundlamuri@openairinterface.org
1. Beam index:
So far rxdataF and txdataF had beam number as first index to separate freq
domain samples of antenna ports when mulitple beams are served in a slot.
This works fine when the beam is applied to entire symbol / slot but not
suitable for digital beamforming. This commit removes the beam number index
from the data buffers and the buffers hold all the antenna ports in the first
dimension. The antenna port index to be used for each UE in a MU-MIMO or
concurrent analog beam scenario is signalled by L2 via dedicated fields in
the FAPI PDU.
2. Beam ID array changes:
- The gNB and RU struct has a 2D array to hold beam IDs for all symbols in a
frame and all antenna ports. The order is now changes to first: symbol index
and second: antenna port because the RU access all ports' beam IDs for each
symbol / slot at a time. This ordering is optimal for maximizing cache hits.
- The type is now changed from int to uint16_t. So far the L1 had to deduce
the beam number index (done in beam_index_allocation()) from the beam ID sent
by L2 and this is done by initializing the beam_id array to -1 which denoted
no beam id set. Now since L2 explicitely passes the port indices, there is no
need for denoting if a beam id is assigned or not to a slot in L1. And
uint16_t matches with the type used by FAPI to carry beam ID. Since the type
is uin16_t, beam_id array is initialized to 0 and the check for -1 when
passing beam ID 0 to xran is also removed.
3. Number of antenna ports:
The removal of beam index from rxdataF and txdataF buffers resulted in all
antenna ports to be in a single vector. The number of logical ports passed to
L1 is not N1*N2*XP*number of beams per period. The buffer initialization
function is updated to reflect this change. DAS reference config file is
updated in accordance with these changes.
4. oaioran.c:
Remove the check of beam ID = -1 for setting nPrbElm = 0. This is a hack for
LiteON to supposedely improve performance according to Mario. If it's true
then a proper fix would be to pass allocation information from L1 and use it
instead of beam ID.
Signed-off-by: Sakthivel Velumani <s.velumani@northeastern.edu>
Add T trace events for SRS least-squares channel estimate samples and individual MAC RSRP reports. These traces support indoor positioning research and offline dataset generation through the existing OAI tracing workflow instead of custom CSV logging.
Signed-off-by: Bingyu Zhou <s240331012@stu.cqupt.edu.cn>
3GPP RRC SRS-ResourceMapping.startPosition is defined as an offset
counted backwards from the end of the slot (TS 38.331). OAI MAC was
previously passing the raw RRC value straight into the FAPI SRS PDU's
time_start_position field, and every L1 consumer was then re-deriving
the absolute symbol via NR_SYMBOLS_PER_SLOT - 1 - time_start_position.
External L1 implementations (e.g. NVIDIA Aerial / cuBB) interpret
time_start_position as the absolute symbol index where the SRS lives,
which left the MAC and external L1 disagreeing by one inversion. The
result was SRS being scheduled on the wrong OFDM symbol and the
returned channel matrix being all-zero for most occasions.
Make MAC populate time_start_position with the absolute symbol index
(NR_SYMBOLS_PER_SLOT - 1 - startPosition) and remove the matching
inversion from the L1 consumers so the value flows through unchanged.
The UE side and the shared SRS generator are harmonized to the same
absolute-symbol convention so generate_srs_nr can read nr_srs_info->
l_offset directly regardless of caller (gNB or UE).
* gNB MAC: gNB_scheduler_srs.c invert at PDU-build time; consume the
already-inverted value when computing l0 for the VRB mask.
* gNB PHY: srs_rx.c (fill + get_signal) and SCHED_NR/phy_procedures_
nr_gNB.c use srs_pdu->time_start_position directly as l0.
* UE MAC: nr_ue_scheduler.c invert at PDU-build time.
* UE PHY: phy_procedures_nr_ue.c consumes srs_config_pdu->time_start_
position directly as l0.
* Shared SRS generator: nr_phy_common_srs.c reads nr_srs_info->l_offset
as the absolute symbol index, matching both gNB and UE call sites.
* Simulators: srssim.c and ulsim.c populate both the gNB-side and
UE-side SRS PDUs with the absolute symbol index so the nr_srssim
and nr_ulsim unit tests pass with the new convention.
Signed-off-by: Gabriele Gemmi <g.gemmi@northeastern.edu>
Use log_ul_fd_dmrs, log_ul_fd_pusch_iq, log_ul_fd_chan_est_dmrs_pos,
log_ul_fd_chan_est_dmrs_interpl, log_ul_payload_rx_bits.
Remove redundant T_ACTIVE() guards and old timestamp formatting.
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
Use two queues for PRACH processing:
- prach_ru_queue: pass jobs from TX thread (scheduler) to RU thread. For
split 8, the RU thread itself handles PRACH processing; for split 7.2,
it is the library that is responsible for handling PRACH messages (see
oran_fh_if4p5_south_in())
- prach_l1rx_queue: after jobs have been handled in RU thread, use this
queue to pass jobs to the RX thread. There, preamble detection is
performed, and RACH.indication FAPI messages are filled if a preamble
has been detected.
Together, these queues replace a linear search in a global array that
has been modified by three threads at the same time. The design ensures
that access now is thread-safe, and with less overhead.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Use the spsc queue to pass jobs from TX thread (scheduler) to RX thread
(handling those jobs), reducing the amount spent searching for SRS jobs,
clarifying the design, and making it thread-safe.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
The structure in which was snr will be a "SRS job" in a follow-up
commit, so the snr parameter cannot be stored in there (and it is also
not necessary to do so, as it can be local to the function handling
nr_srs_rx_procedures()).
Correctly read SRS SNR through FAPI message in nr_ulsim. Switch to SRS
BEAMMANAGEMENT as only this message returns the actual SNR (unlike
CODEBOOK). Add asserts to check what is returned is valid data in the
sense of the test.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Remove useless logging defines. Move srs_estimated_channel_time to where
it is used. Prepare for the next commit by moving UL_INFO to earlier
inside phy_procedures_gNB_uespec_RX().
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
This means that as of this commit, the signal has to be permanently
regenerated. In fact, with the SRS queue to be introduced in a follow-up
commit, we don't have an easy way to cache the sequence generation, as
there is no "index" to which we could refer to (hence, caching would be
tricky).
Instead, the next commits further refactor this to reduce the time for
SRS sequence generation as well as the memory footprint.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Use the spsc queue to pass jobs from TX thread (scheduler) to RX thread
(handling those jobs), reducing the amount spent searching for PUSCH
jobs, clarifying the design, and making it thread-safe.
Since the PUSCH contexts have to be stored somewhere, there is still a
single iteration over all contexts. Removing that is left for future
work. Thus, this commit (together with previous commits) reduces the
number of iterations over all PUSCH entries, only iterating over the
actually requested PUSCH jobs. On the other hand, because only the RX
thread iterates over PUSCH contexts, it should be thread-safe.
Remove flag "handled", which is always 0.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Pass pointers directly instead of ULSCH_id. Put const where possible and
applicable.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Set the FAPI message in nr_ulschsim correctly in line with what
nr_ulsch_procedures() expected. Add an AssertFatal() to verify that the
assumed length of DMRS in the simulator and what is actually set in the
FAPI message matches. Finally, the internal nr_get_G() code (looping
over all PUSCH) does not double the DMRS because Nl == 3 || Nl == 4, so
harmonize in the simulator.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
It is pointless to iterate ulsch_to_decode to find the number of jobs if
we can simply pass it to the function.
Use an additional {} block to limit the amount of indentation.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Pass pointer to data. This necessitates to move delay from
NR_gNB_ULSCH_t (ULSCH data, including transport channels etc) to
NR_gNB_PUSCH (lower-PHY PUSCH data):
1. This allows to pass a single pointer to nr_pusch_channel_estimation()
2. To me, delay estimation seems to be a lower-PHY calculation, so it
fits better anyway.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Use the spsc queue to pass jobs from TX thread (scheduler) to RX thread
(handling those jobs), reducing the amount spent searching for PUCCH
jobs in an array, clarifying the design, and making it thread-safe.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Fix fill_srs_channel_matrix
Fix incorrect SRS subcarrier mapping in fill_srs_channel_matrix
The previous implementation of fill_srs_channel_matrix assumed an incorrect
SRS subcarrier mapping, leading to wrong indexing of the estimated channel
in frequency domain.
Further unused arguments cleanup
More fixes for unused function arguments (see #1057),
add_compile_options(-Wunused-parameter) added in folders:
- nfapi
- openair2
- openair3
- USRP
- rfsimulator
The previous implementation of fill_srs_channel_matrix assumed an incorrect SRS subcarrier mapping, leading to wrong indexing of the estimated channel in frequency domain
- all RAN code, CI code, configuration files, dockerfiles, in CSSL v1.0
- all deployment code (openshift, charts, ancillary files like shell
scripts), in MIT
- documentation in CC-BY-4.0
- exceptions might apply and are listed in NOTICE
- there is a new LICENSES folder with all licenses
- CONTRIBUTIONS.md has been updated accordingly
For automated changes based on OAI PL v1.1:
perl -i~ -0pe 's/\/\*.*Licensed to the OpenAirInterface.*openairinterface.org\n#?/\/*\n * SPDX-License-Identifier: LicenseRef-CSSL-1.0\n/s' **/*.{c,h,cpp}
perl -i~ -0pe 's/\/\*.*Licensed to the OpenAirInterface.*openairinterface.org\n#?/\/*\n * SPDX-License-Identifier: LicenseRef-CSSL-1.0\n/s' **/*.ts
perl -i~ -0pe 's/<!--.*Licensed to the OpenAirInterface.*openairinterface.org\n.*-->/<!-- SPDX-License-Identifier: LicenseRef-CSSL-1.0 -->/s' **/*.xml
The rest (cmake, files with missing license, cmake) manually.
Remove the \file directive, as it is always superfluous because the
current file is implicit [1]:
> If the file name is omitted (i.e. the line after \file is left blank)
> then the documentation block that contains the \file command will belong
> to the file it is located in.
Author names and e-mails are not relevant for us: it can always be
inferred from git blame, and is often outdated.
Eurecom code has been contributed and was under OAI PL v1.0/v1.1.
For the cpack package contact: put generic email address that is
independent of an individual and that will remain reachable.
[1] https://www.doxygen.nl/manual/commands.html#cmdfile
replace static allocation of max antennas in a dynamic structure for gnb rach
NB_ANTENNAS_RX was used in 5G by mistake
there was also a error in O-RU implementation, with no consequences
(index not in right order)
Use flat buffer for txdataF in gNB L1
This MR changes txdataF buffer format to hold freq domain data starting from
PRB0 instead of circular buffer that starts from PRB N/2. The motive is to
simplify RE mapping function in L1 and copying data to xran lib.
So far txdataF buffer has DC RE as the first element. This was prefered
most likely to avoid memcpy before iFFT but comes with a small
complexity in RE mapping functions.
Instead, we use a flat buffer that holds freq domain data starting from
first negative SC. After resource mapping is done on all channels, each
OFDM symbol is shifted before iFFT so that the buffer start with DC RE.
This reduces complexity in mapping functions and later on when passing
beam IDs to 7.2 split RU especially when a beam is associated to
interleaved RB and/or REs.
There is already a memcpy in place to copy txdataF from gNB stuct to RU
struct. So this change does not introduce new memcpy.
Remove unused function arguments
Some of them, because there are hundreds if not thousands. Warnings at compilation time can be enabled using -Wunused-parameter.
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