To run the test with OAI UE and vrtsim, use the following commands, assuming
the executables are in the build directory.
OAI O-RU:
./nr-oru -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/ru.band77.mu1.106rb.1x1.conf --device.name vrtsim --vrtsim.role server
OAI 7.2 gNB:
./nr-softmodem -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band77.mu1.106rb.fhi.1x1.conf
OAI NR UE:
./nr-uesoftmodem -C 4049760000 -r 106 --numerology 1 --ssb 516 --device.name vrtsim
Signed-off-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
Support for aperiodic SRS at gNB
Add support for aperiodic SRS, which currently, if activated, is
hardcoded to be periodically scheduled every 160 TTIs. The configuration
file has been changed, and instead of
do_SRS = 0/1
is now
do_SRS = "none"/"periodic"/"aperiodic"
Reviewed-By: Robert Schmidt <robert.schmidt@openairinterface.org>
Reviewed-By: Maxime Elkael <m.elkael@northeastern.edu>
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>
fix: issue 1054 - Config: Creating New Array members via command line arguments
Before this change, if you wanted to use --rfsimulator.[0].serveraddr
server on the command line but if you had no rfsimulator block in your
config file, it would just ignore it and print:
[CONFIG] unknown option: --rfsimulator.[0].serveraddr
[CONFIG] unknown option: server
This is because the config module only processes array members that
already exist in the config file. If the array is empty, the command
args are never checked.
What I changed is, in config_getlist() in config_userapi.c, after it
finishes processing existing array parameters, it checks whether a new
parameter is needed. If so, it matches with the list of parameters
first, then the highest index is found for that parameter using the
strtol,
"--rfsimulator.[0].serveraddr",
"--rfsimulator.[2].serveraddr",
What I changed is, in config_getlist() in config_userapi.c, after it
finishes processing existing array parameters, it checks whether a new
parameter is needed. If so, it matches with the list of parameters
first, then the highest index is found for that parameter using the
strtol,
"--rfsimulator.[0].serveraddr",
"--rfsimulator.[2].serveraddr",
"--rfsimulator.[4].serverport",
"--rfsimulator.[1].serveraddr",
It sets the index as 4, allocates 4 slots, memory is managed via
standard functions then it fills the gap of all the indices.
this closes#1054
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Reviewed-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
Before this change, if you wanted to use --rfsimulator.[0].serveraddr server
on the command line but if you had no rfsimulator block in your config file,
it would just ignore it and print:
[CONFIG] unknown option: --rfsimulator.[0].serveraddr
[CONFIG] unknown option: server
This is because the config module only processes array members that already
exist in the config file. If the array is empty, the command args are never checked.
What I changed is, in config_getlist() in config_userapi.c, after it finishes
processing existing array parameters, it checks whether a new parameter is given
in CLI.
The array number in the parameter(num) should match with the valid index of
that specific array
--cfg.[0].value 1 creates one array with one element
valid_index = num = 1
--cfg.[0].value 1 --cfg.[0].value 2 creates an array with two elements
if the previous CLI number repeats increments the "num"
valid_index = num = 2
--cfg.[1].value 1 --cfg.[0].value 2 error
valid_index < num, expects 0.
Remove the gNB_MAC_INST.eth_params_s, since it's only purpose is to
store what can be on the stack.
For the Aerial log message, don't print an empty prefix but what is
actually used for Aerial.
- 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
Adjust ssPBCH_BlockPower in FHI7.2 configs
ssPBCH_BlockPower is the average EPRE of the resources elements that carry
secondary synchronization signals in dBm. In OAI, the SSB is the same level
as all the rest, so we can compute ssPBCH_BlockPower from RU TX power and
bandwidth using:
ssPBCH_BlockPower = P_TX(dBm) − 10 x log10(N_RB x 12)
where:
- P_TX is the RU transmit power
- 24 dBm for indoor RUs (configurable on the RU)
- 35 dBm for outdoor RUs (configurable on the RU)
- N_RB is the number of resource blocks for the configured bandwidth
- 12 corresponds to the number of subcarriers per RB
[FHI72] Fix long PRACH format
The problem was that xran_is_prach_slot() compared if the current slot is the
scheduled one. However, this becomes irrelevant if long PRACH format used.
Successfully tested end-to-end the PRACH index 7 with TDD DDDDDDDSUU and Benetel
v2.0.5.
Only static long PRACH configuration verified, i.e. PRACH C-plane
is ignored by the RU.
Note: Introducing `N_ZC` and `num_prbu` parameters is needed for testing
with xran F release. However, in the K release, this information is
stored in xran_rx_packet_ctl struct.
Synchronize multiple gNBs by aligning the slot boundaries
Currently, we derive frame and slot number based on proc->timestamp_rx
using
proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_subframe*10))&1023;
proc->tti_rx = get_slot_from_timestamp(proc->timestamp_rx, fp);
This ignores the samples
proc->timestamp_rx % fp->samples_per_frame
while computing the frame and slot number creating a mis-alignment with
the slot boundaries. A detailed description of the slot misalignment
in a pictorial representation can be seen in an attachment in the MR [1].
We fix this alignment issue by compensating these samples during the
first reception.
We can test the synchronization of the multiple gNBs from the estimated
ToAs from the PRS in the Downlink and the estimated ToAs from the SRS in
the Uplink using rfsim.
In order to test this, make sure you build gNB and nrUE along with the
telnetsrv flag using the option --build-lib telnetsrv.
Also, enable the following log in the function
nr_est_srs_timing_advance_offset() in
openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c to observe SRS ToAs
LOG_I(NR_PHY, "SRS estimatd ToA %d [RX ant %d]: TA offset %d, TA offset ns %d (max_val %ld, mean_val %ld, max_idx %d)\n", srs_toa, ant, *ta_offset, *ta_offset_nsec, max_val, mean_val, max_idx);
Furthermore, update the option Active_gNBs = 2; in
targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.nr.prs.fr1.106prb.conf to enable
decoding PRS transmitted from two gNBs
To run:
nrUE:
sudo ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --uicc0.imsi 001010000000001 --rfsim --phy-test -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.nr.prs.fr1.106prb.conf --rfsimulator.serveraddr server
gNB 0:
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf --gNBs.[0].min_rxtxtime 6 --rfsim --phy-test --rfsimulator.[0].serveraddr 127.0.0.1 --rfsimulator.[0].options chanmod --rfsimulator.[0].modelname AWGN --telnetsrv
gNB 1:
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.prs.band78.fr1.106PRB.usrpx310.conf --gNBs.[0].min_rxtxtime 6 --rfsim --phy-test --rfsimulator.[0].serveraddr 127.0.0.1 --rfsimulator.[0].options chanmod --rfsimulator.[0].modelname AWGN --telnetsrv
When we run the nrUE, gNB0 and gNB1, we can see the following logs
nrUE:
[PHY] [gNB 0][rsc 0][Rx 0][sfn 976][slot 2] DL PRS ToA ==> 0.0 / 2048 samples, peak channel power -16.4 dBm, SNR +4.0 dB, rsrp -42.2 dBm
[PHY] [gNB 1][rsc 0][Rx 0][sfn 976][slot 3] DL PRS ToA ==> 0.0 / 2048 samples, peak channel power -16.4 dBm, SNR +4.0 dB, rsrp -42.2 dBm
gNB 0:
[NR_PHY] SRS estimatd ToA 0 [RX ant 0]: TA offset 31, TA offset ns 0 (max_val 99820162, mean_val 80176, max_idx 0)
gNB 1:
[NR_PHY] SRS estimatd ToA 0 [RX ant 0]: TA offset 31, TA offset ns 0 (max_val 98784562, mean_val 79369, max_idx 0)
From the above logs, when we run the rfsim and when no delays introduced, we can observe the following results
In the Downlink at the UE, the estimated ToAs using PRS from both gNB0
and gNB1 are 0 and in the uplink, the ToA estimated from the SRS
transmitted by the UE at both the gNBs are also 0. This indicates that
both the gNBs are synchronized along with their slot boundaries. We also
highlight that this is not the case in the current develop branch since
the slot boundaries are not aligned.
We also can test the multi gNB synchronization by introducing delays
using telnet as follows,
Introduce new_offset (delay) of 4 samples to the gNB 0 from UE in the
uplink as follows,
openairinterface5g$ echo rfsimu setdistance rfsimu_channel_enB0 20 | ncat --idle 1 127.0.0.80 9080
softmodem_gnb> rfsimu_setdistance_cmd: new_offset 4, new (exact) distance 19.518 m, new delay 0.000065 ms
Ncat: Idle timeout expired (1000 ms).
We can oberve this delay of 4 samples being reflected in the estimated
SRS ToAs at gNB 0 while not changing the ToA in gNB 1
[NR_PHY] SRS estimatd ToA 4 [RX ant 0]: TA offset 31, TA offset ns 65 (max_val 98803636, mean_val 79430, max_idx 8)
similarly, Introduce new_offset (delay) of 2 samples to the gNB 1 from
UE in the uplink as follows,
openairinterface5g$ echo rfsimu setdistance rfsimu_channel_enB0 10 | ncat --idle 1 127.0.0.81 9081
softmodem_gnb> rfsimu_setdistance_cmd: new_offset 2, new (exact) distance 9.759 m, new delay 0.000033 ms
Ncat: Idle timeout expired (1000 ms).
We can oberve this delay of 2 samples being reflected in the estimated
SRS ToAs at gNB 1 while not changing the ToA in gNB 0
[NR_PHY] SRS estimatd ToA 2 [RX ant 0]: TA offset 31, TA offset ns 32 (max_val 98962768, mean_val 79552, max_idx 4)
Closes#897
[1] https://gitlab.eurecom.fr/oai/openairinterface5g/-/merge_requests/3892
Since the grand-parent commit, if possible, the gNBs synchronize on a
slot-level boundary. Some configuration files/command line overrides
left the same SSB position for two DUs in RFsim-based handover
scenarios, which then makes that the UE cannot decode the SSB.
This commit changes the positions such that this is possible again. In
the F1 HO docker-compose
(ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml), we set it
to 2 to send only one SSB (not 2 with bitmap 3).
Following the tutorial in the RF simulator, the PDU session cannot
be established because the Slice Differentiator to request(nssai_sd)
parameter in the ue.conf file is 1(integer) but in the documentation
the default value of the nssai_sd is 0xFFFFF(meaning "no SD")
Now the nssai_sd parameter is removed in the ue.conf to establish the
PDU session.
Compute ssPBCH_BlockPower from RU max TX power and bandwidth
ssPBCH_BlockPower = P_TX(dBm) − 10 x log10(N_RB x 12)
Assume P_TX = 24 dBm for indoor RUs and 35 dBm for outdoor RUs.
[FHI72] [xran F] Handle fragmented (un)compressed packets
In both E and F, the radio-transport fragmentation is not supported, and
all the "fragmented" (not seen as fragments in the xran, only as
sections) packets contain "E-bit" equal to 1. Per spec, the value 1 for
"E-bit" signifies the last fragment of one symbol. For more info, please
see "ecpriSeqid" section in the spec.
In E:
- nRBStart and nRBSize is updated according to the sent/received packet;
- max sections = 1;
- when a packet is fragmented, the xran uses memcpy(pos, iq_data_start,
size) function, and nothing is stored in start_prbu , num_prbu ,...
In F:
- nRBStart and nRBSize is only used for C-plane messages;
- nPrbElm represents the number of sections for DL only;
- based on the nPrbElm, each section contains UP_nRBStart and UP_nRBSize
parameters which represent the start and number of PRBs in one section
or one fragment;
- when a packet is fragmented, the xran uses nSecDesc and sec_desc to
extract the packet section content, and the data is stored in
start_prbu , num_prbu ,...
Previous work on the fragmentation in F:
- #884
- !3394 - only increases the XRAN_MAX_FRAGMENT from 4 to 6, since it was
only tested with BFP 8, but not end-to-end unfortunately. But this MR
fixes all the issues.
Tested with VVDN RU, 2x2, 16 bits, 100MHz, 30kHz, MTU <= 9216 B, and
Quectel UE RM520N-GL Revision: RM520NGLAAR03A03M4G.
Even though the jumbo frame has 9600 bytes by the spec, the max MTU is limited to the MTU of a switch, if any used.
However, the value can be < max MTU of a switch.
This is very important for fragmentation purposes. If not properly set, the PDSCH packets will be missing.
Add Ethernet PDU session support and make PDU session request configurable
This MR adds support for Ethernet PDU sessions, and makes PDU sessions
configurable: per-PDU session ID, type (IPv4/IPv4v6/IPv6/Ethernet [1]),
DNN, NSSAI.
Concretely, it adds a new configuration file section pdu_sessions below
uicc0 that looks like this if everything is specified (default values
are shown):
uicc0:
[...]
pdu_sessions:
- id: 1
type: "IPv4"
nssai_sst: 1
nssai_sd: 0xffffff
dnn: "oai"
It is possible to list multiple PDU sessions (add new line - id: 2 to
request a second PDU session). It is backwards-compatible to the current
PDU session configuration (uicc0.dnn/nssai_sst/etc), the idea being that
either legacy or new configuration could be used, but (1) if
pdu_sessions exist, it will overwrite the legacy configuration, and (2)
multiple PDU sessions, and type, can only be configured using the new
config. The old parameters --extra-pdu-id and --default-pdu-id are not
accepted anymore. Documentation has been added to the UE tutorial.
It is possible to test an Ethernet PDU session [1]. It is possible to
test the PDU session inside the UE by verifying it has an TAP interface
oaitap_ue1, and ARPing the data network (arping has been added to
oai-nr-ue container for that purpose):
ip addr add 192.168.72.140/26 dev oaitap_ue1 # same subnet as data network!
ip link set dev oaitap_ue1 up
arping -c 20 -I oaitap_ue1 192.168.72.135 # will send ARP request in Ethernet frame to get IP address of data network
[1] See description MR !3769 for more information. On the UE side, only
the type has to be changed to "Ethernet".