Merge branch 'integration_2025_w43' into 'develop'

Integration: `2025.w43`

* !3605 Support beam index in OAI 7.2 Fronthaul Interface
* !3709 Fixes for T-Tracer to work with NR-UE
* !3712 Restore UE Capability IE after RRCReestablishment
* !3716 Remove unused ULSCH measurements at gNB
* !3603 UE symbol based PDCCH receiver
* !3708 Add monolithic N2 handover test pipeline with B210 and Quectel
* !3719 Remove Benetel-specific radio drivers
* !3710 [CI] Update the Push to DockerHub Stage
* !3711 CI: Multiple adjustments
* !3717 Initialize NCC=0 on NGAP Initial Context Setup (3GPP TS 33.501 §6.9.2.1.1)
* !3720 fix direct bugs of not used RU_RX_SLOT_DEPTH defined constant
* !3714 Improve handling of selection of RSRP/SINR report via configuration file
* !3519 Refactor SDAP adaptation work for QoS
* !3698 Other CSI measurement fixes
* !3699 Updates for Feature Set

Closes #1008

See merge request oai/openairinterface5g!3713
This commit is contained in:
Robert Schmidt
2025-10-24 15:39:07 +00:00
126 changed files with 2216 additions and 4769 deletions
+46
View File
@@ -1,5 +1,51 @@
# RELEASE NOTES: #
## [v2.3.0](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v2.3.0) -> July 2025. ##
General new features and improvements (both RAN and UE):
- Preliminary support for RedCap UEs
- Support for NTN LEO scenarios including SIB19 and channel emulation (see
doc/RUNMODEM.md)
- VRTSIM: new shared memory realtime radio (see develop/radio/vrtsim/README.md)
- Support for TDD pattern 2
- Support for long PRACH
- Support for SIB2
- Add unit tests using ctest (see doc/UnitTests.md)
Stability and bug fixes:
- Improve various procedures (e.g., RRC reestablishment, RRC Reject, ...)
- Add improvements for ImScope
- Bugfixes in the entire stack (e.g., #803, #805, #810, #812, #818, #852, #878,
#884, #890, #895, #901, #907, #932, #939 ...)
- Documentation updates
- And many other small fixes, like memory leaks, crashes, ...
RAN changes (gNB/CU/CU-CP/CU-UP/DU/DU-high/DU-low):
- Stability and performance improvements when running with 4-layer DL MIMO
- Stability and performance improvements when running with 2-layer UL MIMO
- Interoperability testing with Metanoia Jura and Foxconn RUs
- Support of O-RAN 7.2 M-plane (Start-up procedure including configuration
management, see also doc/ORAN_FHI7.2_Tutorial.md)
- Upgrade OSC FHI (xran) from E to F release
- Refactoring of LDPC interface and performance improvements
- Support for nFAPI in all scenarios for FR1 (see doc/nfapi.md)
- Support at least 32 UEs concurrently
- Improve robustness when running in split modes (F1, E1)
- Add basic support for beam management in FR2
- Add support for O1 on DU (see also https://gitlab.eurecom.fr/oai/o1-adapter)
- E2 agent: Support for multiple E2SM-RC report service styles
nrUE changes:
- Refactoring of threading towards better code and performance
- Add or rework various procedures (e.g., RA with C-RNTI, Going to Idle, RA, ...)
- Refactor and extend NAS implementation (e.g., Service Request, Registration
Request, Service Acept, Service Reject, ...)
- Support for continuous frequency offset compensation
- Reduce minimum RX-to-TX time to 3
Regression:
- Multiple BWPs do not work reliably on gNB; use tag 2025.w17
## [v2.2.0](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v2.2.0) -> November 2024. ##
General 5G improvements (both gNB and UE):
+3 -2
View File
@@ -271,14 +271,15 @@ pipeline {
when { expression {doBuild && "PUSH".equals(env.gitlabActionType)} }
steps {
script {
triggerSlaveJob ('RAN-DockerHub-Push', 'DockerHub-Push')
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
triggerSlaveJob ('RAN-DockerHub-Push', 'DockerHub-Push')
}
}
}
post {
failure {
script {
echo "Push to Docker-Hub KO"
currentBuild.result = 'FAILURE'
failingStages += '\n * RAN-DockerHub-Push'
}
}
+14 -3
View File
@@ -84,9 +84,20 @@ pipeline {
sh "docker login -u ${DH_Username} -p ${DH_Password} > /dev/null 2>&1"
sh "docker login -u oaicicd -p oaicicd ${OAI_Registry} > /dev/null 2>&1"
listOfImages.eachWithIndex { item, iindex ->
sh "docker rmi ${DH_Account}/${item}:${WEEK_TAG} ${DH_Account}/${item}:develop || true"
sh "docker buildx imagetools create --tag ${DH_Account}/${item}:${WEEK_TAG} ${OAI_Registry}/${item}:armv8_develop-${WEEK_SHA} ${OAI_Registry}/${item}:develop-${WEEK_SHA}"
sh "docker buildx imagetools create --tag ${DH_Account}/${item}:develop ${OAI_Registry}/${item}:armv8_develop-${WEEK_SHA} ${OAI_Registry}/${item}:develop-${WEEK_SHA}"
if (["oai-gnb", "oai-nr-ue", "oai-nr-cuup"].contains(item)) {
// For images built on AMD64 and ARMv8 Jetson
echo "Pushing image '${item}' for both AMD64 and ARM64 architectures with tags: ${WEEK_TAG} and develop"
sh "docker rmi ${DH_Account}/${item}:${WEEK_TAG} ${DH_Account}/${item}:develop || true"
sh "docker buildx imagetools create --tag ${DH_Account}/${item}:${WEEK_TAG} ${OAI_Registry}/${item}:armv8_develop-${WEEK_SHA} ${OAI_Registry}/${item}:develop-${WEEK_SHA}"
sh "docker buildx imagetools create --tag ${DH_Account}/${item}:develop ${OAI_Registry}/${item}:armv8_develop-${WEEK_SHA} ${OAI_Registry}/${item}:develop-${WEEK_SHA}"
} else {
sh "docker pull --quiet ${OAI_Registry}/${item}:develop-${WEEK_SHA}"
sh "docker image tag ${OAI_Registry}/${item}:develop-${WEEK_SHA} ${DH_Account}/${item}:develop"
sh "docker image tag ${OAI_Registry}/${item}:develop-${WEEK_SHA} ${DH_Account}/${item}:${WEEK_TAG}"
sh "docker push --quiet ${DH_Account}/${item}:develop"
sh "docker push --quiet ${DH_Account}/${item}:${WEEK_TAG}"
}
sh "docker rmi ${DH_Account}/${item}:${WEEK_TAG} ${DH_Account}/${item}:develop ${OAI_Registry}/${item}:develop-${WEEK_SHA} || true"
}
// Proxy is not following the same pattern.
sh "docker image tag proxy:develop ${DH_Account}/proxy:develop"
@@ -135,11 +135,11 @@ gNBs =
# pattern1
# dl_UL_TransmissionPeriodicity
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
dl_UL_TransmissionPeriodicity = 6;
nrofDownlinkSlots = 7;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
dl_UL_TransmissionPeriodicity = 5;
nrofDownlinkSlots = 3;
nrofDownlinkSymbols = 10;
nrofUplinkSlots = 1;
nrofUplinkSymbols = 2;
ssPBCH_BlockPower = -25;
}
@@ -16,7 +16,7 @@ gNBs =
////////// Physical parameters:
do_SINR = 1;
CSI_report_type = "ssb_sinr";
min_rxtxtime = 6;
disable_harq = 1;
cu_sibs = [2];
@@ -106,8 +106,7 @@ gNBs =
pucchGroupHopping = 0;
hoppingId = 40;
p0_nominal = -90;
# ssb_PositionsInBurs_BitmapPR
# 1=short, 2=medium, 3=long
ssb_PositionsInBurst_Bitmap = 1;
# ssb_periodicityServingCell
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
@@ -0,0 +1,237 @@
Active_gNBs = ( "gNB-OAI");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
gNBs =
(
{
////////// Identification parameters:
gNB_ID = 0xe00;
gNB_name = "gNB-OAI";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({ mcc = 001; mnc = 03; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0xffffff }) });
// Include neighbour configuration for N2 handover
@include "neighbour-config-ho.conf"
nr_cellid = 12345678L;
////////// Physical parameters:
servingCellConfigCommon = (
{
#spCellConfigCommon
physCellId = 0;
# downlinkConfigCommon
#frequencyInfoDL
# this is 3610.56 MHz
absoluteFrequencySSB = 679104;
dl_frequencyBand = 77;
# this is 3599.94 MHz
dl_absoluteFrequencyPointA = 678388;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing = 1;
dl_carrierBandwidth = 51;
#initialDownlinkBWP
#genericParameters
# this is RBstart=27,L=48 (275*(L-1))+RBstart
initialDLBWPlocationAndBandwidth = 13750;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 1;
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 12;
initialDLBWPsearchSpaceZero = 0;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 77;
#scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
ul_subcarrierSpacing = 1;
ul_carrierBandwidth = 51;
pMax = 20;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 13750;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
#rach-ConfigCommon
#rach-ConfigGeneric
prach_ConfigurationIndex = 98;
#prach_msg1_FDM
#0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 13;
preambleReceivedTargetPower = -96;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6;
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
#one (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14;
#ra_ContentionResolutionTimer
#(0..7) 8,16,24,32,40,48,56,64
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
#1 = 839, 2 = 139
prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
msg1_SubcarrierSpacing = 1,
# restrictedSetConfig
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 40;
p0_nominal = -90;
ssb_PositionsInBurst_Bitmap = 1;
# ssb_periodicityServingCell
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
ssb_periodicityServingCell = 2;
# dmrs_TypeA_position
# 0 = pos2, 1 = pos3
dmrs_TypeA_Position = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
subcarrierSpacing = 1;
#tdd-UL-DL-ConfigurationCommon
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
referenceSubcarrierSpacing = 1;
# pattern1
# dl_UL_TransmissionPeriodicity
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
dl_UL_TransmissionPeriodicity = 6;
nrofDownlinkSlots = 7;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = -25;
}
);
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// AMF parameters:
amf_ip_address = ({ ipv4 = "172.21.6.109"; });
NETWORK_INTERFACES :
{
GNB_IPV4_ADDRESS_FOR_NG_AMF = "172.21.19.98";
GNB_IPV4_ADDRESS_FOR_NGU = "172.21.19.98";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
ul_prbblack_SNR_threshold = 10;
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
prach_dtx_threshold = 120;
pucch0_dtx_threshold = 100;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
RUs = (
{
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 0;
att_rx = 0;
bands = [77];
max_pdschReferenceSignalPower = -27;
max_rxgain = 114;
eNB_instances = [0];
clock_src = "external";
time_src = "external";
}
);
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config :
{
global_log_level ="info";
hw_log_level ="info";
phy_log_level ="info";
mac_log_level ="info";
rlc_log_level ="info";
pdcp_log_level ="info";
rrc_log_level ="info";
ngap_log_level ="debug";
f1ap_log_level ="debug";
};
@@ -14,7 +14,6 @@ key = "fec86ba6eb707ed08905757b1bb44b8f";
opc= "C42449363BBAD02B66D16BC975D77CC1";
dnn= "oai";
nssai_sst=1;
nssai_sd=16777215;
}
MACRLCs = (
-1
View File
@@ -4,7 +4,6 @@ uicc0 = {
opc= "c42449363bbad02b66d16bc975d77cc1";
dnn= "oai";
nssai_sst=1;
nssai_sd=66051;
}
thread-pool = "-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1"
+11 -11
View File
@@ -44,7 +44,7 @@
<testCase id="111111">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<node>obelix</node>
<node>localhost</node>
<images>oai-enb oai-lte-ue</images>
</testCase>
<testCase id="800813">
@@ -88,16 +88,16 @@
<class>Attach_UE</class>
<desc>Attach OAI UE</desc>
<id>l2sim4g_ue</id>
<nodes>obelix</nodes>
<nodes>localhost</nodes>
</testCase>
<testCase id="020001">
<class>Ping</class>
<desc>Ping trf-gen from LTE-UE 1</desc>
<id>l2sim4g_ue</id>
<nodes>obelix</nodes>
<nodes>localhost</nodes>
<svr_id>l2sim4g_ext_dn</svr_id>
<svr_node>obelix</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>0</ping_packetloss_threshold>
</testCase>
@@ -106,9 +106,9 @@
<class>Ping</class>
<desc>Ping LTE-UE 1 from trf-gen</desc>
<id>l2sim4g_ext_dn</id>
<nodes>obelix</nodes>
<nodes>localhost</nodes>
<svr_id>l2sim4g_ue</svr_id>
<svr_node>obelix</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>0</ping_packetloss_threshold>
</testCase>
@@ -117,9 +117,9 @@
<class>Iperf</class>
<desc>Iperf UDP Downlink</desc>
<id>l2sim4g_ue</id>
<nodes>obelix</nodes>
<nodes>localhost</nodes>
<svr_id>l2sim4g_ext_dn</svr_id>
<svr_node>obelix</svr_node>
<svr_node>localhost</svr_node>
<iperf_args>-u -t 30 -b 1M -R</iperf_args>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
@@ -129,9 +129,9 @@
<class>Iperf</class>
<desc>Iperf UDP Uplink</desc>
<id>l2sim4g_ue</id>
<nodes>obelix</nodes>
<nodes>localhost</nodes>
<svr_id>l2sim4g_ext_dn</svr_id>
<svr_node>obelix</svr_node>
<svr_node>localhost</svr_node>
<iperf_args>-u -t 30 -b 3M</iperf_args>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
@@ -149,7 +149,7 @@
<class>Clean_Test_Server_Images</class>
<always_exec>true</always_exec>
<desc>Clean Test Images on Test Server</desc>
<node>obelix</node>
<node>localhost</node>
<images>oai-enb oai-lte-ue</images>
</testCase>
@@ -103,16 +103,16 @@
<class>Attach_UE</class>
<desc>Attach OAI UE (Wait for IP)</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
</testCase>
<testCase id="020011">
<class>Ping</class>
<desc>Ping Traffic-Gen from LTE-UE</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim4g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -121,9 +121,9 @@
<class>Ping</class>
<desc>Ping LTE-UE from Traffic-Gen</desc>
<id>rfsim4g_ext_dn</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim4g_ue</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -136,8 +136,8 @@
<iperf_args>-u -t 30 -b 2M -R</iperf_args>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
<nodes>acamas</nodes>
<svr_node>acamas</svr_node>
<nodes>localhost</nodes>
<svr_node>localhost</svr_node>
</testCase>
<testCase id="030011">
@@ -148,8 +148,8 @@
<iperf_args>-u -t 30 -b 1M</iperf_args>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
<nodes>acamas</nodes>
<svr_node>acamas</svr_node>
<nodes>localhost</nodes>
<svr_node>localhost</svr_node>
</testCase>
<testCase id="100011">
@@ -83,9 +83,9 @@
<class>Ping</class>
<desc>Ping Traffic-Gen from LTE-UE</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim4g_enb_nos1</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -94,9 +94,9 @@
<class>Ping</class>
<desc>Ping LTE-UE from eNB</desc>
<id>rfsim4g_enb_nos1</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim4g_ue</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -105,9 +105,9 @@
<class>Iperf</class>
<desc>Iperf UDP DL</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim4g_enb_nos1</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_args>-u -t 30 -b 2M -R</iperf_args>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
@@ -117,9 +117,9 @@
<class>Iperf</class>
<desc>Iperf UDP UL</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim4g_enb_nos1</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_args>-u -t 30 -b 1M</iperf_args>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
@@ -103,16 +103,16 @@
<class>Attach_UE</class>
<desc>Attach OAI UE (Wait for IP)</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
</testCase>
<testCase id="020011">
<class>Ping</class>
<desc>Ping Traffic-Gen from LTE-UE</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim4g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -121,9 +121,9 @@
<class>Ping</class>
<desc>Ping LTE-UE from Traffic-Gen</desc>
<id>rfsim4g_ext_dn</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim4g_ue</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -132,9 +132,9 @@
<class>Iperf</class>
<desc>Iperf UDP DL</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim4g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_args>-u -t 30 -b 2M -R</iperf_args>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
@@ -144,9 +144,9 @@
<class>Iperf</class>
<desc>Iperf UDP UL</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim4g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_args>-u -t 30 -b 1M</iperf_args>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
@@ -103,16 +103,16 @@
<class>Attach_UE</class>
<desc>Attach OAI UE (Wait for IP)</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
</testCase>
<testCase id="020011">
<class>Ping</class>
<desc>Ping Traffic-Gen from LTE-UE</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim4g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -121,9 +121,9 @@
<class>Ping</class>
<desc>Ping LTE-UE from Traffic-Gen</desc>
<id>rfsim4g_ext_dn</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim4g_ue</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -132,9 +132,9 @@
<class>Iperf</class>
<desc>Iperf UDP DL</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim4g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_args>-u -t 30 -b 2M -R</iperf_args>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
@@ -144,9 +144,9 @@
<class>Iperf</class>
<desc>Iperf UDP UL</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim4g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_args>-u -t 30 -b 1M</iperf_args>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
@@ -80,9 +80,9 @@
<class>Iperf2_Unidir</class>
<desc>Iperf2 UDP DL</desc>
<id>rfsim4g_ue_fembms</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim4g_enb_fembms</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_args>-u -t 30 -b 2M</iperf_args>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
@@ -80,9 +80,9 @@
<class>Iperf</class>
<desc>Iperf UDP DL</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim4g_enb_nos1</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_args>-u -t 30 -b 2M -R</iperf_args>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
@@ -103,9 +103,9 @@
<class>Ping</class>
<desc>Ping Traffic-Gen from LTE-UE</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim4g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -114,9 +114,9 @@
<class>Ping</class>
<desc>Ping LTE-UE from Traffic-Gen</desc>
<id>rfsim4g_ext_dn</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim4g_ue</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -125,9 +125,9 @@
<class>Iperf</class>
<desc>Iperf UDP DL</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim4g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_args>-u -t 30 -b 2M -R</iperf_args>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
@@ -137,9 +137,9 @@
<class>Iperf</class>
<desc>Iperf UDP UL</desc>
<id>rfsim4g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim4g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_args>-u -t 30 -b 1M</iperf_args>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
@@ -76,16 +76,16 @@
<class>Attach_UE</class>
<desc>Attach OAI UE (Wait for IP)</desc>
<id>rfsim5g_ue rfsim5g_ue2 rfsim5g_ue3</id>
<nodes>acamas acamas acamas</nodes>
<nodes>localhost localhost localhost</nodes>
</testCase>
<testCase id="020021">
<class>Ping</class>
<desc>Ping ext-dn from all NR-UEs</desc>
<id>rfsim5g_ue rfsim5g_ue2 rfsim5g_ue3</id>
<nodes>acamas acamas acamas</nodes>
<nodes>localhost localhost localhost</nodes>
<svr_id>rfsim5g_5gc_fixed_ip</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
+19 -19
View File
@@ -107,7 +107,7 @@
<class>Attach_UE</class>
<desc>Attach OAI UE (Wait for IP)</desc>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
</testCase>
<testCase id="000024">
@@ -122,9 +122,9 @@
<class>Ping</class>
<desc>Ping ext-dn from all NR-UEs</desc>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -132,7 +132,7 @@
<testCase id="030020">
<class>Custom_Command</class>
<desc>Simulate a DL radio channel with noise (3 dB)</desc>
<node>acamas</node>
<node>localhost</node>
<command>echo channelmod modify 0 noise_power_dB 3 | ncat --send-only 192.168.71.181 8091</command>
</testCase>
@@ -141,9 +141,9 @@
<desc>Iperf (DL/3Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 3M -t 20 -R</iperf_args>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
@@ -153,9 +153,9 @@
<desc>Iperf (UL/3Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 3M -t 20</iperf_args>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
@@ -163,7 +163,7 @@
<testCase id="040001">
<class>Custom_Command</class>
<desc>Trigger Reestablishment</desc>
<node>acamas</node>
<node>localhost</node>
<command>echo ci force_reestab | ncat 192.168.71.171 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment'</command>
</testCase>
@@ -171,9 +171,9 @@
<class>Ping</class>
<desc>Ping ext-dn from NR-UE</desc>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i0.5 -w25</ping_args>
<ping_packetloss_threshold>80</ping_packetloss_threshold>
</testCase>
@@ -181,56 +181,56 @@
<testCase id="040002">
<class>Custom_Command</class>
<desc>Verify Reestablishment</desc>
<node>acamas</node>
<node>localhost</node>
<command>echo ci get_reestab_count | ncat 192.168.71.150 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1'</command>
</testCase>
<testCase id="040021">
<class>Custom_Command</class>
<desc>Simulate a disruption of DL radio channel (ploss 55)</desc>
<node>acamas</node>
<node>localhost</node>
<command>echo channelmod modify 0 ploss 55 | ncat 192.168.71.181 8091</command>
</testCase>
<testCase id="040022">
<class>Custom_Command</class>
<desc>Get UE sync state (UE ID 0)</desc>
<node>acamas</node>
<node>localhost</node>
<command>echo ciUE sync_state 0 | ncat 192.168.71.181 8091 | grep -E UE_NOT_SYNC</command>
</testCase>
<testCase id="040023">
<class>Custom_Command</class>
<desc>Restoration of the original DL channel conditions (ploss 20)</desc>
<node>acamas</node>
<node>localhost</node>
<command>echo channelmod modify 0 ploss 20 | ncat 192.168.71.181 8091</command>
</testCase>
<testCase id="040024">
<class>Custom_Command</class>
<desc>Get UE sync state (UE ID 0)</desc>
<node>acamas</node>
<node>localhost</node>
<command>echo ciUE sync_state 0 | ncat 192.168.71.181 8091 | grep -E UE_CONNECTED</command>
</testCase>
<testCase id="040025">
<class>Custom_Command</class>
<desc>Trigger Handover</desc>
<node>acamas</node>
<node>localhost</node>
<command>echo ci trigger_f1_ho | ncat 192.168.71.150 9090</command>
</testCase>
<testCase id="040026">
<class>Custom_Command</class>
<desc>UE (1) connected to DU-PCI 0?</desc>
<node>acamas</node>
<node>localhost</node>
<command>echo ci fetch_du_by_ue_id 1 | ncat 192.168.71.150 9090 | grep "3584"</command>
</testCase>
<testCase id="040027">
<class>Custom_Command</class>
<desc>UE (1) connected to DU-PCI 1?</desc>
<node>acamas</node>
<node>localhost</node>
<command>echo ci fetch_du_by_ue_id 1 | ncat 192.168.71.150 9090 | grep "3585"</command>
</testCase>
@@ -70,16 +70,16 @@
<class>Attach_UE</class>
<desc>Attach OAI UE (Wait for IP)</desc>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
</testCase>
<testCase id="020011">
<class>Ping</class>
<desc>Ping ext-dn from NR-UE</desc>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -88,9 +88,9 @@
<class>Ping</class>
<desc>Ping NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ue</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -100,9 +100,9 @@
<desc>Iperf (DL/3Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 3M -t 30 -R</iperf_args>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
@@ -112,9 +112,9 @@
<desc>Iperf (UL/3Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 3M -t 30</iperf_args>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
+20 -20
View File
@@ -125,16 +125,16 @@
<class>Attach_UE</class>
<desc>Attach OAI UE (Wait for IP)</desc>
<id>rfsim5g_ue rfsim5g_ue2 rfsim5g_ue3 rfsim5g_ue4 rfsim5g_ue5 rfsim5g_ue6 rfsim5g_ue7 rfsim5g_ue8 rfsim5g_ue9 rfsim5g_ue10</id>
<nodes>acamas acamas acamas acamas acamas acamas acamas acamas acamas acamas</nodes>
<nodes>localhost localhost localhost localhost localhost localhost localhost localhost localhost localhost</nodes>
</testCase>
<testCase id="020001">
<class>Ping</class>
<desc>Ping ext-dn from NR-UE</desc>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -143,9 +143,9 @@
<class>Ping</class>
<desc>Ping NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ue</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -154,9 +154,9 @@
<class>Ping</class>
<desc>Ping ext-dn from Second NR-UE</desc>
<id>rfsim5g_ue2</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -165,9 +165,9 @@
<class>Ping</class>
<desc>Ping Second NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ue2</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -176,9 +176,9 @@
<class>Ping</class>
<desc>Ping ext-dn from both UEs</desc>
<id>rfsim5g_ue rfsim5g_ue2</id>
<nodes>acamas acamas</nodes>
<nodes>localhost localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -187,9 +187,9 @@
<class>Ping</class>
<desc>Ping ext-dn from all UEs</desc>
<id>rfsim5g_ue rfsim5g_ue2 rfsim5g_ue3 rfsim5g_ue4 rfsim5g_ue5 rfsim5g_ue6 rfsim5g_ue7 rfsim5g_ue8 rfsim5g_ue9 rfsim5g_ue10</id>
<nodes>acamas acamas acamas acamas acamas acamas acamas acamas acamas acamas</nodes>
<nodes>localhost localhost localhost localhost localhost localhost localhost localhost localhost localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25 -s 1016</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -199,9 +199,9 @@
<desc>Iperf (DL/3Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 3M -t 20 -R</iperf_args>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
@@ -211,9 +211,9 @@
<desc>Iperf (UL/1Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 1M -t 20</iperf_args>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
@@ -222,21 +222,21 @@
<class>Attach_UE</class>
<desc>Attach OAI UE 1 and 2</desc>
<id>rfsim5g_ue rfsim5g_ue2</id>
<nodes>acamas acamas</nodes>
<nodes>localhost localhost</nodes>
</testCase>
<testCase id="444444">
<class>Detach_UE</class>
<desc>Detach OAI UE 1 and 2</desc>
<id>rfsim5g_ue rfsim5g_ue2</id>
<nodes>acamas acamas</nodes>
<nodes>localhost localhost</nodes>
</testCase>
<testCase id="444445">
<class>Detach_UE</class>
<desc>Detach OAI UE 3 to 10</desc>
<id>rfsim5g_ue3 rfsim5g_ue4 rfsim5g_ue5 rfsim5g_ue6 rfsim5g_ue7 rfsim5g_ue8 rfsim5g_ue9 rfsim5g_ue10</id>
<nodes>acamas acamas acamas acamas acamas acamas acamas acamas</nodes>
<nodes>localhost localhost localhost localhost localhost localhost localhost localhost</nodes>
</testCase>
<testCase id="100001">
@@ -88,7 +88,7 @@
<class>Attach_UE</class>
<desc>Attach OAI UE (Wait for IP)</desc>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
</testCase>
<testCase id="000004">
@@ -101,9 +101,9 @@
<class>Ping</class>
<desc>Ping ext-dn from NR-UE</desc>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args> -c 20 -i0.5</ping_args>
<ping_packetloss_threshold>80</ping_packetloss_threshold>
</testCase>
@@ -112,9 +112,9 @@
<class>Ping</class>
<desc>Ping NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ue</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i0.2</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -124,9 +124,9 @@
<desc>Iperf (DL/3Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 3M -t 20 -R</iperf_args>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
@@ -136,9 +136,9 @@
<desc>Iperf (UL/1Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 1M -t 20</iperf_args>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
@@ -146,14 +146,14 @@
<testCase id="040001">
<class>Custom_Command</class>
<desc>Force Msg3 C-RNTI RA</desc>
<node>acamas</node>
<node>localhost</node>
<command>echo ciUE force_crnti_ra | ncat 192.168.71.150 8091</command>
</testCase>
<testCase id="040002">
<class>Custom_Command</class>
<desc>Force RRC_IDLE (UE ID 0)</desc>
<node>acamas</node>
<node>localhost</node>
<command>echo ciUE force_RRC_IDLE | ncat 192.168.71.150 8091</command>
</testCase>
@@ -70,16 +70,16 @@
<class>Attach_UE</class>
<desc>Attach OAI UE (Wait for IP)</desc>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
</testCase>
<testCase id="020001">
<class>Ping</class>
<desc>Ping ext-dn from NR-UE</desc>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -88,9 +88,9 @@
<class>Ping</class>
<desc>Ping NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ue</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -100,9 +100,9 @@
<desc>Iperf (DL/10Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 10M -t 20 -R</iperf_args>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
@@ -112,9 +112,9 @@
<desc>Iperf (UL/3Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 3M -t 20</iperf_args>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
@@ -49,7 +49,7 @@
<testCase id="004000">
<class>Custom_Command</class>
<desc>Clean-Up any residual volume</desc>
<node>acamas</node>
<node>localhost</node>
<command>docker volume rm 5g_rfsimulator_fdd_phytest_rrc.config -f</command>
</testCase>
<testCase id="800813">
@@ -77,9 +77,9 @@
<class>Ping</class>
<desc>Ping gNB from NR-UE</desc>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_gnb_nos1</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c20 -i0.2</ping_args>
<ping_packetloss_threshold>0</ping_packetloss_threshold>
</testCase>
@@ -88,9 +88,9 @@
<class>Ping</class>
<desc>Ping NR-UE from gNB</desc>
<id>rfsim5g_gnb_nos1</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ue</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c20 -i0.2</ping_args>
<ping_packetloss_threshold>0</ping_packetloss_threshold>
</testCase>
@@ -100,9 +100,9 @@
<desc>Iperf (DL/30kbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 0.03M -t 20 -R -c 10.0.1.1</iperf_args>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_gnb_nos1</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
@@ -112,9 +112,9 @@
<desc>Iperf (UL/30kbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 0.03M -t 20 -c 10.0.1.1</iperf_args>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_gnb_nos1</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
@@ -70,16 +70,16 @@
<class>Attach_UE</class>
<desc>Attach OAI UE (Wait for IP)</desc>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
</testCase>
<testCase id="020001">
<class>Ping</class>
<desc>Ping ext-dn from NR-UE</desc>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i0.2</ping_args>
<ping_packetloss_threshold>0</ping_packetloss_threshold>
</testCase>
@@ -88,9 +88,9 @@
<class>Ping</class>
<desc>Ping NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ue</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i0.2</ping_args>
<ping_packetloss_threshold>0</ping_packetloss_threshold>
</testCase>
@@ -48,56 +48,52 @@
<testCase id="111111">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<svr_id>0</svr_id>
<node>localhost</node>
<images>oai-gnb-asan oai-nr-ue</images>
</testCase>
<testCase id="800813">
<class>Create_Workspace</class>
<desc>Create new Workspace</desc>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<node>localhost</node>
</testCase>
<testCase id="000001">
<class>Deploy_Object</class>
<desc>Deploy OAI 5G CoreNetwork</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_multiue</yaml_path>
<services>mysql oai-amf oai-smf oai-upf oai-ext-dn</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000002">
<class>Deploy_Object</class>
<desc>Deploy OAI 5G gNB RF sim SA</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_multiue</yaml_path>
<services>oai-gnb</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000003">
<class>Deploy_Object</class>
<desc>Deploy OAI 5G NR-UE RF sim SA</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_multiue</yaml_path>
<services>oai-nr-ue</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000008">
<class>Attach_UE</class>
<desc>Attach OAI UE (Wait for IP)</desc>
<id>rfsim5g_multiue1 rfsim5g_multiue2 rfsim5g_multiue3 rfsim5g_multiue4 rfsim5g_multiue5 rfsim5g_multiue6 rfsim5g_multiue7 rfsim5g_multiue8 rfsim5g_multiue9 rfsim5g_multiue10</id>
<nodes>acamas acamas acamas acamas acamas acamas acamas acamas acamas acamas</nodes>
<nodes>localhost localhost localhost localhost localhost localhost localhost localhost localhost localhost</nodes>
</testCase>
<testCase id="020001">
<class>Ping</class>
<desc>Ping ext-dn from NR-UE</desc>
<id>rfsim5g_multiue1</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -106,9 +102,9 @@
<class>Ping</class>
<desc>Ping NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_multiue1</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -117,9 +113,9 @@
<class>Ping</class>
<desc>Ping ext-dn from Second NR-UE</desc>
<id>rfsim5g_multiue2</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -128,9 +124,9 @@
<class>Ping</class>
<desc>Ping Second NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_multiue2</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -139,9 +135,9 @@
<class>Ping</class>
<desc>Ping ext-dn from both UEs</desc>
<id>rfsim5g_multiue1 rfsim5g_multiue2</id>
<nodes>acamas acamas</nodes>
<nodes>localhost localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -150,9 +146,9 @@
<class>Ping</class>
<desc>Ping ext-dn from all UEs</desc>
<id>rfsim5g_multiue1 rfsim5g_multiue2 rfsim5g_multiue3 rfsim5g_multiue4 rfsim5g_multiue5 rfsim5g_multiue6 rfsim5g_multiue7 rfsim5g_multiue8 rfsim5g_multiue9 rfsim5g_multiue10</id>
<nodes>acamas acamas acamas acamas acamas acamas acamas acamas acamas acamas</nodes>
<nodes>localhost localhost localhost localhost localhost localhost localhost localhost localhost localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25 -s 1016</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -162,9 +158,9 @@
<desc>Iperf (DL/3Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 3M -t 20 -R</iperf_args>
<id>rfsim5g_multiue1</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
@@ -174,9 +170,9 @@
<desc>Iperf (UL/1Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 1M -t 20</iperf_args>
<id>rfsim5g_multiue1</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
@@ -185,7 +181,7 @@
<class>Detach_UE</class>
<desc>Detach OAI UEs</desc>
<id>rfsim5g_multiue1</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
</testCase>
<testCase id="100001">
@@ -195,15 +191,14 @@
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_multiue</yaml_path>
<d_retx_th>1,0,0,0</d_retx_th>
<u_retx_th>1,0,0,0</u_retx_th>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<node>localhost</node>
</testCase>
<testCase id="222222">
<class>Clean_Test_Server_Images</class>
<always_exec>true</always_exec>
<desc>Clean Test Images on Test Server</desc>
<svr_id>0</svr_id>
<node>localhost</node>
<images>oai-gnb-asan oai-nr-ue</images>
</testCase>
@@ -55,58 +55,54 @@
<testCase id="111111">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<svr_id>0</svr_id>
<node>localhost</node>
<images>oai-gnb-asan oai-nr-cuup-asan oai-nr-ue-asan</images>
</testCase>
<testCase id="800813">
<class>Create_Workspace</class>
<desc>Create new Workspace</desc>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<node>localhost</node>
</testCase>
<testCase id="000001">
<class>Deploy_Object</class>
<desc>Deploy OAI 5G CoreNetwork</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_n2_ho</yaml_path>
<services>mysql oai-amf oai-smf oai-upf oai-ext-dn</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000002">
<class>Deploy_Object</class>
<desc>Deploy OAI 5G CU-CP/CU-UP/DU 0 + UE RFsim SA</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_n2_ho</yaml_path>
<services>oai-cucp-0 oai-cuup-0 oai-du-0 oai-nr-ue</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000003">
<class>Attach_UE</class>
<desc>Attach OAI UE (Wait for IP)</desc>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
</testCase>
<testCase id="000004">
<class>Deploy_Object</class>
<desc>Deploy OAI 5G CU-CP/CU-UP/DU 1 RFsim SA</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_n2_ho</yaml_path>
<services>oai-cucp-1 oai-cuup-1 oai-du-1</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="020001">
<class>Ping</class>
<desc>Ping NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ue</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 50 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -115,9 +111,9 @@
<class>Ping</class>
<desc>Ping ext-dn from NR-UE</desc>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 50 -i 0.25</ping_args>
<ping_packetloss_threshold>10</ping_packetloss_threshold>
</testCase>
@@ -127,9 +123,9 @@
<desc>Iperf (DL/10Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 3M -t 20 -R</iperf_args>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
@@ -139,9 +135,9 @@
<desc>Iperf (UL/4Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 1M -t 20</iperf_args>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
@@ -155,7 +151,7 @@
<testCase id="050001">
<class>Custom_Command</class>
<desc>Trigger N2 Handover</desc>
<node>acamas</node>
<node>localhost</node>
<command>echo ci trigger_n2_ho 1,1 | ncat 192.168.71.150 9090</command>
<command_fail>yes</command_fail>
</testCase>
@@ -163,14 +159,14 @@
<testCase id="050002">
<class>Custom_Command</class>
<desc>UE (1) connected to DU-PCI 1?</desc>
<node>acamas</node>
<node>localhost</node>
<command>echo ci fetch_du_by_ue_id 1 | ncat 192.168.71.180 9090 | grep "1234"</command>
</testCase>
<testCase id="050003">
<class>Custom_Command</class>
<desc>Trigger N2 Handover</desc>
<node>acamas</node>
<node>localhost</node>
<command>echo ci trigger_n2_ho 0,1 | ncat 192.168.71.180 9090</command>
<command_fail>yes</command_fail>
</testCase>
@@ -178,7 +174,7 @@
<testCase id="050004">
<class>Custom_Command</class>
<desc>UE (1) connected to DU-PCI 0?</desc>
<node>acamas</node>
<node>localhost</node>
<command>echo ci fetch_du_by_ue_id 1 | ncat 192.168.71.150 9090 | grep "3584"</command>
</testCase>
@@ -186,9 +182,8 @@
<class>Undeploy_Object</class>
<always_exec>true</always_exec>
<desc>Undeploy all OAI 5G stack</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_n2_ho</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<d_retx_th>10,100,100,100</d_retx_th>
<u_retx_th>10,100,100,100</u_retx_th>
</testCase>
@@ -197,7 +192,7 @@
<class>Clean_Test_Server_Images</class>
<always_exec>true</always_exec>
<desc>Clean Test Images on Test Server</desc>
<svr_id>0</svr_id>
<node>localhost</node>
<images>oai-gnb-asan oai-nr-cuup-asan oai-nr-ue-asan</images>
</testCase>
@@ -74,16 +74,16 @@
<class>Attach_UE</class>
<desc>Attach OAI UE (Wait for IP)</desc>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
</testCase>
<testCase id="020001">
<class>Ping</class>
<desc>Ping ext-dn from NR-UE</desc>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -92,9 +92,9 @@
<class>Ping</class>
<desc>Ping NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ue</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -102,7 +102,7 @@
<testCase id="040001">
<class>Custom_Command</class>
<desc>Trigger Reestablishment</desc>
<node>acamas</node>
<node>localhost</node>
<command>echo ci force_reestab | ncat 192.168.71.140 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment'</command>
<command_fail>yes</command_fail>
</testCase>
@@ -111,9 +111,9 @@
<class>Ping</class>
<desc>Ping ext-dn from NR-UE</desc>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i0.5 -w25</ping_args>
<ping_packetloss_threshold>80</ping_packetloss_threshold>
</testCase>
@@ -121,7 +121,7 @@
<testCase id="040002">
<class>Custom_Command</class>
<desc>Verify Reestablishment</desc>
<node>acamas</node>
<node>localhost</node>
<command>echo ci get_reestab_count | ncat 192.168.71.140 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1'</command>
<command_fail>yes</command_fail>
</testCase>
@@ -69,16 +69,16 @@
<class>Attach_UE</class>
<desc>Attach OAI UE (Wait for IP)</desc>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
</testCase>
<testCase id="020001">
<class>Ping</class>
<desc>Ping ext-dn from NR-UE</desc>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -87,9 +87,9 @@
<class>Ping</class>
<desc>Ping NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ue</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -74,7 +74,7 @@
<testCase id="000005">
<class>Custom_Command</class>
<desc>Check that UE synched</desc>
<node>acamas</node>
<node>localhost</node>
<command>docker logs rfsim5g-oai-nr-ue-2 | grep -m 1 "PSBCH RX:OK"</command>
</testCase>
@@ -49,7 +49,7 @@
<testCase id="004000">
<class>Custom_Command</class>
<desc>Clean-Up any residual volume</desc>
<node>acamas</node>
<node>localhost</node>
<command>docker volume rm 5g_rfsimulator_tdd_dora_rrc.config -f</command>
</testCase>
<testCase id="800813">
@@ -83,9 +83,9 @@
<class>Ping</class>
<desc>Ping gNB from NR-UE</desc>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_gnb_nos1</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c20 -i0.2</ping_args>
<ping_packetloss_threshold>0</ping_packetloss_threshold>
</testCase>
@@ -94,9 +94,9 @@
<class>Ping</class>
<desc>Ping NR-UE from gNB</desc>
<id>rfsim5g_gnb_nos1</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ue</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c20 -i0.2</ping_args>
<ping_packetloss_threshold>0</ping_packetloss_threshold>
</testCase>
@@ -72,16 +72,16 @@
<class>Attach_UE</class>
<desc>Attach OAI UE (Wait for IP)</desc>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
</testCase>
<testCase id="020001">
<class>Ping</class>
<desc>Ping ext-dn from NR-UE</desc>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -90,9 +90,9 @@
<class>Ping</class>
<desc>Ping NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ue</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -101,16 +101,16 @@
<class>Attach_UE</class>
<desc>Verify 2nd PDU session is up</desc>
<id>rfsim5g_ue_pdu_2</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
</testCase>
<testCase id="020003">
<class>Ping</class>
<desc>Ping ext-dn from NR-UE on PDU session ID 2</desc>
<id>rfsim5g_ue_pdu_2</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
@@ -120,9 +120,9 @@
<desc>Iperf (DL/3Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 3M -t 20 -R</iperf_args>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
@@ -132,9 +132,9 @@
<desc>Iperf (UL/1Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 1M -t 20</iperf_args>
<id>rfsim5g_ue</id>
<nodes>acamas</nodes>
<nodes>localhost</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<svr_node>localhost</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
@@ -0,0 +1,230 @@
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>TEST-MONO-N2-HO-B210</htmlTabRef>
<htmlTabName>Monolithic N2 Handover 20 MHz TDD SA</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<TestCaseRequestedList>
000001
000002
000023
000003
000004
000005
000006
000007
000008
000009
000010
000011
000012
000013
000014
000015
000017
000018
000019
000016
000020
000021
000022
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="000001">
<class>DeployCoreNetwork</class>
<desc>Initialize 5G Core</desc>
<cn_id>oc-cn5g-00103-ho</cn_id>
</testCase>
<testCase id="000002">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<images>oai-gnb</images>
<node>groot</node>
</testCase>
<testCase id="000023">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<images>oai-gnb</images>
<node>rocket</node>
</testCase>
<testCase id="000003">
<class>Create_Workspace</class>
<desc>Create new Workspace for groot</desc>
<node>groot</node>
</testCase>
<testCase id="000005">
<class>Create_Workspace</class>
<desc>Create new Workspace on rocket</desc>
<node>rocket</node>
</testCase>
<testCase id="000004">
<class>Custom_Command</class>
<desc>Set initial attenuation on target gNB</desc>
<node>rocket</node>
<command>python3 %%workspace%%/ci-scripts/attenuatorctl.py -s 1,2 0 -s 3,4 15</command>
</testCase>
<testCase id="000005">
<class>Deploy_Object</class>
<desc>Deploy Monolithic gNB-PCI0 (TDD/Band77/20MHz/B210) in a container</desc>
<yaml_path>ci-scripts/yaml_files/5g_sa_n2_ho_b210</yaml_path>
<node>groot</node>
<services>oai-gnb-pci0</services>
</testCase>
<testCase id="000006">
<class>Deploy_Object</class>
<desc>Deploy Monolithic gNB-PCI1 (TDD/Band77/20MHz/B210) in a container</desc>
<yaml_path>ci-scripts/yaml_files/5g_sa_n2_ho_b210</yaml_path>
<node>rocket</node>
<services>oai-gnb-pci1</services>
</testCase>
<testCase id="000007">
<class>Attach_UE</class>
<desc>Attach Quectel</desc>
<id>raspix</id>
</testCase>
<testCase id="000008">
<class>Ping</class>
<desc>Ping: 100pings in 20sec</desc>
<id>raspix</id>
<svr_id>oc-cn5g-00103-ho</svr_id>
<ping_args>-c 100 -i 0.2</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="000009">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
</testCase>
<testCase id="000010">
<class>Custom_Command</class>
<desc>Gradually attenuate gNB-PCI0 (ch1-2=15dB) and gNB-PCI1 (ch3-4=0dB) over 5s to trigger N2 Handover to gNB-PCI1</desc>
<node>rocket</node>
<command>python3 %%workspace%%/ci-scripts/attenuatorctl.py -r 1,2 15 -r 3,4 0 -d 5</command>
</testCase>
<testCase id="000011">
<class>Ping</class>
<desc>Ping: 50pings in 10sec</desc>
<id>raspix</id>
<svr_id>oc-cn5g-00103-ho</svr_id>
<ping_args>-c 50 -i 0.2</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="000012">
<class>Custom_Command</class>
<desc>UE connected to gNB-PCI1?</desc>
<node>rocket</node>
<command>echo ci fetch_du_by_ue_id 1 | ncat 127.0.0.1 9090 | grep "3585"</command>
</testCase>
<testCase id="000013">
<class>Custom_Command</class>
<desc>Gradually attenuate gNB-PCI0 (ch1-2=0dB) and gNB-PCI1 (ch3-4=15dB) over 5s to trigger N2 Handover back to gNB-PCI0</desc>
<node>rocket</node>
<command>python3 %%workspace%%/ci-scripts/attenuatorctl.py -r 1,2 0 -r 3,4 15 -d 5</command>
</testCase>
<testCase id="000014">
<class>Ping</class>
<desc>Ping: 50pings in 10sec</desc>
<id>raspix</id>
<svr_id>oc-cn5g-00103-ho</svr_id>
<ping_args>-c 50 -i 0.2</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="000015">
<class>Custom_Command</class>
<desc>UE connected to gNB-PCI0?</desc>
<node>groot</node>
<command>echo ci fetch_du_by_ue_id 1 | ncat 127.0.0.1 9090 | grep "3584"</command>
</testCase>
<testCase id="000016">
<class>Custom_Command</class>
<always_exec>true</always_exec>
<desc>Reset all attenuators to 0dB</desc>
<node>rocket</node>
<command>python3 %%workspace%%/ci-scripts/attenuatorctl.py -s 1-4 0</command>
</testCase>
<testCase id="000017">
<class>Detach_UE</class>
<always_exec>true</always_exec>
<desc>Detach Quectel</desc>
<id>raspix</id>
</testCase>
<testCase id="000018">
<class>Undeploy_Object</class>
<always_exec>true</always_exec>
<desc>Undeploy Monolithic gNB-PCI0</desc>
<node>groot</node>
<yaml_path>ci-scripts/yaml_files/5g_sa_n2_ho_b210</yaml_path>
</testCase>
<testCase id="000019">
<class>Undeploy_Object</class>
<always_exec>true</always_exec>
<desc>Undeploy Monolithic gNB-PCI1</desc>
<node>rocket</node>
<yaml_path>ci-scripts/yaml_files/5g_sa_n2_ho_b210</yaml_path>
</testCase>
<testCase id="000020">
<class>Clean_Test_Server_Images</class>
<always_exec>true</always_exec>
<desc>Clean Test Images on Test Server</desc>
<node>groot</node>
<images>oai-gnb</images>
</testCase>
<testCase id="000021">
<class>Clean_Test_Server_Images</class>
<always_exec>true</always_exec>
<desc>Clean Test Images on Test Server</desc>
<node>rocket</node>
<images>oai-gnb</images>
</testCase>
<testCase id="000022">
<class>UndeployCoreNetwork</class>
<always_exec>true</always_exec>
<desc>Terminate 5G Core</desc>
<cn_id>oc-cn5g-00103-ho</cn_id>
</testCase>
</testCaseList>
@@ -150,7 +150,6 @@ services:
--telnetsrv --telnetsrv.listenaddr 192.168.71.171
--telnetsrv.shrmod ci
--rfsimulator.serveraddr 192.168.71.190
--gNBs.[0].servingCellConfigCommon.[0].ra_ResponseWindow 5
ASAN_OPTIONS: detect_leaks=0:detect_odr_violation=0
depends_on:
- oai-cucp-0
@@ -0,0 +1,61 @@
services:
oai-gnb-pci0:
image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop}
container_name: oai-gnb-pci0
cap_drop:
- ALL
cap_add:
- SYS_NICE
- IPC_LOCK
ulimits:
core: -1 # for core dumps
environment:
USE_B2XX: 'yes'
USE_ADDITIONAL_OPTIONS: --RUs.[0].sdr_addrs serial=30AD30F
--telnetsrv --telnetsrv.shrmod ci
--log_config.global_log_options level,nocolor,utc_time,line_num,function
ASAN_OPTIONS: detect_leaks=0:detect_odr_violation=0
devices:
- /dev/bus/usb/:/dev/bus/usb/
volumes:
- ../../conf_files/neighbour-config-ho.conf:/opt/oai-gnb/etc/neighbour-config-ho.conf
- ../../conf_files/gnb.sa.band77.51prb.usrpb200.n2-ho.conf:/opt/oai-gnb/etc/gnb.conf
network_mode: "host"
healthcheck:
test: /bin/bash -c "ps aux | grep -v grep | grep -c softmodem"
interval: 10s
timeout: 5s
retries: 5
oai-gnb-pci1:
image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop}
container_name: oai-gnb-pci1
cap_drop:
- ALL
cap_add:
- SYS_NICE
- IPC_LOCK
ulimits:
core: -1 # for core dumps
environment:
USE_B2XX: 'yes'
USE_ADDITIONAL_OPTIONS: --RUs.[0].sdr_addrs serial=31F8010
--gNBs.[0].nr_cellid 11111111
--gNBs.[0].gNB_ID 0xe01
--gNBs.[0].servingCellConfigCommon.[0].physCellId 1
--gNBs.[0].servingCellConfigCommon.[0].ssb_PositionsInBurst_Bitmap 2
--gNBs.[0].NETWORK_INTERFACES.GNB_IPV4_ADDRESS_FOR_NG_AMF 172.21.19.99
--gNBs.[0].NETWORK_INTERFACES.GNB_IPV4_ADDRESS_FOR_NGU 172.21.19.99
--telnetsrv --telnetsrv.shrmod ci
--log_config.global_log_options level,nocolor,utc_time,line_num,function
devices:
- /dev/bus/usb/:/dev/bus/usb/
volumes:
- ../../conf_files/neighbour-config-ho.conf:/opt/oai-gnb/etc/neighbour-config-ho.conf
- ../../conf_files/gnb.sa.band77.51prb.usrpb200.n2-ho.conf:/opt/oai-gnb/etc/gnb.conf
network_mode: "host"
healthcheck:
test: /bin/bash -c "ps aux | grep -v grep | grep -c softmodem"
interval: 10s
timeout: 5s
retries: 5
@@ -17,7 +17,7 @@ services:
#entrypoint: /bin/bash -c "sleep infinity"
environment:
TZ: Europe/Paris
USE_ADDITIONAL_OPTIONS: --usrp-args type=n3xx,name=ni-n3xx-31641B9,addr=192.168.10.2 -r 106 --numerology 1 --band 78 -C 3425010000 --ssb 509 --ue-fo-compensation --ue-rxgain 65 --tune-offset 20000000 -A 90 --log_config.global_log_options level,nocolor,time --uicc0.imsi 001020000000111 --uicc0.nssai_sd 16777215
USE_ADDITIONAL_OPTIONS: --usrp-args type=n3xx,name=ni-n3xx-31641B9,addr=192.168.10.2 -r 106 --numerology 1 --band 78 -C 3425010000 --ssb 509 --ue-fo-compensation --ue-rxgain 65 --tune-offset 20000000 -A 90 --log_config.global_log_options level,nocolor,time --uicc0.imsi 001020000000111
volumes:
- ../../conf_files/ue.sa.conf:/opt/oai-nr-ue/etc/nr-ue.conf
healthcheck:
+1 -5
View File
@@ -92,7 +92,7 @@ Options:
USRP, BLADERF, LMSSDR, IRIS, SIMU, AW2SORI, AERIAL, None (Default)
Adds this RF board support (in external packages installation and in compilation)
-t | --transport
Selects the transport protocol type, options: None, Ethernet, benetel4g, benetel5g, oran_fhlib_5g, oran_fhlib_5g_mplane, WLS
Selects the transport protocol type, options: None, Ethernet, oran_fhlib_5g, oran_fhlib_5g_mplane, WLS
-P | --phy_simulators
Makes the unitary tests Layer 1 simulators
-V | --vcd
@@ -278,10 +278,6 @@ function main() {
TARGET_LIST="$TARGET_LIST oai_eth_transpro"
CMAKE_CMD="$CMAKE_CMD -DOAI_${2^^}=ON" # ^^ makes uppercase
;;
"benetel4g" | "benetel5g" | "oran_fhlib_4g")
TARGET_LIST="$TARGET_LIST $2"
CMAKE_CMD="$CMAKE_CMD -DOAI_${2^^}=ON" # ^^ makes uppercase
;;
"oran_fhlib_5g")
TARGET_LIST="$TARGET_LIST $2"
CMAKE_CMD="$CMAKE_CMD -DOAI_FHI72=ON"
@@ -1,5 +1,5 @@
diff --git a/fhi_lib/app/src/common.h b/fhi_lib/app/src/common.h
index ac5f471..5efcce3 100644
index ac5f471..b0f7ed1 100644
--- a/fhi_lib/app/src/common.h
+++ b/fhi_lib/app/src/common.h
@@ -28,7 +28,7 @@
@@ -7,7 +7,7 @@ index ac5f471..5efcce3 100644
#include <rte_mbuf.h>
-#define VERSIONX "oran_f_release_v1.0"
+#define VERSIONX "oran_f_release_v1.4"
+#define VERSIONX "oran_f_release_v1.5"
#define APP_O_DU 0
#define APP_O_RU 1
@@ -919,7 +919,7 @@ index 4acade1..c939edc 100644
for(i = 0; i < xran_ports_num; i++){
g_xran_dev_ctx[i] = pCtx;
diff --git a/fhi_lib/lib/src/xran_main.c b/fhi_lib/lib/src/xran_main.c
index 7c472d7..216c7f5 100644
index 7c472d7..9da3621 100644
--- a/fhi_lib/lib/src/xran_main.c
+++ b/fhi_lib/lib/src/xran_main.c
@@ -35,7 +35,11 @@
@@ -969,7 +969,29 @@ index 7c472d7..216c7f5 100644
print_dbg("PRACH eAxC_offset %d\n", pPrachCPConfig->eAxC_offset);
/* Save some configs for app */
@@ -1570,6 +1593,7 @@ int32_t handle_ecpri_ethertype(struct rte_mbuf* pkt_q[], uint16_t xport_id, stru
@@ -1169,6 +1192,10 @@ xran_prepare_cp_ul_slot(uint16_t xran_port_id, uint32_t nSlotIdx, uint32_t nCcS
uint8_t seqid = xran_get_cp_seqid(pHandle, XRAN_DIR_UL, cc_id, port_id);
beam_id = xran_get_beamid(pHandle, XRAN_DIR_UL, cc_id, port_id, slot_id);
+ pBufList = &(p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[buf_id][cc_id][ant_id].sBufferList);
+ struct xran_prb_map *prbMap = pBufList->pBuffers->pData;
+ struct xran_prb_elm *pPrbElm = &prbMap->prbMap[0]; //mjoang
+ beam_id = pPrbElm->nBeamIndex;
ret = generate_cpmsg_prach(pHandle, &params, sect_geninfo, mbuf, p_xran_dev_ctx,
frame_id, subframe_id, slot_id, tti,
beam_id, cc_id, port_id, occasionid, seqid);
@@ -1338,6 +1365,10 @@ tx_cp_ul_cb(struct rte_timer *tim, void *arg)
uint8_t seqid = xran_get_cp_seqid(pHandle, XRAN_DIR_UL, cc_id, port_id);
beam_id = xran_get_beamid(pHandle, XRAN_DIR_UL, cc_id, port_id, slot_id);
+ pBufList = &(p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[buf_id][cc_id][ant_id].sBufferList);
+ struct xran_prb_map *prbMap = pBufList->pBuffers->pData;
+ struct xran_prb_elm *pPrbElm = &prbMap->prbMap[0]; //mjoang
+ beam_id = pPrbElm->nBeamIndex;
ret = generate_cpmsg_prach(pHandle, &params, sect_geninfo, mbuf, p_xran_dev_ctx,
frame_id, subframe_id, slot_id, tti,
beam_id, cc_id, port_id, occasionid, seqid);
@@ -1570,6 +1601,7 @@ int32_t handle_ecpri_ethertype(struct rte_mbuf* pkt_q[], uint16_t xport_id, stru
{
case ECPRI_IQ_DATA:
pkt_data[num_data++] = pkt;
@@ -977,7 +999,7 @@ index 7c472d7..216c7f5 100644
break;
// For RU emulation
case ECPRI_RT_CONTROL_DATA:
@@ -1587,7 +1611,7 @@ int32_t handle_ecpri_ethertype(struct rte_mbuf* pkt_q[], uint16_t xport_id, stru
@@ -1587,7 +1619,7 @@ int32_t handle_ecpri_ethertype(struct rte_mbuf* pkt_q[], uint16_t xport_id, stru
break;
default:
if (p_dev_ctx->fh_init.io_cfg.id == O_DU) {
@@ -986,7 +1008,7 @@ index 7c472d7..216c7f5 100644
}
break;
}
@@ -1876,7 +1900,7 @@ xran_sector_get_instances (uint32_t xran_port, void * pDevHandle, uint16_t nNumI
@@ -1876,7 +1908,7 @@ xran_sector_get_instances (uint32_t xran_port, void * pDevHandle, uint16_t nNumI
for (i = 0; i < nNumInstances; i++) {
/* Allocate Memory for CC handles */
@@ -995,7 +1017,7 @@ index 7c472d7..216c7f5 100644
if(pCcHandle == NULL)
return XRAN_STATUS_RESOURCE;
@@ -2347,8 +2371,7 @@ ring_processing_func_per_port(void* args)
@@ -2347,8 +2379,7 @@ ring_processing_func_per_port(void* args)
for (i = 0; i < ctx->io_cfg.num_vfs && i < XRAN_VF_MAX; i = i+1) {
if (ctx->vf2xran_port[i] == port_id) {
for(qi = 0; qi < ctx->rxq_per_port[port_id]; qi++){
@@ -1005,7 +1027,7 @@ index 7c472d7..216c7f5 100644
}
}
}
@@ -2414,9 +2437,6 @@ xran_spawn_workers(void)
@@ -2414,9 +2445,6 @@ xran_spawn_workers(void)
nWorkerCore = nWorkerCore << 1;
}
@@ -1015,7 +1037,7 @@ index 7c472d7..216c7f5 100644
printf("O-XU %d\n", eth_ctx->io_cfg.id);
printf("HW %d\n", icx_cpu);
printf("Num cores %d\n", total_num_cores);
@@ -2453,7 +2473,7 @@ xran_spawn_workers(void)
@@ -2453,7 +2481,7 @@ xran_spawn_workers(void)
eth_ctx->time_wrk_cfg.arg = NULL;
eth_ctx->time_wrk_cfg.state = 1;
@@ -1024,7 +1046,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2475,7 +2495,7 @@ xran_spawn_workers(void)
@@ -2475,7 +2503,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 **/
@@ -1033,7 +1055,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2502,7 +2522,7 @@ xran_spawn_workers(void)
@@ -2502,7 +2530,7 @@ xran_spawn_workers(void)
}
/** 1 - CP GEN **/
@@ -1042,7 +1064,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2536,7 +2556,7 @@ xran_spawn_workers(void)
@@ -2536,7 +2564,7 @@ xran_spawn_workers(void)
else
p_dev->tx_sym_gen_func = xran_process_tx_sym_cp_on_opt;
@@ -1051,7 +1073,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2559,7 +2579,7 @@ xran_spawn_workers(void)
@@ -2559,7 +2587,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 **/
@@ -1060,7 +1082,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2586,7 +2606,7 @@ xran_spawn_workers(void)
@@ -2586,7 +2614,7 @@ xran_spawn_workers(void)
}
/** 1 - CP GEN **/
@@ -1069,7 +1091,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2613,7 +2633,7 @@ xran_spawn_workers(void)
@@ -2613,7 +2641,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 **/
@@ -1078,7 +1100,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2628,7 +2648,7 @@ xran_spawn_workers(void)
@@ -2628,7 +2656,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 1 - CP GEN **/
@@ -1087,7 +1109,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2643,7 +2663,7 @@ xran_spawn_workers(void)
@@ -2643,7 +2671,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 2 UP GEN **/
@@ -1096,7 +1118,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2682,7 +2702,7 @@ xran_spawn_workers(void)
@@ -2682,7 +2710,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 **/
@@ -1105,7 +1127,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2697,7 +2717,7 @@ xran_spawn_workers(void)
@@ -2697,7 +2725,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 1 - CP GEN **/
@@ -1114,7 +1136,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2712,7 +2732,7 @@ xran_spawn_workers(void)
@@ -2712,7 +2740,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 2 UP GEN **/
@@ -1123,7 +1145,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2727,7 +2747,7 @@ xran_spawn_workers(void)
@@ -2727,7 +2755,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 3 UP GEN **/
@@ -1132,7 +1154,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2766,7 +2786,7 @@ xran_spawn_workers(void)
@@ -2766,7 +2794,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 **/
@@ -1141,7 +1163,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2781,7 +2801,7 @@ xran_spawn_workers(void)
@@ -2781,7 +2809,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 1 Eth Tx **/
@@ -1150,7 +1172,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
@@ -2797,7 +2817,7 @@ xran_spawn_workers(void)
@@ -2797,7 +2825,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 2 - CP GEN **/
@@ -1159,7 +1181,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2812,7 +2832,7 @@ xran_spawn_workers(void)
@@ -2812,7 +2840,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 3 UP GEN **/
@@ -1168,7 +1190,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2827,7 +2847,7 @@ xran_spawn_workers(void)
@@ -2827,7 +2855,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 4 UP GEN **/
@@ -1177,7 +1199,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2861,7 +2881,7 @@ xran_spawn_workers(void)
@@ -2861,7 +2889,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 Eth RX */
@@ -1186,7 +1208,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2876,7 +2896,7 @@ xran_spawn_workers(void)
@@ -2876,7 +2904,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 1 FH RX and BBDEV */
@@ -1195,7 +1217,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2891,7 +2911,7 @@ xran_spawn_workers(void)
@@ -2891,7 +2919,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 2 FH RX and BBDEV */
@@ -1204,7 +1226,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2906,7 +2926,7 @@ xran_spawn_workers(void)
@@ -2906,7 +2934,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 3 FH RX and BBDEV */
@@ -1213,7 +1235,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2921,7 +2941,7 @@ xran_spawn_workers(void)
@@ -2921,7 +2949,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** FH TX and BBDEV */
@@ -1222,7 +1244,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -2969,7 +2989,7 @@ xran_spawn_workers(void)
@@ -2969,7 +2997,7 @@ xran_spawn_workers(void)
/* p_dev->tx_sym_gen_func = xran_process_tx_sym_cp_on_opt; */
@@ -1231,7 +1253,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3004,7 +3024,7 @@ xran_spawn_workers(void)
@@ -3004,7 +3032,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 **/
@@ -1240,7 +1262,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3031,7 +3051,7 @@ xran_spawn_workers(void)
@@ -3031,7 +3059,7 @@ xran_spawn_workers(void)
}
/** 1 - CP GEN **/
@@ -1249,7 +1271,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3062,7 +3082,7 @@ xran_spawn_workers(void)
@@ -3062,7 +3090,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 **/
@@ -1258,7 +1280,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3089,7 +3109,7 @@ xran_spawn_workers(void)
@@ -3089,7 +3117,7 @@ xran_spawn_workers(void)
}
/** 1 - CP GEN **/
@@ -1267,7 +1289,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3115,7 +3135,7 @@ xran_spawn_workers(void)
@@ -3115,7 +3143,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 **/
@@ -1276,7 +1298,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3130,7 +3150,7 @@ xran_spawn_workers(void)
@@ -3130,7 +3158,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 1 - CP GEN **/
@@ -1285,7 +1307,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3145,7 +3165,7 @@ xran_spawn_workers(void)
@@ -3145,7 +3173,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 2 UP GEN **/
@@ -1294,7 +1316,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3184,7 +3204,7 @@ xran_spawn_workers(void)
@@ -3184,7 +3212,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 FH RX and BBDEV */
@@ -1303,7 +1325,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3199,7 +3219,7 @@ xran_spawn_workers(void)
@@ -3199,7 +3227,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 1 - CP GEN **/
@@ -1312,7 +1334,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3214,7 +3234,7 @@ xran_spawn_workers(void)
@@ -3214,7 +3242,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 2 UP GEN **/
@@ -1321,7 +1343,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3229,7 +3249,7 @@ xran_spawn_workers(void)
@@ -3229,7 +3257,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 3 UP GEN **/
@@ -1330,7 +1352,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3266,7 +3286,7 @@ xran_spawn_workers(void)
@@ -3266,7 +3294,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 **/
@@ -1339,7 +1361,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3281,7 +3301,7 @@ xran_spawn_workers(void)
@@ -3281,7 +3309,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 1 - CP GEN **/
@@ -1348,7 +1370,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3296,7 +3316,7 @@ xran_spawn_workers(void)
@@ -3296,7 +3324,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 2 UP GEN **/
@@ -1357,7 +1379,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3311,7 +3331,7 @@ xran_spawn_workers(void)
@@ -3311,7 +3339,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 3 UP GEN **/
@@ -1366,7 +1388,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3326,7 +3346,7 @@ xran_spawn_workers(void)
@@ -3326,7 +3354,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 4 UP GEN **/
@@ -1375,7 +1397,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3348,7 +3368,7 @@ xran_spawn_workers(void)
@@ -3348,7 +3376,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 Eth RX */
@@ -1384,7 +1406,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3363,7 +3383,7 @@ xran_spawn_workers(void)
@@ -3363,7 +3391,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 1 FH RX and BBDEV */
@@ -1393,7 +1415,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3378,7 +3398,7 @@ xran_spawn_workers(void)
@@ -3378,7 +3406,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 2 FH RX and BBDEV */
@@ -1402,7 +1424,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3393,7 +3413,7 @@ xran_spawn_workers(void)
@@ -3393,7 +3421,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 3 FH RX and BBDEV */
@@ -1411,7 +1433,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3408,7 +3428,7 @@ xran_spawn_workers(void)
@@ -3408,7 +3436,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** FH TX and BBDEV */
@@ -1420,7 +1442,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3435,7 +3455,7 @@ xran_spawn_workers(void)
@@ -3435,7 +3463,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 Eth RX */
@@ -1429,7 +1451,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3450,7 +3470,7 @@ xran_spawn_workers(void)
@@ -3450,7 +3478,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 1 FH RX and BBDEV */
@@ -1438,7 +1460,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3465,7 +3485,7 @@ xran_spawn_workers(void)
@@ -3465,7 +3493,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 2 FH RX and BBDEV */
@@ -1447,7 +1469,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3480,7 +3500,7 @@ xran_spawn_workers(void)
@@ -3480,7 +3508,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 3 FH RX and BBDEV */
@@ -1456,7 +1478,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3495,7 +3515,7 @@ xran_spawn_workers(void)
@@ -3495,7 +3523,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 4 FH RX and BBDEV */
@@ -1465,7 +1487,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3510,7 +3530,7 @@ xran_spawn_workers(void)
@@ -3510,7 +3538,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** FH TX and BBDEV */
@@ -1474,7 +1496,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3537,7 +3557,7 @@ xran_spawn_workers(void)
@@ -3537,7 +3565,7 @@ xran_spawn_workers(void)
/* workers */
/** 0 **/
@@ -1483,7 +1505,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3562,7 +3582,7 @@ xran_spawn_workers(void)
@@ -3562,7 +3590,7 @@ xran_spawn_workers(void)
}
/** 1 - CP GEN **/
@@ -1492,7 +1514,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3577,7 +3597,7 @@ xran_spawn_workers(void)
@@ -3577,7 +3605,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 2 UP GEN **/
@@ -1501,7 +1523,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3602,7 +3622,7 @@ xran_spawn_workers(void)
@@ -3602,7 +3630,7 @@ xran_spawn_workers(void)
}
/** 3 UP GEN **/
@@ -1510,7 +1532,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3627,7 +3647,7 @@ xran_spawn_workers(void)
@@ -3627,7 +3655,7 @@ xran_spawn_workers(void)
}
/** 4 UP GEN **/
@@ -1519,7 +1541,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -3642,7 +3662,7 @@ xran_spawn_workers(void)
@@ -3642,7 +3670,7 @@ xran_spawn_workers(void)
eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx;
/** 5 UP GEN **/
@@ -1528,7 +1550,7 @@ index 7c472d7..216c7f5 100644
if(pThCtx == NULL){
print_err("pThCtx allocation error\n");
return XRAN_STATUS_FAIL;
@@ -4034,6 +4054,24 @@ xran_get_slot_idx (uint32_t PortId, uint32_t *nFrameIdx, uint32_t *nSubframeIdx,
@@ -4034,6 +4062,24 @@ xran_get_slot_idx (uint32_t PortId, uint32_t *nFrameIdx, uint32_t *nSubframeIdx,
return tti;
}
+1 -3
View File
@@ -37,9 +37,7 @@ typedef struct nssai_s {
// Globally Unique AMF Identifier
typedef struct nr_guami_s {
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_len;
plmn_id_t plmn;
uint8_t amf_region_id;
uint16_t amf_set_id;
uint8_t amf_pointer;
+25 -25
View File
@@ -196,7 +196,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
view *v;
logger *l;
main_window = new_toplevel_window(g, 1200, 900, "eNB tracer");
main_window = new_toplevel_window(g, 1200, 900, "UE tracer");
top_container = new_container(g, VERTICAL);
widget_add_child(g, main_window, top_container, -1);
@@ -207,7 +207,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
/* logo */
widget_add_child(g, line, logo, -1);
input_signal_plot = new_xy_plot(g, 256, 55, "input signal", 20);
input_signal_plot = new_xy_plot(g, 512, 110, "input signal", 20);
widget_add_child(g, line, input_signal_plot, -1);
xy_plot_set_range(g, input_signal_plot, 0, 7680*10, 20, 70);
input_signal_log = new_framelog(h, database,
@@ -221,7 +221,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
logger_add_view(input_signal_log, input_signal_view);
/* UE x PDSCH IQ data */
w = new_xy_plot(g, 55, 55, "", 50);
w = new_xy_plot(g, 110, 110, "", 50);
e->pdsch_iq_ue_xy_plot = w;
widget_add_child(g, line, w, -1);
xy_plot_set_range(g, w, -500, 500, -500, 500);
@@ -232,7 +232,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
e->pdsch_iq_ue_logger = l;
/* UE x estimated DL channel */
w = new_xy_plot(g, 280, 55, "", 50);
w = new_xy_plot(g, 560, 110, "", 50);
e->dl_estimate_ue_xy_plot = w;
widget_add_child(g, line, w, -1);
xy_plot_set_range(g, w, 0, 512*10, -10, 80);
@@ -245,7 +245,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
e->dl_estimate_ue_logger = l;
/* PHY Meas */
w = new_xy_plot(g, 128, 55, "", 50);
w = new_xy_plot(g, 256, 110, "", 50);
e->phy_meas_xy_plot = w;
widget_add_child(g, line, w, -1);
xy_plot_set_range(g, w, 0, 1024*10, -130, 35);
@@ -271,7 +271,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
/* UE x DL mcs */
line = new_container(g, HORIZONTAL);
widget_add_child(g, top_container, line, -1);
w = new_xy_plot(g, 128, 55, "", 20);
w = new_xy_plot(g, 192, 110, "", 20);
xy_plot_set_range(g, w, 0, 1024*10, -2, 30);
e->dl_mcs_xy_plot = w;
widget_add_child(g, line, w, -1);
@@ -282,7 +282,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
e->dl_mcs_logger = l;
/* UE x UL mcs */
w = new_xy_plot(g, 128, 55, "", 20);
w = new_xy_plot(g, 192, 110, "", 20);
xy_plot_set_range(g, w, 0, 1024*10, -2, 30);
e->ul_mcs_xy_plot = w;
widget_add_child(g, line, w, -1);
@@ -295,7 +295,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
/* UE x PUSCH TX Power */
// line = new_container(g, HORIZONTAL);
// widget_add_child(g, top_container, line, -1);
w = new_xy_plot(g, 128, 55, "", 20);
w = new_xy_plot(g, 192, 110, "", 20);
e->pusch_power_xy_plot = w;
widget_add_child(g, line, w, -1);
xy_plot_set_range(g, w, 0, 1024*10, -30, 50);
@@ -313,7 +313,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
/* UE x PUCCH TX Power */
// line = new_container(g, HORIZONTAL);
// widget_add_child(g, top_container, line, -1);
w = new_xy_plot(g, 128, 55, "", 20);
w = new_xy_plot(g, 192, 110, "", 20);
e->pucch_power_xy_plot = w;
widget_add_child(g, line, w, -1);
xy_plot_set_range(g, w, 0, 1024*10, -30, 50);
@@ -329,7 +329,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
e->pucch_ampl_logger = l;
/* UE x PDSCH energy */
w = new_xy_plot(g, 128, 55, "", 50);
w = new_xy_plot(g, 192, 110, "", 50);
e->pdsch_energy_ue_xy_plot = w;
widget_add_child(g, line, w, -1);
xy_plot_set_range(g, w, 0, 1024*10, -10, 80);
@@ -355,7 +355,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
e->pdsch_energy_logger = l;
/* UE x PDCCH energy */
w = new_xy_plot(g, 128, 55, "", 50);
w = new_xy_plot(g, 192, 110, "", 50);
e->pdcch_energy_ue_xy_plot = w;
widget_add_child(g, line, w, -1);
xy_plot_set_range(g, w, 0, 1024*10, -10, 80);
@@ -381,7 +381,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
e->pdcch_energy_logger = l;
/* UE x PDCCH IQ data */
w = new_xy_plot(g, 55, 55, "", 50);
w = new_xy_plot(g, 110, 110, "", 50);
e->pdcch_iq_ue_xy_plot = w;
widget_add_child(g, line, w, -1);
xy_plot_set_range(g, w, -100, 100, -100, 100);
@@ -544,16 +544,16 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
/* phy/mac/rlc/pdcp/rrc textlog */
line = new_container(g, HORIZONTAL);
widget_add_child(g, top_container, line, -1);
container_set_child_growable(g, top_container, line, 1);
container_set_child_growable(g, top_container, line, 0);
/* phy */
col = new_container(g, VERTICAL);
widget_add_child(g, line, col, -1);
container_set_child_growable(g, line, col, 1);
widget_add_child(g, col, new_label(g, "PHY"), -1);
text = new_textlist(g, 100, 10, new_color(g, "#afa"));
text = new_textlist(g, 100, 5, new_color(g, "#afa"));
widget_add_child(g, col, text, -1);
container_set_child_growable(g, col, text, 1);
container_set_child_growable(g, col, text, 0);
textview = new_view_textlist(10000, 10, g, text);
e->phyview = textview;
@@ -562,24 +562,24 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
widget_add_child(g, line, col, -1);
container_set_child_growable(g, line, col, 1);
widget_add_child(g, col, new_label(g, "MAC"), -1);
text = new_textlist(g, 100, 10, new_color(g, "#adf"));
text = new_textlist(g, 100, 5, new_color(g, "#adf"));
widget_add_child(g, col, text, -1);
container_set_child_growable(g, col, text, 1);
container_set_child_growable(g, col, text, 0);
textview = new_view_textlist(10000, 10, g, text);
e->macview = textview;
line = new_container(g, HORIZONTAL);
widget_add_child(g, top_container, line, -1);
container_set_child_growable(g, top_container, line, 1);
container_set_child_growable(g, top_container, line, 0);
/* rlc */
col = new_container(g, VERTICAL);
widget_add_child(g, line, col, -1);
container_set_child_growable(g, line, col, 1);
widget_add_child(g, col, new_label(g, "RLC"), -1);
text = new_textlist(g, 100, 10, new_color(g, "#aff"));
text = new_textlist(g, 100, 5, new_color(g, "#aff"));
widget_add_child(g, col, text, -1);
container_set_child_growable(g, col, text, 1);
container_set_child_growable(g, col, text, 0);
textview = new_view_textlist(10000, 10, g, text);
e->rlcview = textview;
@@ -588,24 +588,24 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
widget_add_child(g, line, col, -1);
container_set_child_growable(g, line, col, 1);
widget_add_child(g, col, new_label(g, "PDCP"), -1);
text = new_textlist(g, 100, 10, new_color(g, "#ed9"));
text = new_textlist(g, 100, 5, new_color(g, "#ed9"));
widget_add_child(g, col, text, -1);
container_set_child_growable(g, col, text, 1);
container_set_child_growable(g, col, text, 0);
textview = new_view_textlist(10000, 10, g, text);
e->pdcpview = textview;
line = new_container(g, HORIZONTAL);
widget_add_child(g, top_container, line, -1);
container_set_child_growable(g, top_container, line, 1);
container_set_child_growable(g, top_container, line, 0);
/* rrc */
col = new_container(g, VERTICAL);
widget_add_child(g, line, col, -1);
container_set_child_growable(g, line, col, 1);
widget_add_child(g, col, new_label(g, "RRC"), -1);
text = new_textlist(g, 100, 10, new_color(g, "#fdb"));
text = new_textlist(g, 100, 5, new_color(g, "#fdb"));
widget_add_child(g, col, text, -1);
container_set_child_growable(g, col, text, 1);
container_set_child_growable(g, col, text, 0);
textview = new_view_textlist(10000, 10, g, text);
e->rrcview = textview;
+79 -17
View File
@@ -29,9 +29,9 @@ The following features are valid for the gNB and the 5G-NR UE.
* Static FDD
* Normal CP
* Subcarrier spacings: 15 and 30kHz (FR1), 120kHz (FR2)
* Bandwidths: 10, 20, 40, 60, 80, 100MHz
* Bandwidths: 5-100MHz (FR1), 100 and 200MHz (FR2)
* Intermediate downlink and uplink frequencies to interface with IF equipment
* Procedures for 2-layer DL and UL MIMO
* Procedures for 4-layer DL and 2-layer UL SU-MIMO
* Slot format: 14 OFDM symbols in UL or DL
* Highly efficient 3GPP compliant LDPC encoder and decoder (BG1 and BG2 supported)
* Highly efficient 3GPP compliant polar encoder and decoder
@@ -47,7 +47,7 @@ These modes of operation are supported:
* "noS1" mode (DL and UL, gNB, nrUE):
- Connection setup stops after RA; RRC configuration is exchanged through
files
- Creates TUN interface to PDCP to inject and receive user-place traffic
- Creates TUN interface to SDAP to inject and receive user-place traffic
- No connection to the core network
* Standalone (SA) mode (gNB, nrUE):
- UE can register with the 5G Core Network through the gNB, establish a PDU
@@ -73,7 +73,7 @@ These modes of operation are supported:
- Single and multiple DMRS symbols
- PTRS support
- Support for up to 4 TX antennas
- Support for up to 2 layers
- Support for up to 4 layers
- Support for 256 QAM
* NR-CSIRS Generation of sequence at PHY
* NR-PUSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
@@ -104,7 +104,9 @@ These modes of operation are supported:
## gNB MAC
- MAC -> PHY configuration using NR FAPI P5 interface
- MAC <-> PHY data interface using FAPI P7 interface for BCH PDU, DCI PDU, PDSCH PDU
- MAC <-> PHY data interface using FAPI P7 interface for DL_TTI.request,
UL_TTI.request, UL_DCI.request, TX_data.request, RX_Data.indication,
CRC.indication, UCI.indication, SRS.indication
- Generation of and scheduler procedures for MIB/SIB1
- Scheduler procedures for RA
- 4-Step RA
@@ -123,13 +125,14 @@ These modes of operation are supported:
- MAC downlink scheduler
- phy-test scheduler (fixed allocation and usable also without UE)
- regular scheduler with dynamic proportionally-fair allocation
- MCS adaptation from HARQ BLER
- MCS adaptation from HARQ BLER or SSB-SINR report
- MAC header generation (including timing advance)
- ACK / NACK handling and HARQ procedures for downlink
- ACK/NACK handling and HARQ procedures for downlink
- MAC uplink scheduler
- phy-test scheduler (fixed allocation)
- regular scheduler with dynamic proportionally-fair allocation
- HARQ procedures for uplink
- MCS adaption from HARQ BLER or PUSCH SINR
- Scheduler procedures for SRS reception
- Periodic SRS reception
- Channel rank computation up to 2x2 scenario
@@ -144,7 +147,15 @@ These modes of operation are supported:
neighbors include cells operating on different frequencies
- DUs must be synchronized with each other for the measurements to be properly performed
- Initial support for RedCap
- Scheduling of SIBs (2, 19)
- RedCap SIB1 v17 IEs supported
- Coexistence of RedCap and Normal UEs
- Handling of RedCap capability for small PDCP/RLC SN size
- Scheduling of other SIBs (2, 19)
- NTN
- Support downlinkHARQ-FeedbackDisabled-r17
- Support for 32 PDSCH and PUSCH HARQ processes per UE
- Consider ntn-Config-r17.cellSpecificKoffset-r17 in scheduling
- Function-based interface for ntn-Config-r17 updates (used by NTN-LEO RFsimulator)
## gNB RLC
@@ -180,7 +191,7 @@ These modes of operation are supported:
- NR RRC (38.331) Rel 17 messages using new [asn1c](https://github.com/mouse07410/asn1c)
- LTE RRC (36.331) also updated to Rel 15
- Generation of system information (SIB2)
- RRC can configure PDCP, RLC, MAC
- RRC can configure PDCP and SDAP (through E1), and RLC and MAC (through F1)
- Interface with GTP-U (tunnel creation/handling for S1-U (NSA), N3 (SA), F1 interfaces)
- Integration of RRC messages and procedures supporting UE 5G SA connection
- RRCSetupRequest/RRCSetup/RRCSetupComplete
@@ -190,8 +201,17 @@ These modes of operation are supported:
- Support for MasterCellGroup configuration (from DU)
- Interface with NGAP for the interactions with the AMF
- Interface with F1AP for CU/DU split deployment option
- Periodic RRC measurements of serving cell (no A/B events)
- Initial support for RedCap
- Interface with E1AP for CU-CP/CU-CP split deployment option
- Periodic RRC measurements of serving/neighbour cells and A2/A3 event
handling
- RRC Mobility Management Procedures:
- Inter-DU Handover (F1-based handover within same CU)
- Inter-gNB Handover (N2-based handover between different gNBs)
- Handover Preparation Information generation and processing
- Handover Command generation and processing
- PDCP Status transfer procedures
- Support for handover decision triggers (A3 events, manual triggers)
- Initial support for RedCap (see MAC)
## gNB X2AP
@@ -209,6 +229,16 @@ These modes of operation are supported:
- NGAP UE context release request/complete
- NGAP UE radio capability info indication
- NGAP PDU session resource setup request/response
- NGAP Mobility Management Procedures:
* NGAP Handover Required
* NGAP Handover Request
* NGAP Handover Request Acknowledge
* NGAP Handover Command
* NGAP Handover Notify
* NGAP Handover Cancel
* NGAP Handover Cancel Acknowledge
* NGAP Uplink RAN Status Transfer
* NGAP Downlink RAN Status Transfer
- Interface with RRC
## gNB F1AP
@@ -226,7 +256,10 @@ These modes of operation are supported:
* F1 UE Context modification required
* F1 UE Context release req/cmd/complete
- F1 gNB CU configuration update
- F1 gNB DU configuration update
- F1 Reset (handled at DU only, full reset only)
- F1 Mobility Management Procedures:
* F1 Intra-CU Handover (Inter-DU mobility)
- Interface with RRC
- Interface with GTP-u (tunnel creation/handling for F1-U interface)
- One CU(-CP) can handle multiple DUs
@@ -245,7 +278,8 @@ These modes of operation are supported:
- Bearer Context Modification (gNB-CU-CP initiated)
- E1 Bearer Context Modification Request
- E1 Bearer Context Modification Response
- Interface with RRC and PDCP
- E1 Reset
- Interface with RRC and PDCP/SDAP
- One CU-CP can handle multiple CU-UPs
## gNB GTP-U
@@ -268,7 +302,8 @@ These modes of operation are supported:
- non-blind synchronization (information required: carrier frequency, bandwidth, numerology)
- option to search SSB inside the bandwidth available
* Time tracking based on PBCH DMRS
* Frequency offset estimation based on PSS and SSS
* Initial Frequency offset estimation based on PSS and SSS
* Continuous Frequency offset estimation and compensation based on PBCH DMRS
* 15kHz and 30kHz SCS for FR1 and 120 kHz SCS for FR2
* Reception of NR-PSS/NR-SSS
* NR-PBCH supports multiple SSBs and flexible periodicity
@@ -299,6 +334,7 @@ These modes of operation are supported:
- Support for 256 QAM
- Support for up to 2 TX antenna
- Support for up to 2 layers
- Support for UCI on PUSCH
* NR-PUCCH
- Format 0 (2 bits for ACK/NACK and SR)
- Format 2 (mainly for CSI feedback)
@@ -314,6 +350,10 @@ These modes of operation are supported:
- Support for multiple gNB reception with gNBs synced via GPSDO
* NR-PRACH
- Formats 0,1,2,3, A1-A3, B1-B3
* NTN
- TA adjustemt based on ntn-Config-r17 information
- Autonomous TA adjustemt between SIB19 receptions based on DL time tracking
- UL Doppler pre-compensation based on continuous DL FO estimation
* Highly efficient 3GPP compliant LDPC encoder and decoder (BG1 and BG2 are supported)
* Highly efficient 3GPP compliant polar encoder and decoder
* Encoder and decoder for short block
@@ -331,6 +371,8 @@ These modes of operation are supported:
* Minimum system information (MSI)
- MIB processing
- Scheduling of system information block 1 (SIB1) reception
* Other system information
- Scheduling of other system information blocks reception
* Random access procedure (needs improvement, there is still not a clear separation between MAC and PHY)
- Mapping SSBs to multiple ROs
- Scheduling of PRACH
@@ -367,6 +409,10 @@ These modes of operation are supported:
- Periodic and aperiodic SRS transmission
* Bandwidth part (BWP) operation
- Operation in configured dedicated BWP through RRCSetup or RRCReconfiguration
* NTN
- Support downlinkHARQ-FeedbackDisabled-r17
- Support for 32 PDSCH and PUSCH HARQ processes
- Consider ntn-Config-r17.cellSpecificKoffset-r17 in scheduling
## UE RLC
@@ -399,25 +445,41 @@ These modes of operation are supported:
* Integration of RRC messages and procedures supporting UE 5G SA connection according to 38.331 Rel.16
- RRCSetupRequest/RRCSetup/RRCSetupComplete
- RRCReject
- RRCRelease/ RRC going to IDLE
- RRC Uplink/Downlink Information transfer carrying NAS messages transparently
- RRC Reconfiguration/Reconfiguration complete
- RRCSetup fallback (after reestablishment)
- RRCReestablishmentRequest/RRC Reestablishment/Reestablishment complete
- Support for master cell group configuration
- Reception of UECapabilityEnquiry, encoding and transmission of UECapability
* NTN according to 38.331 Rel.17
- Reception of ntn-Config-r17 from SIB19 or reconfigurationWithSync
- Handling of ntn-UlSyncValidityDuration-r17 in SIB19
* Interface with PDCP: configuration, DCCH and CCCH message handling
* Interface with RLC and MAC for configuration
## UE NAS
## UE 5G NAS
* Transfer of NAS messages between the AMF and the UE supporting the UE registration with the core network and the PDU session establishment according to 24.501 Rel.16
* Transfer of NAS messages between the AMF and the UE supporting the UE registration with the core network and the PDU session establishment according to 24.501 Rel.16
* 5GMM (5G Mobility Management) messages:
- Service Request/Accept/Reject (enc/dec library only)
- Identity Request/Response
- Authentication Request/Response
- Security Mode Command/Complete
- Registration Request/Accept/Complete
- Deregistration Request (UE originating)
- Uplink NAS Transport
* 5GSM (5G Session Management) messages:
- PDU Session Establishment Request/Accept
- NAS configuration and basic interfacing with RRC
* Security Features:
- NAS message integrity protection and ciphering
- Security context establishment and management
* Integration:
- NAS configuration and interfacing with RRC
- Integration with SDAP for user plane data transfer
For detailed implementation status, encoding/decoding support, and unit test coverage, see [5G NAS Implementation Documentation](5Gnas.md).
# OpenAirInterface 4G LTE eNB Feature Set #
+11 -8
View File
@@ -257,7 +257,7 @@ configuration](../RRC/rrc-usage.md) as well for SIB configuration.
* `do_CSIRS` (default 0): flag whether to use channel-state information
reference signal (CSI-RS)
* `do_SRS` (default 0): flag whether to use sounding reference signal (SRS)
* `do_SINR` (default 0): flag whether to enable CSI reporting of SSB-SINR (introduced in rel16)
* `CSI_report_type` (default `ssb_rsrp`): parameter to enable different CSI reporting (options: `ssb_rsrp`, `ssb_sinr` and `cri_rsrp`)
Default setting of CSI reporting quantity is SSB-RSRP.
* `min_rxtxtime` (default 2): minimum feedback time for UE to respond to
transmissions (k1 and k2 in 3GPP spec)
@@ -281,14 +281,17 @@ configuration](../RRC/rrc-usage.md) as well for SIB configuration.
- `du_sibs` (default `[]`): list of SIBs to transmit in the cell. Currently,
SIB19 (for NTN) is supported.
| DL MIMO |`do_CSIRS`|`do_SINR`| CSI report Quantity |
| ---------------------------- | -------- | ------- | --------------------------------------------------|
| OFF (pdsch_AntennaPorts = 1) | 0 | 0 | SSB-RSRP |
| OFF (pdsch_AntennaPorts = 1) | 0 | 1 | SSB-SINR |
| OFF (pdsch_AntennaPorts = 1) | 1 | 0 | CSI-Reference signal RSRP |
| OFF (pdsch_AntennaPorts = 1) | 1 | 1 | CSI-Reference signal SINR (not supported yet) |
| ON (pdsch_AntennaPorts > 1) | 1 | 0 | cri-RI-PMI-CQI |
| DL MIMO |`do_CSIRS`|`CSI_report_type`| CSI report Quantity |
| ------------------------------ | -------- | --------------- | --------------------------------------------------|
| any | any | `ssb_rsrp` | SSB-RSRP |
| any | 0 | `cri_rsrp` | SSB-RSRP (no CSI-RS configured) |
| any | 1 | `cri_rsrp` | CRI-RSRP |
| any | any | `ssb_sinr` | SSB-SINR |
| ON (`pdsch_AntennaPorts` > 1) | 1 | any | cri-RI-PMI-CQI |
Note that activating `cri-RI-PMI-CQI` will result in that report to be produced
in addition to either `SSB-SINR`, `SSB-RSRP` or `CRI-RSRP`.
DL-MIMO is configured using following parameters:
`pdsch_AntennaPorts_XP` , `pdsch_AntennaPorts_N1` , `pdsch_AntennaPorts_N2`, `maxMIMO_layers`
(see also [`RUNMODEM.md`](../RUNMODEM.md))
+1 -1
View File
@@ -325,7 +325,7 @@ The PDCP implementation is secured by a general mutex, akin to the design of the
Initialization of the PDCP layer follows a structure similar to that of the RLC layer. The function `nr_pdcp_layer_init()` initializes PDCP, while a second initialization function, `pdcp_module_init()`, must also be invoked.
To manage UE connections, `nr_pdcp_add_srbs()` is employed for adding UE SRBs in PDCP, while `nr_pdcp_remove_UE()` is used for their removal. Similarly, `nr_pdcp_add_drbs()` adds UE DRBs in PDCP, with `nr_pdcp_remove_UE()` handling their removal.
To manage UE connections, `nr_pdcp_add_srbs()` is employed for adding UE SRBs in PDCP, while `nr_pdcp_remove_UE()` is used for their removal. Similarly, `nr_pdcp_add_drb()` adds UE DRB in PDCP, with `nr_pdcp_remove_UE()` handling their removal.
## PDCP Tx flow
-1
View File
@@ -151,7 +151,6 @@ double cpuf;
bool sdap_data_req(protocol_ctxt_t *ctxt_p,
const ue_id_t ue_id,
const srb_flag_t srb_flag,
const rb_id_t rb_id,
const mui_t mui,
const confirm_t confirm,
const sdu_size_t sdu_buffer_size,
+13 -10
View File
@@ -114,7 +114,10 @@ static void tx_func(processingData_L1tx_t *info)
pushNotifiedFIFO(&gNB->resp_L1, res);
int tx_slot_type = nr_slot_select(cfg, frame_tx, slot_tx);
if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT || get_softmodem_params()->continuous_tx || IS_SOFTMODEM_RFSIM) {
// TODO check for analog_beam_list is a workaround while no beam API for beam
// selection is implemented
if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT || get_softmodem_params()->continuous_tx || IS_SOFTMODEM_RFSIM
|| cfg->analog_beamforming_ve.analog_beam_list) {
start_meas(&info->gNB->phy_proc_tx);
phy_procedures_gNB_TX(info, frame_tx, slot_tx, 1);
@@ -190,17 +193,17 @@ static void rx_func(processingData_L1_t *info)
//WA: comment rotation in tx/rx
if (gNB->phase_comp) {
//apply the rx signal rotation here
int soffset = (slot_rx & 3) * gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size;
int soffset = (slot_rx % RU_RX_SLOT_DEPTH) * gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size;
for (int bb = 0; bb < gNB->common_vars.num_beams_period; bb++) {
for (int aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) {
apply_nr_rotation_RX(&gNB->frame_parms,
gNB->common_vars.rxdataF[bb][aa],
gNB->frame_parms.symbol_rotation[1],
slot_rx,
gNB->frame_parms.N_RB_UL,
soffset,
0,
gNB->frame_parms.Ncp == EXTENDED ? 12 : 14);
const uint max_symb = (gNB->frame_parms.Ncp == EXTENDED) ? 12 : 14;
for (int sym = 0; sym < max_symb; sym++)
apply_nr_rotation_symbol_RX(&gNB->frame_parms,
gNB->common_vars.rxdataF[bb][aa] + soffset + sym * gNB->frame_parms.ofdm_symbol_size,
gNB->frame_parms.symbol_rotation[1],
gNB->frame_parms.N_RB_UL,
slot_rx,
sym);
}
}
}
+2 -1
View File
@@ -564,7 +564,8 @@ static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE,
UE->if_inst->dl_indication(&dl_indication);
}
sampleShift = pbch_pdcch_processing(UE, proc, phy_data);
sampleShift = pbch_processing(UE, proc, phy_data);
pdcch_processing(UE, proc, phy_data);
if (phy_data->dlsch[0].active
&& (phy_data->dlsch[0].rnti_type == TYPE_C_RNTI_ || phy_data->dlsch[0].rnti_type == TYPE_RA_RNTI_)) {
// indicate to tx thread to wait for DLSCH decoding
@@ -73,6 +73,7 @@ typedef struct {
/// frequency_domain_resource;
uint8_t frequency_domain_resource[6];
uint8_t StartSymbolIndex;
uint16_t StartSymbolBitmap;
uint8_t duration;
uint8_t CceRegMappingType; // interleaved or noninterleaved
uint8_t RegBundleSize; // valid if CCE to REG mapping type is interleaved type
+4 -2
View File
@@ -175,8 +175,10 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB)
if (cfg->analog_beamforming_ve.analog_bf_vendor_ext.value) {
common_vars->beam_id = (int **)malloc16(common_vars->num_beams_period * sizeof(int*));
for (int i = 0; i < common_vars->num_beams_period; i++)
common_vars->beam_id[i] = (int*)malloc16_clear(fp->symbols_per_slot * fp->slots_per_frame * sizeof(int));
for (int i = 0; i < common_vars->num_beams_period; i++) {
common_vars->beam_id[i] = (int*)malloc16(fp->symbols_per_slot * fp->slots_per_frame * sizeof(int));
memset(common_vars->beam_id[i], -1, fp->symbols_per_slot * fp->slots_per_frame * sizeof(int));
}
}
common_vars->txdataF = (c16_t ***)malloc16(common_vars->num_beams_period * sizeof(c16_t**));
for (int i = 0; i < common_vars->num_beams_period; i++) {
+4 -2
View File
@@ -53,8 +53,10 @@ void nr_phy_init_RU(RU_t *ru)
int nb_rx_streams = ru->nb_rx * ru->num_beams_period;
LOG_I(NR_PHY, "nb_tx_streams %d, nb_rx_streams %d, num_Beams_period %d\n", nb_tx_streams, nb_rx_streams, ru->num_beams_period);
ru->common.beam_id = malloc16_clear(ru->num_beams_period * sizeof(int*));
for(int i = 0; i < ru->num_beams_period; i++)
ru->common.beam_id[i] = malloc16_clear(fp->symbols_per_slot * fp->slots_per_frame * sizeof(int));
for(int i = 0; i < ru->num_beams_period; i++) {
ru->common.beam_id[i] = malloc16(fp->symbols_per_slot * fp->slots_per_frame * sizeof(int));
memset(ru->common.beam_id[i], -1, fp->symbols_per_slot * fp->slots_per_frame * sizeof(int));
}
if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so allocate memory for time-domain signals
// Time-domain signals
+6 -8
View File
@@ -117,14 +117,12 @@ void init_symbol_rotation(NR_DL_FRAME_PARMS *fp);
void init_timeshift_rotation(NR_DL_FRAME_PARMS *fp);
void apply_nr_rotation_RX(const NR_DL_FRAME_PARMS *frame_parms,
c16_t *rxdataF,
const c16_t *rot,
int slot,
int nb_rb,
int soffset,
int first_symbol,
int nsymb);
void apply_nr_rotation_symbol_RX(const NR_DL_FRAME_PARMS *frame_parms,
c16_t *rxdataF,
const c16_t *rot,
int nb_rb,
int slot,
int symbol);
/*! \brief Perform NR precoding. TS 38.211 V15.4.0 subclause 6.3.1.5
@param[in] datatx_F_precoding, Pointer to n_layers*re data array
+101 -92
View File
@@ -28,6 +28,36 @@
#include "PHY/nr_phy_common/inc/nr_phy_common.h"
#include <common/utils/LOG/log.h>
/* rxdataF should be 16 bytes aligned */
void nr_symbol_fep(const NR_DL_FRAME_PARMS *frame_parms,
const int slot,
const unsigned char symbol,
const int link_type,
c16_t *rxdata[frame_parms->nb_antennas_rx],
c16_t *rxdataF[frame_parms->nb_antennas_rx],
time_stats_t* dft_stats)
{
AssertFatal(symbol < frame_parms->symbols_per_slot,
"slot_fep: symbol must be between 0 and %d\n",
frame_parms->symbols_per_slot - 1);
AssertFatal(slot < frame_parms->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_parms->slots_per_frame - 1);
dft_size_idx_t dftsize = get_dft(frame_parms->ofdm_symbol_size);
for (unsigned char aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
if (dft_stats) start_meas(dft_stats);
dft(dftsize, (int16_t *)rxdata[aa], (int16_t *)rxdataF[aa], 1);
if (dft_stats) stop_meas(dft_stats);
const bool is_sl = (link_type == link_type_sl);
apply_nr_rotation_symbol_RX(frame_parms,
rxdataF[aa],
frame_parms->symbol_rotation[link_type],
is_sl ? frame_parms->N_RB_SL : frame_parms->N_RB_DL,
slot,
symbol);
}
}
int nr_slot_fep(PHY_VARS_NR_UE *ue,
const NR_DL_FRAME_PARMS *frame_parms,
unsigned int slot,
@@ -37,35 +67,23 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
uint32_t sample_offset,
c16_t **rxdata)
{
AssertFatal(symbol < frame_parms->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_parms->symbols_per_slot-1);
AssertFatal(symbol < frame_parms->symbols_per_slot,
"slot_fep: symbol must be between 0 and %d\n",
frame_parms->symbols_per_slot - 1);
AssertFatal(slot < frame_parms->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_parms->slots_per_frame - 1);
bool is_sl = (linktype == link_type_sl) ? true : false;
bool is_sl = (linktype == link_type_sl);
bool is_synchronized = (ue) ? ue->is_synchronized : false;
unsigned int nb_prefix_samples;
unsigned int nb_prefix_samples0;
unsigned int nb_prefix_samples = frame_parms->nb_prefix_samples;
unsigned int nb_prefix_samples0 = (is_synchronized || is_sl) ? frame_parms->nb_prefix_samples0 : nb_prefix_samples;
// For Sidelink 16 frames worth of samples is processed to find SSB, for 5G-NR 2.
unsigned int total_samples = (is_sl) ? 16 * frame_parms->samples_per_frame : 2 * frame_parms->samples_per_frame;
int N_RB = (is_sl) ? frame_parms->N_RB_SL : frame_parms->N_RB_DL;
if (is_synchronized || is_sl) {
nb_prefix_samples = frame_parms->nb_prefix_samples;
nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
} else {
nb_prefix_samples = frame_parms->nb_prefix_samples;
nb_prefix_samples0 = frame_parms->nb_prefix_samples;
AssertFatal(slot == 0, "Slot should be 0\n");
}
dft_size_idx_t dftsize = get_dft(frame_parms->ofdm_symbol_size);
// This is for misalignment issues
c16_t tmp_dft_in[frame_parms->ofdm_symbol_size] __attribute__ ((aligned (32)));
const unsigned int total_samples = (is_sl) ? 16 * frame_parms->samples_per_frame : 2 * frame_parms->samples_per_frame;
unsigned int rx_offset = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0);
unsigned int abs_symbol = slot * frame_parms->symbols_per_slot + symbol;
const unsigned int abs_symbol = slot * frame_parms->symbols_per_slot + symbol;
for (int idx_symb = slot * frame_parms->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++)
rx_offset += (idx_symb%(0x7<<frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
rx_offset += (idx_symb % (0x7 << frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
rx_offset += frame_parms->ofdm_symbol_size * symbol;
rx_offset += sample_offset;
@@ -73,48 +91,47 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
// use OFDM symbol from within 1/8th of the CP to avoid ISI
rx_offset -= (nb_prefix_samples / frame_parms->ofdm_offset_divisor);
rx_offset %= total_samples;
for (unsigned char aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
c16_t *rxdata_ptr = &rxdata[aa][rx_offset];
LOG_D(PHY,
"slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, rx_offset %u energy %d\n",
slot,
symbol,
nb_prefix_samples,
nb_prefix_samples0,
rx_offset,
dB_fixed(signal_energy((int32_t *)&rxdata[0][rx_offset], frame_parms->ofdm_symbol_size)));
c16_t tmp_dft_in[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
c16_t *rxdata_symb_ptr[frame_parms->nb_antennas_rx];
c16_t *rxdataF_symb_ptr[frame_parms->nb_antennas_rx];
for (unsigned char aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
rxdataF_symb_ptr[aa] = &rxdataF[aa][frame_parms->ofdm_symbol_size * symbol];
// This happens only during initial sync
if (rx_offset + frame_parms->ofdm_symbol_size > total_samples) {
// rxdata is 2 frames len
// we have to wrap on the end
memcpy((void *)&tmp_dft_in[0], (void *)&rxdata[aa][rx_offset], (total_samples - rx_offset) * sizeof(int32_t));
memcpy((void *)&tmp_dft_in[total_samples - rx_offset],
(void *)&rxdata[aa][0],
memcpy(&tmp_dft_in[aa][0], &rxdata[aa][rx_offset], (total_samples - rx_offset) * sizeof(int32_t));
memcpy(&tmp_dft_in[aa][total_samples - rx_offset],
&rxdata[aa][0],
(frame_parms->ofdm_symbol_size - (total_samples - rx_offset)) * sizeof(int32_t));
rxdata_ptr = tmp_dft_in;
} else if ((rx_offset & 7) != 0) { // if input to dft is not 256-bit aligned
memcpy((void *)&tmp_dft_in[0], (void *)&rxdata[aa][rx_offset], frame_parms->ofdm_symbol_size * sizeof(int32_t));
rxdata_ptr = tmp_dft_in;
rxdata_symb_ptr[aa] = tmp_dft_in[aa];
} else {
rxdata_symb_ptr[aa] = &rxdata[aa][rx_offset];
}
if (ue && ue->cont_fo_comp) {
start_meas_nr_ue_phy(ue, RX_FO_COMPENSATION_STATS);
nr_fo_compensation(ue->freq_offset, frame_parms->samples_per_subframe, rx_offset, rxdata_ptr, tmp_dft_in, frame_parms->ofdm_symbol_size);
rxdata_ptr = tmp_dft_in;
nr_fo_compensation(ue->freq_offset,
frame_parms->samples_per_subframe,
rx_offset,
rxdata_symb_ptr[aa],
tmp_dft_in[aa],
frame_parms->ofdm_symbol_size);
stop_meas_nr_ue_phy(ue, RX_FO_COMPENSATION_STATS);
rxdata_symb_ptr[aa] = tmp_dft_in[aa];
}
if (ue)
start_meas_nr_ue_phy(ue, RX_DFT_STATS);
dft(dftsize,
(int16_t *)rxdata_ptr,
(int16_t *)&rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
1);
if (ue)
stop_meas_nr_ue_phy(ue, RX_DFT_STATS);
apply_nr_rotation_RX(frame_parms, rxdataF[aa], frame_parms->symbol_rotation[linktype], slot, N_RB, 0, symbol, 1);
}
time_stats_t* dft_stats = NULL;
if (ue) dft_stats = &ue->phy_cpu_stats.cpu_time_stats[RX_DFT_STATS];
nr_symbol_fep(frame_parms, slot, symbol, linktype, rxdata_symb_ptr, rxdataF_symb_ptr, dft_stats);
return 0;
}
@@ -177,54 +194,46 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
return 0;
}
void apply_nr_rotation_RX(const NR_DL_FRAME_PARMS *frame_parms,
c16_t *rxdataF,
const c16_t *rot,
int slot,
int nb_rb,
int soffset,
int first_symbol,
int nsymb)
void apply_nr_rotation_symbol_RX(const NR_DL_FRAME_PARMS *frame_parms,
c16_t *rxdataF,
const c16_t *rot,
int nb_rb,
int slot,
int symbol)
{
AssertFatal(first_symbol + nsymb <= NR_NUMBER_OF_SYMBOLS_PER_SLOT,
"First symbol %d and number of symbol %d not compatible with number of symbols in a slot %d\n",
first_symbol, nsymb, NR_NUMBER_OF_SYMBOLS_PER_SLOT);
int symb_offset = (slot % frame_parms->slots_per_subframe) * frame_parms->symbols_per_slot;
const int symb_offset = (slot % frame_parms->slots_per_subframe) * frame_parms->symbols_per_slot;
for (int symbol = first_symbol; symbol < first_symbol + nsymb; symbol++) {
c16_t rot2 = rot[symbol + symb_offset];
rot2.i = -rot2.i;
LOG_D(PHY,"slot %d, symb_offset %d rotating by %d.%d\n", slot, symb_offset, rot2.r, rot2.i);
const c16_t *shift_rot = frame_parms->timeshift_symbol_rotation;
c16_t *this_symbol = &rxdataF[soffset + (frame_parms->ofdm_symbol_size * symbol)];
c16_t rot2 = rot[symbol + symb_offset];
rot2.i = -rot2.i;
LOG_D(PHY,"slot %d, symb_offset %d rotating by %d.%d\n", slot, symb_offset, rot2.r, rot2.i);
const c16_t *shift_rot = frame_parms->timeshift_symbol_rotation;
c16_t *this_symbol = rxdataF;
if (nb_rb & 1) {
rotate_cpx_vector(this_symbol, &rot2, this_symbol,
(nb_rb + 1) * 6, 15);
rotate_cpx_vector(this_symbol + frame_parms->first_carrier_offset - 6,
&rot2,
this_symbol + frame_parms->first_carrier_offset - 6,
(nb_rb + 1) * 6, 15);
mult_cpx_vector(this_symbol, shift_rot, this_symbol, (nb_rb + 1) * 6, 15);
mult_cpx_vector(this_symbol + frame_parms->first_carrier_offset - 6,
shift_rot + frame_parms->first_carrier_offset - 6,
if (nb_rb & 1) {
rotate_cpx_vector(this_symbol, &rot2, this_symbol, (nb_rb + 1) * 6, 15);
rotate_cpx_vector(this_symbol + frame_parms->first_carrier_offset - 6,
&rot2,
this_symbol + frame_parms->first_carrier_offset - 6,
(nb_rb + 1) * 6,
15);
} else {
rotate_cpx_vector(this_symbol, &rot2, this_symbol,
nb_rb * 6, 15);
rotate_cpx_vector(this_symbol + frame_parms->first_carrier_offset,
&rot2,
this_symbol + frame_parms->first_carrier_offset,
nb_rb * 6, 15);
mult_cpx_vector(this_symbol, shift_rot, this_symbol, nb_rb * 6, 15);
mult_cpx_vector(this_symbol + frame_parms->first_carrier_offset,
shift_rot + frame_parms->first_carrier_offset,
mult_cpx_vector(this_symbol, shift_rot, this_symbol, (nb_rb + 1) * 6, 15);
mult_cpx_vector(this_symbol + frame_parms->first_carrier_offset - 6,
shift_rot + frame_parms->first_carrier_offset - 6,
this_symbol + frame_parms->first_carrier_offset - 6,
(nb_rb + 1) * 6,
15);
} else {
rotate_cpx_vector(this_symbol, &rot2, this_symbol, nb_rb * 6, 15);
rotate_cpx_vector(this_symbol + frame_parms->first_carrier_offset,
&rot2,
this_symbol + frame_parms->first_carrier_offset,
nb_rb * 6,
15);
}
mult_cpx_vector(this_symbol, shift_rot, this_symbol, nb_rb * 6, 15);
mult_cpx_vector(this_symbol + frame_parms->first_carrier_offset,
shift_rot + frame_parms->first_carrier_offset,
this_symbol + frame_parms->first_carrier_offset,
nb_rb * 6,
15);
}
}
@@ -136,7 +136,7 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_sy
// TODO modify the measurements to take into account concurrent beams
for (int s = first_symb; s < first_symb + num_symb; s++) {
int offset0 = ((slot&3)*frame_parms->symbols_per_slot + s) * frame_parms->ofdm_symbol_size;
int offset0 = ((slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot + s) * frame_parms->ofdm_symbol_size;
for (int rb = 0; rb < frame_parms->N_RB_UL; rb++) {
if ((rb_mask_ul[s][rb >> 5] & (1U << (rb & 31))) == 0 && // check that rb was not used in this subframe
!(I0_SKIP_DC && rb == frame_parms->N_RB_UL >> 1)) { // skip middle PRB because of artificial noise possibly created by FFT
@@ -188,74 +188,3 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_sy
}
}
}
// Scope: This function computes the UL SNR from the UL channel estimates
//
// Todo:
// - averaging IIR filter for RX power and noise
void nr_gnb_measurements(PHY_VARS_gNB *gNB,
NR_gNB_ULSCH_t *ulsch,
NR_gNB_PUSCH *pusch_vars,
unsigned char symbol,
uint8_t nrOfLayers)
{
uint32_t rx_power_tot = 0;
unsigned short rx_power_avg_dB;
unsigned short rx_power_tot_dB;
RU_t *ru = gNB->RU_list[0];
double rx_gain, rx_gain_offset;
if (ru && ru->rfdevice.openair0_cfg) {
rx_gain = ru->rfdevice.openair0_cfg->rx_gain[0];
rx_gain_offset = ru->rfdevice.openair0_cfg->rx_gain_offset[0];
} else if (ru && ru->ifdevice.openair0_cfg) {
rx_gain = ru->ifdevice.openair0_cfg->rx_gain[0];
rx_gain_offset = ru->ifdevice.openair0_cfg->rx_gain_offset[0];
} else {
LOG_W(NR_PHY, "no device for rx gain, take arbitrary gain = 1)\n");
rx_gain = 1;
rx_gain_offset = 0;
}
PHY_MEASUREMENTS_gNB *meas = &gNB->measurements;
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
int ch_offset = fp->ofdm_symbol_size * symbol;
int N_RB_UL = ulsch->harq_process->ulsch_pdu.rb_size;
ulsch_measurements_gNB *ulsch_measurements = &ulsch->ulsch_measurements;
int rx_power[fp->nb_antennas_rx];
int rx_spatial_power[nrOfLayers][fp->nb_antennas_rx];
for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++){
rx_power[aarx] = 0;
for (int aatx = 0; aatx < nrOfLayers; aatx++){
rx_spatial_power[aatx][aarx] =
(signal_energy_nodc((c16_t*)&pusch_vars->ul_ch_estimates[aatx * fp->nb_antennas_rx + aarx][ch_offset],
N_RB_UL * NR_NB_SC_PER_RB));
if (rx_spatial_power[aatx][aarx] < 0) {
rx_spatial_power[aatx][aarx] = 0;
}
rx_power[aarx] += rx_spatial_power[aatx][aarx];
}
LOG_D(PHY, "[RNTI %04x] RX power in antenna %d = %d\n", ulsch->rnti, aarx, rx_power[aarx]);
rx_power_tot += rx_power[aarx];
}
rx_power_tot_dB = (unsigned short)dB_fixed(rx_power_tot);
rx_power_avg_dB = rx_power_tot_dB;
ulsch_measurements->wideband_cqi_tot = dB_fixed2(rx_power_tot, meas->n0_power_tot);
ulsch_measurements->rx_rssi_dBm =
rx_power_avg_dB + 30 - SQ15_SQUARED_NORM_FACTOR_DB - (rx_gain - rx_gain_offset) - dB_fixed(fp->ofdm_symbol_size);
LOG_D(PHY,
"[RNTI %04x] RSSI %d dBm/RE, RSSI (digital) %d dB (N_RB_UL %d), WBand CQI tot %d dB, N0 Power tot %d, RX Power tot %d\n",
ulsch->rnti,
ulsch_measurements->rx_rssi_dBm,
rx_power_avg_dB,
N_RB_UL,
ulsch_measurements->wideband_cqi_tot,
meas->n0_power_tot,
rx_power_tot);
}
@@ -111,7 +111,7 @@ static void nr_pusch_antenna_processing(void *arg)
c16_t **ul_ch_estimates = (c16_t **)pusch_vars->ul_ch_estimates;
NR_DL_FRAME_PARMS *frame_parms = rdata->frame_parms;
const int symbolSize = frame_parms->ofdm_symbol_size;
const int slot_offset = (Ns & 3) * frame_parms->symbols_per_slot * symbolSize;
const int slot_offset = (Ns % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot * symbolSize;
const int delta = get_delta(p, pusch_pdu->dmrs_config_type);
const int symbol_offset = symbolSize * symbol;
const int k0 = bwp_start_subcarrier;
@@ -59,12 +59,6 @@ void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB);
void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_symb, uint32_t rb_mask_ul[14][9]);
void nr_gnb_measurements(PHY_VARS_gNB *gNB,
NR_gNB_ULSCH_t *ulsch,
NR_gNB_PUSCH *pusch_vars,
unsigned char symbol,
uint8_t nrOfLayers);
int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms,
const c16_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size]);
+1 -3
View File
@@ -150,9 +150,7 @@ int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue,
return(0);
}
int nr_pdcch_dmrs_rx(const PHY_VARS_NR_UE *ue,
unsigned int Ns,
const unsigned int *nr_gold_pdcch,
int nr_pdcch_dmrs_rx(const unsigned int *nr_gold_pdcch,
c16_t *output,
unsigned short p,
unsigned short nb_rb_coreset)
+1 -3
View File
@@ -35,9 +35,7 @@ void nr_pbch_dmrs_rx(int dmrss, const unsigned int *nr_gold_pbch, c16_t *output,
/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PDCCH DMRS.
@param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
*/
int nr_pdcch_dmrs_rx(const PHY_VARS_NR_UE *ue,
unsigned int Ns,
const unsigned int *nr_gold_pdcch,
int nr_pdcch_dmrs_rx(const unsigned int *nr_gold_pdcch,
c16_t *output,
unsigned short p,
unsigned short nb_rb_corset);
@@ -1188,12 +1188,7 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
pusch_ch_est_dmrs_pos_slot_mem);
nvar += nvar_tmp;
}
// measure the SNR from the channel estimation
nr_gnb_measurements(gNB,
&gNB->ulsch[ulsch_id],
pusch_vars,
symbol,
rel15_ul->nrOfLayers);
allocCast2D(n0_subband_power,
unsigned int,
gNB->measurements.n0_subband_power,
@@ -1212,7 +1207,7 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
int end_sc = (start_sc + rel15_ul->rb_size * NR_NB_SC_PER_RB - 1) % frame_parms->ofdm_symbol_size;
for (int s = rel15_ul->start_symbol_index; s < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); s++) {
int offset0 = ((slot & 3) * frame_parms->symbols_per_slot + s) * frame_parms->ofdm_symbol_size;
int offset0 = ((slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot + s) * frame_parms->ofdm_symbol_size;
int offset = offset0 + (frame_parms->first_carrier_offset + start_sc) % frame_parms->ofdm_symbol_size;
c16_t *ul_ch = &gNB->common_vars.rxdataF[beam_nb][aarx][offset];
if (end_sc < start_sc) {
+1 -1
View File
@@ -161,7 +161,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
nfapi_nr_pucch_pdu_t *pucch_pdu)
{
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
int soffset = (slot & 3) * frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size;
int soffset = (slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size;
AssertFatal(pucch_pdu->bit_len_harq > 0 || pucch_pdu->sr_flag > 0,
"Either bit_len_harq (%d) or sr_flag (%d) must be > 0\n",
@@ -805,17 +805,12 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
uint16_t BWPStart,
int32_t pdcch_est_size,
c16_t pdcch_dl_ch_estimates[][pdcch_est_size],
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
c16_t rxdataF[ue->frame_parms.nb_antennas_rx][ue->frame_parms.ofdm_symbol_size])
{
int slot = proc->nr_slot_rx;
unsigned char aarx;
unsigned short k;
unsigned int pilot_cnt;
int ch_offset,symbol_offset;
ch_offset = ue->frame_parms.ofdm_symbol_size*symbol;
symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;
int nb_rb_coreset=0;
int coreset_start_rb=0;
@@ -830,8 +825,7 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
unsigned short coreset_start_subcarrier = first_carrier_offset+(BWPStart + coreset_start_rb)*12;
#ifdef DEBUG_PDCCH
printf("PDCCH Channel Estimation : ch_offset %d, OFDM size %d, Ncp=%d, slot=%d, symbol %d\n",
ch_offset,
printf("PDCCH Channel Estimation : OFDM size %d, Ncp=%d, slot=%d, symbol %d\n",
ue->frame_parms.ofdm_symbol_size,
ue->frame_parms.Ncp,
slot,
@@ -852,14 +846,14 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
c16_t pilot[(nb_rb_coreset + dmrs_ref) * 3] __attribute__((aligned(16)));
// Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS
const uint32_t *gold = nr_gold_pdcch(ue->frame_parms.N_RB_DL, ue->frame_parms.symbols_per_slot, scrambling_id, slot, symbol);
nr_pdcch_dmrs_rx(ue, slot, gold, pilot, 2000, (nb_rb_coreset + dmrs_ref));
nr_pdcch_dmrs_rx(gold, pilot, 2000, (nb_rb_coreset + dmrs_ref));
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
k = coreset_start_subcarrier;
c16_t *pil = &pilot[dmrs_ref * 3];
c16_t *rxF = &rxdataF[aarx][symbol_offset + k + 1];
c16_t *dl_ch = &pdcch_dl_ch_estimates[aarx][ch_offset];
c16_t *rxF = &rxdataF[aarx][k + 1];
c16_t *dl_ch = &pdcch_dl_ch_estimates[aarx][0];
memset(dl_ch, 0, sizeof(c16_t) * ue->frame_parms.ofdm_symbol_size);
@@ -879,29 +873,29 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
if (k >= ue->frame_parms.ofdm_symbol_size) {
k -= ue->frame_parms.ofdm_symbol_size;
rxF = &rxdataF[aarx][(symbol_offset + k + 1)];
rxF = &rxdataF[aarx][k + 1];
}
multadd_real_vector_complex_scalar(fm, c16mulShift(*pil++, *rxF, 15), dl_ch, 16);
k = (k + 4) % ue->frame_parms.ofdm_symbol_size;
rxF = (c16_t *)&rxdataF[aarx][(symbol_offset + k + 1)];
rxF = (c16_t *)&rxdataF[aarx][k + 1)];
multadd_real_vector_complex_scalar(fr, c16mulShift(*pil++, *rxF, 15), dl_ch, 16);
dl_ch += 12;
k = (k + 4) % ue->frame_parms.ofdm_symbol_size;
rxF = (c16_t *)&rxdataF[aarx][(symbol_offset + k + 1)];
rxF = (c16_t *)&rxdataF[aarx][k + 1];
for (pilot_cnt=3; pilot_cnt<(3*nb_rb_coreset); pilot_cnt += 3) {
multadd_real_vector_complex_scalar(fl, c16mulShift(*pil++, *rxF, 15), dl_ch, 16);
k = (k + 4) % ue->frame_parms.ofdm_symbol_size;
rxF = (c16_t *)&rxdataF[aarx][(symbol_offset + k + 1)];
rxF = (c16_t *)&rxdataF[aarx][k + 1];
multadd_real_vector_complex_scalar(fm, c16mulShift(*pil++, *rxF, 15), dl_ch, 16);
k = (k + 4) % ue->frame_parms.ofdm_symbol_size;
rxF = (c16_t *)&rxdataF[aarx][(symbol_offset + k + 1)];
rxF = (c16_t *)&rxdataF[aarx][k + 1];
multadd_real_vector_complex_scalar(fr, c16mulShift(*pil++, *rxF, 15), dl_ch, 16);
dl_ch += 12;
k = (k + 4) % ue->frame_parms.ofdm_symbol_size;
rxF = (c16_t *)&rxdataF[aarx][(symbol_offset + k + 1)];
rxF = (c16_t *)&rxdataF[aarx][k + 1];
}
#else //ELSE CH_INTERP
c32_t ch_sum = {0, 0};
@@ -915,7 +909,7 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
ch_sum.r += ch.r;
ch_sum.i += ch.i;
k = (k + 4) % ue->frame_parms.ofdm_symbol_size;
rxF = (c16_t *)&rxdataF[aarx][(symbol_offset + k + 1)];
rxF = (c16_t *)&rxdataF[aarx][k + 1];
if (pilot_cnt % 3 == 2) {
ch.r = ch_sum.r / 3;
@@ -52,7 +52,7 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
uint16_t BWPStart,
int32_t pdcch_est_size,
c16_t pdcch_dl_ch_estimates[][pdcch_est_size],
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
c16_t rxdataF[ue->frame_parms.nb_antennas_rx][ue->frame_parms.ofdm_symbol_size]);
c32_t nr_pbch_dmrs_correlation(const NR_DL_FRAME_PARMS *fp,
const UE_nr_rxtx_proc_t *proc,
@@ -125,8 +125,9 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue,
for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
ue->measurements.rx_power_avg_dB[gNB_id] = dB_fixed( ue->measurements.rx_power_avg[gNB_id]);
ue->measurements.n0_power_avg_dB = dB_fixed(ue->measurements.n0_power_avg);
ue->measurements.wideband_cqi_tot[gNB_id] = ue->measurements.rx_power_tot_dB[gNB_id] - ue->measurements.n0_power_tot_dB;
ue->measurements.wideband_cqi_avg[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] - dB_fixed(ue->measurements.n0_power_avg);
ue->measurements.wideband_cqi_avg[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] - ue->measurements.n0_power_avg_dB;
ue->measurements.rx_rssi_dBm[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] + 30 - SQ15_SQUARED_NORM_FACTOR_DB
- ((int)ue->openair0_cfg[0].rx_gain[0] - (int)ue->openair0_cfg[0].rx_gain_offset[0])
- dB_fixed(ue->frame_parms.ofdm_symbol_size);
+266 -135
View File
@@ -41,6 +41,7 @@
#include "common/utils/nr/nr_common.h"
#include <openair1/PHY/TOOLS/phy_scope_interface.h>
#include "openair1/PHY/NR_REFSIG/nr_refsig_common.h"
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
#include "assertions.h"
#include "T.h"
@@ -72,10 +73,10 @@
#define RE_PER_RB_OUT_DMRS 9
static void nr_pdcch_demapping_deinterleaving(uint32_t coreset_nbr_rb,
c16_t llr[][coreset_nbr_rb * RE_PER_RB_OUT_DMRS],
c16_t *llr,
c16_t *e_rx,
uint8_t coreset_time_dur,
uint8_t reg_bundle_size_L,
uint8_t reg_bundle_size_L_in,
uint8_t coreset_interleaver_size_R,
uint8_t n_shift,
uint8_t number_of_candidates,
@@ -118,17 +119,11 @@ static void nr_pdcch_demapping_deinterleaving(uint32_t coreset_nbr_rb,
| REG 0 (bundle 0) bundle 0 bundle 0
*/
uint32_t coreset_C = 0;
int coreset_interleaved = 0;
const int N_regs = coreset_nbr_rb * coreset_time_dur;
if (reg_bundle_size_L != 0) { // interleaving will be done only if reg_bundle_size_L != 0
coreset_interleaved = 1;
coreset_C = (uint32_t)(N_regs / (coreset_interleaver_size_R * reg_bundle_size_L));
} else {
reg_bundle_size_L = 6;
}
/* interleaving will be done only if reg_bundle_size_L != 0 */
const int coreset_C = (reg_bundle_size_L_in != 0) ? (uint32_t)(N_regs / (coreset_interleaver_size_R * reg_bundle_size_L_in)) : 0;
const int coreset_interleaved = (reg_bundle_size_L_in != 0) ? 1 : 0;
const int reg_bundle_size_L = (reg_bundle_size_L_in != 0) ? reg_bundle_size_L_in : 6;
int B_rb = reg_bundle_size_L / coreset_time_dur; // nb of RBs occupied by each REG bundle
int num_bundles_per_cce = 6 / reg_bundle_size_L;
@@ -173,7 +168,7 @@ static void nr_pdcch_demapping_deinterleaving(uint32_t coreset_nbr_rb,
for (int cce_count = 0; cce_count < L[c_id]; cce_count++) {
for (int k = 0; k < NR_NB_REG_PER_CCE / reg_bundle_size_L; k++) { // loop over REG bundles
int f = f_bundle_j_list_ord[c_id][k + NR_NB_REG_PER_CCE * cce_count / reg_bundle_size_L];
c16_t *in = llr[symbol_idx] + f * B_rb * RE_PER_RB_OUT_DMRS;
c16_t *in = llr + (f * B_rb + symbol_idx * coreset_nbr_rb) * RE_PER_RB_OUT_DMRS;
// loop over the RBs of the bundle
memcpy(e_rx + RE_PER_RB_OUT_DMRS * rb_count, in, B_rb * RE_PER_RB_OUT_DMRS * sizeof(*e_rx));
rb_count += B_rb;
@@ -200,16 +195,15 @@ static void nr_pdcch_llr(uint32_t sz, c16_t *rxF, c16_t *llr)
// This function will extract the mapped DM-RS PDCCH REs as per 38.211 Section 7.4.1.3.2 (Mapping to physical resources)
static void nr_pdcch_extract_rbs_single(uint32_t rxdataF_sz,
uint32_t coreset_nbr_rb,
c16_t rxdataF[][rxdataF_sz],
int32_t est_size,
c16_t dl_ch_estimates[][est_size],
int arraySz,
c16_t rxdataF_ext[][arraySz],
c16_t dl_ch_estimates_ext[][arraySz],
int symbol,
NR_DL_FRAME_PARMS *frame_parms,
uint8_t *coreset_freq_dom,
uint32_t coreset_nbr_rb,
uint32_t n_BWP_start)
{
/*
@@ -224,8 +218,8 @@ static void nr_pdcch_extract_rbs_single(uint32_t rxdataF_sz,
*/
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
const c16_t *dl_ch0 = dl_ch_estimates[aarx] + frame_parms->ofdm_symbol_size * symbol;
c16_t *rxFbase = rxdataF[aarx] + frame_parms->ofdm_symbol_size * symbol;
c16_t *dl_ch0 = dl_ch_estimates[aarx];
c16_t *rxFbase = rxdataF[aarx];
LOG_DDD("dl_ch0 = &dl_ch_estimates[aarx = (%d)][0]\n", aarx);
c16_t *dl_ch0_ext = dl_ch_estimates_ext[aarx];
@@ -249,44 +243,52 @@ static void nr_pdcch_extract_rbs_single(uint32_t rxdataF_sz,
* the position 0+c_rb-N_RB_DL/2 in rxdataF and we have to point the pointer at (1+c_rb-N_RB_DL/2) in rxdataF
*/
int c_rb = 0;
for (int rb = 0; rb < coreset_nbr_rb; rb++, c_rb++) {
int c_rb_by6 = c_rb / 6;
c16_t middle_prb_buffer[RE_PER_RB];
for (int rb_group = 0; rb_group < coreset_nbr_rb / 6; rb_group++) {
if ((coreset_freq_dom[rb_group / 8] & (1 << (7 - (rb_group & 7)))) == 0) {
continue;
}
for (int rb = 0; rb < 6; rb++) {
int c_rb = rb_group * 6 + rb;
c16_t *rxF = NULL;
if ((frame_parms->N_RB_DL & 1) == 0) {
if ((c_rb + n_BWP_start) < frame_parms->N_RB_DL / 2)
// if RB to be treated is lower than middle system bandwidth then rxdataF pointed
// at (offset + c_br + symbol * ofdm_symbol_size): even case
rxF = rxFbase + frame_parms->first_carrier_offset + RE_PER_RB * (c_rb + n_BWP_start);
else
// number of RBs is even and c_rb is higher than half system bandwidth (we don't skip DC)
// if these conditions are true the pointer has to be situated at the 1st part of the rxdataF
// we point at the 1st part of the rxdataF in symbol
rxF = rxFbase + RE_PER_RB * (c_rb + n_BWP_start - frame_parms->N_RB_DL / 2);
} else {
if ((c_rb + n_BWP_start) <= frame_parms->N_RB_DL / 2)
// if RB to be treated is lower than middle system bandwidth then rxdataF pointed
// at (offset + c_br + symbol * ofdm_symbol_size): odd case
// Reassemble the middle PRB
if (c_rb + n_BWP_start == frame_parms->N_RB_DL / 2) {
memcpy(middle_prb_buffer, rxFbase + frame_parms->ofdm_symbol_size - RE_PER_RB / 2, sizeof(c16_t) * RE_PER_RB / 2);
memcpy(middle_prb_buffer + RE_PER_RB / 2, rxFbase, sizeof(c16_t) * RE_PER_RB / 2);
rxF = middle_prb_buffer;
} else {
rxF = rxFbase + frame_parms->first_carrier_offset + RE_PER_RB * (c_rb + n_BWP_start);
}
// skip zeros in frequency domain bitmap
while ((coreset_freq_dom[c_rb_by6 / 8] & (1 << (7 - (c_rb_by6 & 7)))) == 0) {
c_rb += 6;
c_rb_by6 = c_rb / 6;
else
// number of RBs is odd and c_rb is higher than half system bandwidth + 1
// if these conditions are true the pointer has to be situated at the 1st part of
// the rxdataF just after the first IQ symbols of the RB containing DC
// we point at the 1st part of the rxdataF in symbol
rxF = rxFbase + RE_PER_RB * (c_rb + n_BWP_start - frame_parms->N_RB_DL / 2) - 6;
}
const int valid_re[RE_PER_RB_OUT_DMRS] = {0, 2, 3, 4, 6, 7, 8, 10, 11};
for (int i = 0; i < sizeofArray(valid_re); i++) {
*rxF_ext++ = rxF[valid_re[i]];
*dl_ch0_ext++ = dl_ch0[valid_re[i]];
}
dl_ch0 += RE_PER_RB;
}
c16_t *rxF = NULL;
if ((frame_parms->N_RB_DL & 1) == 0) {
if ((c_rb + n_BWP_start) < frame_parms->N_RB_DL / 2)
// if RB to be treated is lower than middle system bandwidth then rxdataF pointed
// at (offset + c_br + symbol * ofdm_symbol_size): even case
rxF = rxFbase + frame_parms->first_carrier_offset + RE_PER_RB * (c_rb + n_BWP_start);
else
// number of RBs is even and c_rb is higher than half system bandwidth (we don't skip DC)
// if these conditions are true the pointer has to be situated at the 1st part of the rxdataF
// we point at the 1st part of the rxdataF in symbol
rxF = rxFbase + RE_PER_RB * (c_rb + n_BWP_start - frame_parms->N_RB_DL / 2);
} else {
if ((c_rb + n_BWP_start) <= frame_parms->N_RB_DL / 2)
// if RB to be treated is lower than middle system bandwidth then rxdataF pointed
// at (offset + c_br + symbol * ofdm_symbol_size): odd case
rxF = rxFbase + frame_parms->first_carrier_offset + RE_PER_RB * (c_rb + n_BWP_start);
else
// number of RBs is odd and c_rb is higher than half system bandwidth + 1
// if these conditions are true the pointer has to be situated at the 1st part of
// the rxdataF just after the first IQ symbols of the RB containing DC
// we point at the 1st part of the rxdataF in symbol
rxF = rxFbase + RE_PER_RB * (c_rb + n_BWP_start - frame_parms->N_RB_DL / 2) - 6;
}
const int valid_re[RE_PER_RB_OUT_DMRS] = {0, 2, 3, 4, 6, 7, 8, 10, 11};
for (int i = 0; i < sizeofArray(valid_re); i++) {
*rxF_ext++ = rxF[valid_re[i]];
*dl_ch0_ext++ = dl_ch0[valid_re[i]];
}
dl_ch0 += RE_PER_RB;
}
}
}
@@ -318,92 +320,222 @@ static void nr_pdcch_detection_mrc(int sz, c16_t rxdataF_comp[][sz])
}
}
void nr_rx_pdcch(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
int32_t pdcch_est_size,
c16_t pdcch_dl_ch_estimates[][pdcch_est_size],
c16_t *pdcch_e_rx,
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
/* Produce LLRs from received PDCCH signal */
static void nr_rx_pdcch_symbol(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
int symbol,
int rel_symb_monOcc,
int ss_idx,
nr_phy_data_t *phy_data,
int llr_size_symbol,
c16_t rxdataF[ue->frame_parms.nb_antennas_rx][ue->frame_parms.ofdm_symbol_size],
c16_t llr[llr_size_symbol])
{
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config;
fapi_nr_coreset_t *coreset = &phy_pdcch_config->pdcch_config[ss_idx].coreset;
int32_t pdcch_est_size = ((((fp->ofdm_symbol_size + LTE_CE_FILTER_LENGTH) + 15) / 16) * 16);
__attribute__((aligned(16))) c16_t pdcch_dl_ch_estimates[fp->nb_antennas_rx][pdcch_est_size];
int n_rb,rb_offset;
get_coreset_rballoc(rel15->coreset.frequency_domain_resource,&n_rb,&rb_offset);
const int antRx = frame_parms->nb_antennas_rx;
nr_pdcch_channel_estimation(ue,
proc,
symbol,
coreset,
fp->first_carrier_offset,
phy_pdcch_config->pdcch_config[ss_idx].BWPStart,
pdcch_est_size,
pdcch_dl_ch_estimates,
rxdataF);
// Pointer to llrs
const int symb_size = n_rb * RE_PER_RB_OUT_DMRS;
c16_t llr[rel15->coreset.duration][symb_size];
const int32_t rx_size = ((4 * fp->N_RB_DL * 12 + 31) >> 5) << 5;
__attribute__((aligned(32))) c16_t rxdataF_ext[fp->nb_antennas_rx][rx_size];
__attribute__((aligned(32))) c16_t rxdataF_comp[fp->nb_antennas_rx][rx_size];
__attribute__((aligned(32))) c16_t pdcch_dl_ch_estimates_ext[fp->nb_antennas_rx][rx_size];
memset(rxdataF_comp, 0, sizeof(rxdataF_comp));
LOG_D(NR_PHY_DCI,
"pdcch coreset: freq %x, n_rb %d, rb_offset %d\n",
rel15->coreset.frequency_domain_resource[0],
n_rb,
rb_offset);
for (int s = 0; s < rel15->coreset.duration; s++) {
LOG_D(NR_PHY_DCI, "in nr_pdcch_extract_rbs_single(rxdataF -> rxdataF_ext || dl_ch_estimates -> dl_ch_estimates_ext)\n");
const int arraySz = ceil_mod(symb_size, 32);
__attribute__((aligned(32))) c16_t rxdataF_ext[antRx][arraySz];
__attribute__((aligned(32))) c16_t pdcch_dl_ch_estimates_ext[antRx][arraySz];
nr_pdcch_extract_rbs_single(ue->frame_parms.samples_per_slot_wCP,
n_rb,
rxdataF,
pdcch_est_size,
pdcch_dl_ch_estimates,
arraySz,
int n_rb;
int rb_offset;
get_coreset_rballoc(coreset->frequency_domain_resource, &n_rb, &rb_offset);
nr_pdcch_extract_rbs_single(ue->frame_parms.ofdm_symbol_size,
rxdataF,
pdcch_est_size,
pdcch_dl_ch_estimates,
rx_size,
rxdataF_ext,
pdcch_dl_ch_estimates_ext,
fp,
coreset->frequency_domain_resource,
n_rb,
phy_pdcch_config->pdcch_config[ss_idx].BWPStart);
LOG_D(NR_PHY_DCI, "in channel level function (dl_ch_estimates_ext -> dl_ch_estimates_ext)\n");
int avg[fp->nb_antennas_rx];
nr_channel_level(0, rx_size, pdcch_dl_ch_estimates_ext, fp->nb_antennas_rx, 1, avg, n_rb * RE_PER_RB_OUT_DMRS);
int avgs = avg[0];
for (int i = 1; i < fp->nb_antennas_rx; i++)
avgs = cmax(avgs, avg[i]);
const int log2_maxh = (log2_approx(avgs) / 2) + 5; //+frame_parms->nb_antennas_rx;
nr_pdcch_channel_compensation(rx_size,
rxdataF_ext,
pdcch_dl_ch_estimates_ext,
rel15->coreset.StartSymbolIndex + s,
frame_parms,
rel15->coreset.frequency_domain_resource,
rel15->BWPStart);
rxdataF_comp,
fp->nb_antennas_rx,
log2_maxh); // log2_maxh+I0_shift
LOG_D(NR_PHY_DCI, "in channel level function (dl_ch_estimates_ext -> dl_ch_estimates_ext)\n");
// compute channel level based on ofdm symbol 0
int avg[antRx];
nr_channel_level(0, arraySz, pdcch_dl_ch_estimates_ext, antRx, 1, avg, n_rb);
int avgs = avg[0];
for (int i = 1; i < antRx; i++)
avgs = cmax(avgs, avg[i]);
uint8_t log2_maxh = (log2_approx(avgs) / 2) + 5; //+antRx;
UEscopeCopy(ue, pdcchRxdataF_comp, rxdataF_comp, sizeof(struct complex16), fp->nb_antennas_rx, rx_size, 0);
#ifdef UE_DEBUG_TRACE
LOG_D(NR_PHY_DCI, "slot %d: pdcch log2_maxh = %d (%d,%d)\n", proc->nr_slot_rx, log2_maxh, avgP[0], avgs);
#endif
#if T_TRACER
T(T_UE_PHY_PDCCH_ENERGY, T_INT(0), T_INT(0), T_INT(proc->frame_rx % 1024), T_INT(proc->nr_slot_rx), T_INT(avgs));
#endif
LOG_D(NR_PHY_DCI, "we enter nr_pdcch_channel_compensation(log2_maxh=%d)\n", log2_maxh);
LOG_D(NR_PHY_DCI, "in nr_pdcch_channel_compensation(rxdataF_ext x dl_ch_estimates_ext -> rxdataF_comp)\n");
// compute LLRs for ofdm symbol 0 only
__attribute__((aligned(32))) c16_t rxdataF_comp[antRx][arraySz];
nr_pdcch_channel_compensation(arraySz,
rxdataF_ext,
pdcch_dl_ch_estimates_ext,
rxdataF_comp,
antRx,
log2_maxh); // log2_maxh+I0_shift
UEscopeCopy(ue, pdcchRxdataF_comp, rxdataF_comp, sizeof(struct complex16), antRx, symb_size, 0);
if (antRx > 1)
nr_pdcch_detection_mrc(arraySz, rxdataF_comp);
nr_pdcch_llr(symb_size, rxdataF_comp[0], llr[s]);
if (fp->nb_antennas_rx > 1) {
nr_pdcch_detection_mrc(rx_size, rxdataF_comp);
}
UEscopeCopy(ue, pdcchLlr, llr, sizeof(c16_t), 1, rel15->coreset.duration * symb_size, 0);
nr_pdcch_demapping_deinterleaving(n_rb,
llr,
pdcch_e_rx,
rel15->coreset.duration,
rel15->coreset.RegBundleSize,
rel15->coreset.InterleaverSize,
rel15->coreset.ShiftIndex,
rel15->number_of_candidates,
rel15->CCE,
rel15->L);
nr_pdcch_llr(llr_size_symbol, rxdataF_comp[0], llr);
}
bool is_start_symbol_in_ss(const fapi_nr_dl_config_dci_dl_pdu_rel15_t *ss, const int symbol)
{
return ((ss->coreset.StartSymbolBitmap >> (NR_SYMBOLS_PER_SLOT - 1 - symbol)) & 1);
}
int get_pdcch_mon_occasions_slot(const fapi_nr_dl_config_dci_dl_pdu_rel15_t *ss, uint8_t start_symb[NR_SYMBOLS_PER_SLOT])
{
int sum = 0;
for (int s = 0; s < NR_SYMBOLS_PER_SLOT; s++) {
if (is_start_symbol_in_ss(ss, s)) {
if (start_symb != NULL)
start_symb[sum] = s;
sum++;
}
}
return sum;
}
int get_max_pdcch_monOcc(const NR_UE_PDCCH_CONFIG *phy_pdcch_config)
{
int monOcc = 0;
for (int ss = 0; ss < phy_pdcch_config->nb_search_space; ss++) {
monOcc = max(monOcc, get_pdcch_mon_occasions_slot(&phy_pdcch_config->pdcch_config[ss], NULL));
}
return monOcc;
}
static void nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
c16_t *pdcch_e_rx,
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15,
fapi_nr_dci_indication_t *dci_ind);
void set_first_last_pdcch_symb(const NR_UE_PDCCH_CONFIG *phy_pdcch_config, int *first_symb, int *last_symb)
{
*first_symb = NR_SYMBOLS_PER_SLOT; // max first pdcch symbol
*last_symb = 0; // min last pdcch symbol
for (int ss = 0; ss < phy_pdcch_config->nb_search_space; ss++) {
for (int symb = 0; symb < NR_SYMBOLS_PER_SLOT; symb++) {
if (is_start_symbol_in_ss(&phy_pdcch_config->pdcch_config[ss], symb)) {
const int duration = phy_pdcch_config->pdcch_config[ss].coreset.duration;
*first_symb = min(*first_symb, symb);
*last_symb = max(*last_symb, symb + duration - 1);
}
}
}
}
/* Generates PDCCH LLRs from received symbol for each Search-Space */
void nr_pdcch_generate_llr(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
int symbol,
nr_phy_data_t *phy_data,
int llr_size_symbol,
int num_monitoring_occ,
int max_symb,
c16_t rxdataF[ue->frame_parms.nb_antennas_rx][ue->frame_parms.ofdm_symbol_size],
c16_t pdcch_llr[phy_data->phy_pdcch_config.nb_search_space][num_monitoring_occ][max_symb * llr_size_symbol])
{
const NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config;
// Loop over search spaces
for (int ss_idx = 0; ss_idx < phy_pdcch_config->nb_search_space; ss_idx++) {
uint8_t start_symb[NR_SYMBOLS_PER_SLOT] = {0};
const int num_monOcc = get_pdcch_mon_occasions_slot(&phy_pdcch_config->pdcch_config[ss_idx], start_symb);
// Loop over monitoring occations within the slot in this ss
for (int occ = 0; occ < num_monOcc; occ++) {
const int first_symb = start_symb[occ];
const int last_symb = first_symb + phy_pdcch_config->pdcch_config[ss_idx].coreset.duration;
// Decode PDCCH and generate LLR for each ss in this OFDM symbol
if ((symbol >= first_symb) && (symbol < last_symb)) {
const int rel_symb_monOcc = symbol - first_symb;
nr_rx_pdcch_symbol(ue,
proc,
symbol,
rel_symb_monOcc,
ss_idx,
phy_data,
llr_size_symbol,
rxdataF,
&pdcch_llr[ss_idx][occ][rel_symb_monOcc * llr_size_symbol]);
}
}
}
}
/* Decode DCI from LLRs for each Search-Space and send to MAC */
void nr_pdcch_dci_indication(const UE_nr_rxtx_proc_t *proc,
int llr_size,
int max_monOcc,
PHY_VARS_NR_UE *ue,
nr_phy_data_t *phy_data,
c16_t llr[phy_data->phy_pdcch_config.nb_search_space][max_monOcc][llr_size])
{
NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config;
nr_downlink_indication_t dl_indication;
fapi_nr_dci_indication_t dci_ind = {.SFN = proc->frame_rx, .slot = proc->nr_slot_rx};
for (int ss_idx = 0; ss_idx < phy_pdcch_config->nb_search_space; ss_idx++) {
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &phy_pdcch_config->pdcch_config[ss_idx];
uint8_t unused_start_symb[NR_SYMBOLS_PER_SLOT] = {0};
const int num_monitoring_occ = get_pdcch_mon_occasions_slot(rel15, unused_start_symb);
int n_rb;
int rb_offset;
get_coreset_rballoc(rel15->coreset.frequency_domain_resource, &n_rb, &rb_offset);
for (int m = 0; m < num_monitoring_occ; m++) {
/// PDCCH/DCI e-sequence (input to rate matching).
c16_t pdcch_e_rx[NR_MAX_PDCCH_SIZE];
nr_pdcch_demapping_deinterleaving(n_rb,
llr[ss_idx][m],
pdcch_e_rx,
rel15->coreset.duration,
rel15->coreset.RegBundleSize,
rel15->coreset.InterleaverSize,
rel15->coreset.ShiftIndex,
rel15->number_of_candidates,
rel15->CCE,
rel15->L);
nr_dci_decoding_procedure(ue, proc, pdcch_e_rx, rel15, &dci_ind);
}
}
for (int i = 0; i < dci_ind.number_of_dcis; i++) {
LOG_D(PHY,
"Frame.slot: %d.%d: DCI %i of %d total DCIs found --> rnti %x : format %d\n",
proc->frame_rx,
proc->nr_slot_rx,
i + 1,
dci_ind.number_of_dcis,
dci_ind.dci_list[i].rnti,
dci_ind.dci_list[i].dci_format);
}
/* Send to MAC */
nr_fill_dl_indication(&dl_indication, &dci_ind, NULL, proc, ue, phy_data);
ue->if_inst->dl_indication(&dl_indication);
phy_pdcch_config->nb_search_space = 0;
}
static void nr_pdcch_unscrambling(c16_t *e_rx,
@@ -425,14 +557,13 @@ static void nr_pdcch_unscrambling(c16_t *e_rx,
}
}
void nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
c16_t *pdcch_e_rx,
fapi_nr_dci_indication_t *dci_ind,
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15)
static void nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
c16_t *pdcch_e_rx,
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15,
fapi_nr_dci_indication_t *dci_ind)
{
int e_rx_cand_idx = 0;
*dci_ind = (fapi_nr_dci_indication_t){.SFN = proc->frame_rx, .slot = proc->nr_slot_rx};
// if DCI for SIB we don't break after finding 1st DCI with that RNTI
// there might be SIB1 and otherSIB in the same slot with the same length
bool is_SI = rel15->rnti == SI_RNTI;
@@ -540,6 +540,16 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
}
*log2_maxh = (log2_approx(avgs) / 2) + 1;
LOG_D(PHY, "[DLSCH] AbsSubframe %d.%d log2_maxh = %d (%d)\n", frame % 1024, nr_slot_rx, *log2_maxh, avgs);
#if T_TRACER
T(T_UE_PHY_PDSCH_ENERGY,
T_INT(gNB_id),
T_INT(frame % 1024),
T_INT(nr_slot_rx),
T_INT(avg[0]), // layer 0, antenna 0
T_INT(n_rx > 1 ? avg[1] : 0), // layer 0, antenna 1
T_INT(nl > 1 ? avg[n_rx] : 0), // layer 1, antenna 0
T_INT(nl > 1 && n_rx > 1 ? avg[n_rx + 1] : 0)); // layer 1, antenna 1
#endif
}
stop_meas_nr_ue_phy(ue, DLSCH_CHANNEL_LEVEL_STATS);
if (meas_enabled) {
@@ -552,9 +562,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
first_symbol_flag,
ue->phy_cpu_stats.cpu_time_stats[DLSCH_CHANNEL_LEVEL_STATS].p_time / (cpuf * 1000.0));
}
#if T_TRACER
T(T_UE_PHY_PDSCH_ENERGY, T_INT(gNB_id), T_INT(0), T_INT(frame % 1024), T_INT(nr_slot_rx));
#endif
//----------------------------------------------------------
//--------------------- channel compensation ---------------
@@ -746,13 +753,12 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
#if T_TRACER
T(T_UE_PHY_PDSCH_IQ,
T_INT(gNB_id),
T_INT(ue->Mod_id),
T_INT(frame % 1024),
T_INT(nr_slot_rx),
T_INT(nb_rb_pdsch),
T_INT(fp->N_RB_UL),
T_INT(fp->symbols_per_slot),
T_BUFFER(&rxdataF_comp[gNB_id][0], 2 * /* ulsch[UE_id]->harq_processes[harq_pid]->nb_rb */ fp->N_RB_UL * 12 * 2));
T_BUFFER(&rxdataF_comp[gNB_id][0], 2 * fp->N_RB_UL * 12 * fp->symbols_per_slot * 2));
#endif
if (ue->phy_sim_pdsch_rxdataF_comp)
@@ -69,6 +69,12 @@ typedef struct pdsch_scope_req_s {
void nr_ue_dlsch_init(NR_UE_DLSCH_t *dlsch_list, int num_dlsch, uint8_t max_ldpc_iterations);
void nr_conjch0_mult_ch1(c16_t *ch0, c16_t *ch1, c16_t *ch0conj_ch1, unsigned short nb_rb, unsigned char output_shift0);
void set_first_last_pdcch_symb(const NR_UE_PDCCH_CONFIG *phy_pdcch_config, int *first_symb, int *last_symb);
int get_pdcch_mon_occasions_slot(const fapi_nr_dl_config_dci_dl_pdu_rel15_t *ss, uint8_t start_symb[NR_SYMBOLS_PER_SLOT]);
int get_max_pdcch_monOcc(const NR_UE_PDCCH_CONFIG *phy_pdcch_config);
/** \brief This is the alternative top-level entry point for DLSCH decoding in UE.
It handles all the HARQ processes in only one call. The routine first
computes the segmentation information and then call LDPC decoder on the
@@ -180,14 +186,6 @@ void nr_dlsch_unscrambling(int16_t* llr,
uint32_t Nid,
uint32_t n_RNTI);
void nr_rx_pdcch(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
int32_t pdcch_est_size,
c16_t pdcch_dl_ch_estimates[][pdcch_est_size],
c16_t *pdcch_e_rx,
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
/*! \brief Performs detection of SSS to find cell ID and other framing parameters (FDD/TDD, normal/extended prefix)
@param phy_vars_ue Pointer to UE variables
@param tot_metric Pointer to variable containing maximum metric under framing hypothesis (to be compared to other hypotheses
@@ -279,12 +277,6 @@ void nr_sl_rf_card_config_freq(PHY_VARS_NR_UE *ue,
openair0_config_t *openair0_cfg,
int freq_offset);
void nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
c16_t *pdcch_e_rx,
fapi_nr_dci_indication_t *dci_ind,
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15);
/** \brief This function is the top-level entry point to PDSCH demodulation, after frequency-domain transformation and channel
estimation. It performs
- RB extraction (signal and channel estimates)
-8
View File
@@ -215,13 +215,6 @@ static inline int crcType(int nbSeg, int len)
return len > NR_MAX_PDSCH_TBS ? CRC24_A : CRC16;
}
typedef struct {
//! estimated rssi (dBm)
int rx_rssi_dBm;
/// Wideband CQI (sum of all RX antennas, in dB)
char wideband_cqi_tot;
} ulsch_measurements_gNB;
typedef struct {
uint32_t frame;
uint32_t slot;
@@ -243,7 +236,6 @@ typedef struct {
/// Flag to indicate that the UL configuration has been handled. Used to remove a stale ULSCH when frame wraps around
uint8_t handled;
delay_t delay;
ulsch_measurements_gNB ulsch_measurements;
} NR_gNB_ULSCH_t;
typedef struct {
+3 -3
View File
@@ -185,9 +185,6 @@ void nr_feptx_prec(RU_t *ru, int frame_tx, int slot_tx)
int txdataF_offset = slot_tx * fp->samples_per_slot_wCP;
start_meas(&ru->precoding_stats);
if (nr_slot_select(cfg,frame_tx,slot_tx) == NR_UPLINK_SLOT)
return;
if (gNB->common_vars.analog_bf) {
for (int i = 0; i < ru->num_beams_period; i++) {
memcpy((void*) &ru->common.beam_id[i][slot_tx * fp->symbols_per_slot],
@@ -196,6 +193,9 @@ void nr_feptx_prec(RU_t *ru, int frame_tx, int slot_tx)
}
}
if (nr_slot_select(cfg,frame_tx,slot_tx) == NR_UPLINK_SLOT)
return;
// If there is no digital beamforming we just need to copy the data to RU
if (ru->config.dbt_config.num_dig_beams == 0 || ru->gNB_list[0]->common_vars.analog_bf) {
for (int b = 0; b < ru->num_beams_period; b++) {
+16 -6
View File
@@ -92,7 +92,8 @@
*/
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data, c16_t **txp);
int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data);
int pbch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data);
void pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data);
void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data);
@@ -137,13 +138,22 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
void *typeSpecific,
uint8_t *b);
int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue,
void nr_pdcch_generate_llr(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
int32_t pdcch_est_size,
c16_t pdcch_dl_ch_estimates[][pdcch_est_size],
int symbol,
nr_phy_data_t *phy_data,
int n_ss,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
int llr_size_symbol,
int num_monitoring_occ,
int max_symb,
c16_t rxdataF[ue->frame_parms.nb_antennas_rx][ue->frame_parms.ofdm_symbol_size],
c16_t pdcch_llr[phy_data->phy_pdcch_config.nb_search_space][num_monitoring_occ][max_symb * llr_size_symbol]);
void nr_pdcch_dci_indication(const UE_nr_rxtx_proc_t *proc,
int llr_size,
int max_monOcc,
PHY_VARS_NR_UE *ue,
nr_phy_data_t *phy_data,
c16_t llr[phy_data->phy_pdcch_config.nb_search_space][max_monOcc][llr_size]);
void nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
+76 -87
View File
@@ -372,6 +372,9 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, n
AssertFatal(ue->CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN);
#if T_TRACER
T(T_UE_PHY_UL_TICK, T_INT(ue->Mod_id), T_INT(frame_tx % 1024), T_INT(slot_tx));
#endif
const int samplesF_per_slot = NR_SYMBOLS_PER_SLOT * ue->frame_parms.ofdm_symbol_size;
c16_t txdataF_buf[ue->frame_parms.nb_antennas_tx * samplesF_per_slot] __attribute__((aligned(32)));
@@ -440,7 +443,6 @@ static void nr_ue_measurement_procedures(uint16_t l,
if(nr_slot_rx == 0)
T(T_UE_PHY_MEAS,
T_INT(gNB_id),
T_INT(ue->Mod_id),
T_INT(proc->frame_rx % 1024),
T_INT(nr_slot_rx),
T_INT((int)(10 * log10(ue->measurements.rsrp[0]) - ue->rx_total_gain_dB)),
@@ -448,7 +450,8 @@ static void nr_ue_measurement_procedures(uint16_t l,
T_INT((int)(ue->measurements.rx_power_avg_dB[0] - ue->measurements.n0_power_avg_dB)),
T_INT((int)ue->measurements.rx_power_avg_dB[0]),
T_INT((int)ue->measurements.n0_power_avg_dB),
T_INT((int)ue->measurements.wideband_cqi_avg[0]));
T_INT((int)ue->measurements.wideband_cqi_avg[0]),
T_INT((int)ue->common_vars.freq_offset));
#endif
}
@@ -527,53 +530,6 @@ static int nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue,
return ret;
}
int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
int32_t pdcch_est_size,
c16_t pdcch_dl_ch_estimates[][pdcch_est_size],
nr_phy_data_t *phy_data,
int n_ss,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
{
int frame_rx = proc->frame_rx;
int nr_slot_rx = proc->nr_slot_rx;
NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config;
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &phy_pdcch_config->pdcch_config[n_ss];
start_meas_nr_ue_phy(ue, DLSCH_RX_PDCCH_STATS);
/// PDCCH/DCI e-sequence (input to rate matching).
int32_t pdcch_e_rx_size = NR_MAX_PDCCH_SIZE;
c16_t pdcch_e_rx[pdcch_e_rx_size];
nr_rx_pdcch(ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, pdcch_e_rx, rel15, rxdataF);
fapi_nr_dci_indication_t dci_ind;
nr_dci_decoding_procedure(ue, proc, pdcch_e_rx, &dci_ind, rel15);
for (int i = 0; i < dci_ind.number_of_dcis; i++) {
LOG_D(PHY,
"[UE %d] AbsSubFrame %d.%d: DCI %i of %d total DCIs found --> rnti %x : format %d\n",
ue->Mod_id,
frame_rx % 1024,
nr_slot_rx,
i + 1,
dci_ind.number_of_dcis,
dci_ind.dci_list[i].rnti,
dci_ind.dci_list[i].dci_format);
}
nr_downlink_indication_t dl_indication;
// fill dl_indication message
nr_fill_dl_indication(&dl_indication, &dci_ind, NULL, proc, ue, phy_data);
// send to mac
ue->if_inst->dl_indication(&dl_indication);
stop_meas_nr_ue_phy(ue, DLSCH_RX_PDCCH_STATS);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT);
return (dci_ind.number_of_dcis);
}
static freq_alloc_bitmap_t set_start_end_from_bitmap(int size, int alloc_size, const uint8_t bitmap[alloc_size])
{
freq_alloc_bitmap_t alloc = {
@@ -1027,18 +983,87 @@ static bool is_ssb_index_transmitted(const PHY_VARS_NR_UE *ue, const int index)
return ue->frame_parms.ssb_index == index;
}
int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data)
static int get_pdcch_max_rbs(NR_UE_PDCCH_CONFIG *phy_pdcch_config)
{
int nb_rb = 0;
int rb_offset = 0;
for (int i = 0; i < phy_pdcch_config->nb_search_space; i++) {
int tmp = 0;
get_coreset_rballoc(phy_pdcch_config->pdcch_config[i].coreset.frequency_domain_resource, &tmp, &rb_offset);
if (tmp > nb_rb)
nb_rb = tmp;
}
return nb_rb;
}
static int get_max_pdcch_symb(const NR_UE_PDCCH_CONFIG *phy_pdcch_config)
{
int max_pdcch_symb = 0;
for (int i = 0; i < phy_pdcch_config->nb_search_space; i++)
if (phy_pdcch_config->pdcch_config[i].coreset.duration > max_pdcch_symb)
max_pdcch_symb = phy_pdcch_config->pdcch_config[i].coreset.duration;
return max_pdcch_symb;
}
void pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data)
{
NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config;
if (phy_pdcch_config->nb_search_space == 0)
return;
TracyCZone(ctx, true);
/* process PDCCH */
LOG_D(PHY, " ------ --> PDCCH ChannelComp/LLR Frame.slot %d.%d ------ \n", proc->frame_rx % 1024, proc->nr_slot_rx);
start_meas_nr_ue_phy(ue, DLSCH_RX_PDCCH_STATS);
int num_monitoring_occ = get_max_pdcch_monOcc(phy_pdcch_config);
int max_nb_symb_pdcch = get_max_pdcch_symb(phy_pdcch_config);
int llr_size_symbol = get_pdcch_max_rbs(phy_pdcch_config) * 9;
c16_t pdcch_llr[phy_pdcch_config->nb_search_space][num_monitoring_occ][max_nb_symb_pdcch * llr_size_symbol];
int start_symb_pdcch, last_symb_pdcch;
set_first_last_pdcch_symb(phy_pdcch_config, &start_symb_pdcch, &last_symb_pdcch);
/* Temporarily loop over symbols in the slot, perform OFDM demod and process PDCCH.
When symbol based proc design is fully merged, this function will be called to process only one symbol
and OFDM demod will be removed from here. */
const uint32_t rxdataF_sz = ue->frame_parms.samples_per_slot_wCP;
__attribute__((aligned(32))) c16_t rxdataF[ue->frame_parms.nb_antennas_rx][rxdataF_sz];
for (int symbol = start_symb_pdcch; symbol <= last_symb_pdcch; symbol++) {
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
nr_slot_fep(ue, fp, proc->nr_slot_rx, symbol, rxdataF, link_type_dl, 0, ue->common_vars.rxdata);
__attribute__((aligned(32))) c16_t rxdataF_symb[fp->nb_antennas_rx][((fp->ofdm_symbol_size + 7) / 8) * 8];
for (int ant = 0; ant < fp->nb_antennas_rx; ant++)
memcpy(rxdataF_symb[ant], &rxdataF[ant][symbol * fp->ofdm_symbol_size], sizeof(c16_t) * fp->ofdm_symbol_size);
nr_pdcch_generate_llr(ue, proc, symbol, phy_data, llr_size_symbol, num_monitoring_occ, max_nb_symb_pdcch, rxdataF_symb, pdcch_llr);
if (symbol == last_symb_pdcch) {
nr_pdcch_dci_indication(proc, llr_size_symbol * max_nb_symb_pdcch, num_monitoring_occ, ue, phy_data, pdcch_llr);
UEscopeCopy(ue, pdcchLlr, pdcch_llr, sizeof(c16_t), 1, sizeof(pdcch_llr), 0);
}
}
stop_meas_nr_ue_phy(ue, DLSCH_RX_PDCCH_STATS);
TracyCZoneEnd(ctx);
if (ue->phy_sim_rxdataF)
memcpy(ue->phy_sim_rxdataF, rxdataF[0], sizeof(int32_t) * max_nb_symb_pdcch * ue->frame_parms.ofdm_symbol_size);
}
int pbch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data)
{
TracyCZone(ctx, true);
int frame_rx = proc->frame_rx;
int nr_slot_rx = proc->nr_slot_rx;
int gNB_id = proc->gNB_id;
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config;
int sampleShift = INT_MAX;
nr_ue_dlsch_init(phy_data->dlsch, NR_MAX_NB_LAYERS>4 ? 2:1, ue->max_ldpc_iterations);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
#if T_TRACER
T(T_UE_PHY_DL_TICK, T_INT(ue->Mod_id), T_INT(frame_rx % 1024), T_INT(nr_slot_rx));
#endif
LOG_D(PHY," ****** start RX-Chain for Frame.Slot %d.%d ****** \n",
frame_rx%1024, nr_slot_rx);
@@ -1163,43 +1188,7 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_
} // for i
} // for rsc_id
} // for gNB_id
LOG_D(PHY," ------ --> PDCCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_slot_rx);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_IN);
uint8_t nb_symb_pdcch = phy_pdcch_config->nb_search_space > 0 ? phy_pdcch_config->pdcch_config[0].coreset.duration : 0;
int first_symb_pdcch = phy_pdcch_config->nb_search_space > 0 ? phy_pdcch_config->pdcch_config[0].coreset.StartSymbolIndex : 0;
int last_symb_pdcch = first_symb_pdcch + nb_symb_pdcch;
for (int l = first_symb_pdcch; l < last_symb_pdcch; l++) {
nr_slot_fep(ue, fp, proc->nr_slot_rx, l, rxdataF, link_type_dl, 0, ue->common_vars.rxdata);
}
// Hold the channel estimates in frequency domain.
int32_t pdcch_est_size = ((((fp->symbols_per_slot*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH))+15)/16)*16);
__attribute__((aligned(16))) c16_t pdcch_dl_ch_estimates[4 * fp->nb_antennas_rx][pdcch_est_size];
uint8_t dci_cnt = 0;
for(int n_ss = 0; n_ss<phy_pdcch_config->nb_search_space; n_ss++) {
for (int l = first_symb_pdcch; l < last_symb_pdcch; l++) {
// note: this only works if RBs for PDCCH are contigous!
nr_pdcch_channel_estimation(ue,
proc,
l,
&phy_pdcch_config->pdcch_config[n_ss].coreset,
fp->first_carrier_offset,
phy_pdcch_config->pdcch_config[n_ss].BWPStart,
pdcch_est_size,
pdcch_dl_ch_estimates,
rxdataF);
}
dci_cnt = dci_cnt + nr_ue_pdcch_procedures(ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, phy_data, n_ss, rxdataF);
}
LOG_D(PHY, "[UE %d] Frame %d, nr_slot_rx %d: found %d DCIs\n", ue->Mod_id, frame_rx, nr_slot_rx, dci_cnt);
phy_pdcch_config->nb_search_space = 0;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_OUT);
TracyCZoneEnd(ctx);
if (ue->phy_sim_rxdataF)
memcpy(ue->phy_sim_rxdataF, rxdataF[0], sizeof(int32_t) * nb_symb_pdcch * ue->frame_parms.ofdm_symbol_size);
return sampleShift;
}
+2 -3
View File
@@ -1216,9 +1216,8 @@ int main(int argc, char **argv)
ue_dci_configuration(UE_mac, &dl_config, frame, slot);
nr_ue_scheduled_response(&scheduled_response);
pbch_pdcch_processing(UE,
&UE_proc,
&phy_data);
pbch_processing(UE, &UE_proc, &phy_data);
pdcch_processing(UE, &UE_proc, &phy_data);
pdsch_processing(UE,
&UE_proc,
&phy_data);
-11
View File
@@ -110,17 +110,6 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
{
}
int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
int32_t pdcch_est_size,
c16_t pdcch_dl_ch_estimates[][pdcch_est_size],
nr_phy_data_t *phy_data,
int n_ss,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
{
return 0;
}
configmodule_interface_t *uniqCfg = NULL;
int main(int argc, char **argv)
{
+8 -8
View File
@@ -1468,14 +1468,14 @@ int main(int argc, char *argv[])
}
int offset = (slot & 3) * gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size;
for (int aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) {
apply_nr_rotation_RX(&gNB->frame_parms,
gNB->common_vars.rxdataF[0][aa],
gNB->frame_parms.symbol_rotation[1],
slot,
gNB->frame_parms.N_RB_UL,
offset,
0,
gNB->frame_parms.Ncp == EXTENDED ? 12 : 14);
const unsigned int max_symb = (gNB->frame_parms.Ncp == EXTENDED) ? 12 : 14;
for (int sym = 0; sym < max_symb; sym++)
apply_nr_rotation_symbol_RX(&gNB->frame_parms,
gNB->common_vars.rxdataF[0][aa] + offset + sym * gNB->frame_parms.ofdm_symbol_size,
gNB->frame_parms.symbol_rotation[1],
gNB->frame_parms.N_RB_UL,
slot,
sym);
}
ul_proc_error = phy_procedures_gNB_uespec_RX(gNB, frame, slot, &UL_INFO);
+6
View File
@@ -421,6 +421,8 @@ typedef struct ngap_nas_first_req_s {
/* PLMN: Selected PLMN Identity (optional)
* User Location Information (mandatory) */
plmn_id_t plmn;
// NR Cell ID for NR CGI (mandatory)
uint32_t nr_cell_id;
// RRC Establishment Cause (mandatory)
ngap_rrc_establishment_cause_t establishment_cause;
// NAS-PDU (mandatory)
@@ -434,6 +436,10 @@ typedef struct ngap_uplink_nas_s {
uint32_t gNB_ue_ngap_id;
/* NAS pdu */
byte_array_t nas_pdu;
/* UserLocationInformation (mandatory) */
plmn_id_t plmn; // CGI and TAI
uint32_t nr_cell_id; // CGI
uint32_t tac; // TAI
} ngap_uplink_nas_t;
typedef struct target_cell_id_s {
@@ -38,13 +38,11 @@ ue_id_e2sm_t fill_e2sm_gnb_ue_id_data(const gNB_RRC_UE_t *rrc_ue_context, __attr
ue_id.gnb.amf_ue_ngap_id = auni < (1LL << 40) ? auni : 0;
// Mandatory
//GUAMI 6.2.3.17
ue_id.gnb.guami.plmn_id = (e2sm_plmn_t) {
.mcc = rrc_ue_context->ue_guami.mcc,
.mnc = rrc_ue_context->ue_guami.mnc,
.mnc_digit_len = rrc_ue_context->ue_guami.mnc_len
};
//GUAMI 6.2.3.17
ue_id.gnb.guami.plmn_id = (e2sm_plmn_t){.mcc = rrc_ue_context->ue_guami.plmn.mcc,
.mnc = rrc_ue_context->ue_guami.plmn.mnc,
.mnc_digit_len = rrc_ue_context->ue_guami.plmn.mnc_digit_length};
ue_id.gnb.guami.amf_region_id = rrc_ue_context->ue_guami.amf_region_id;
ue_id.gnb.guami.amf_set_id = rrc_ue_context->ue_guami.amf_set_id;
ue_id.gnb.guami.amf_ptr = rrc_ue_context->ue_guami.amf_pointer;
+6 -4
View File
@@ -707,7 +707,7 @@ void RCconfig_verify(configmodule_interface_t *cfg, ngran_node_t node_type)
verify_gnb_param_notset(gnbp, GNB_DISABLE_HARQ_IDX, GNB_CONFIG_STRING_DISABLE_HARQ);
verify_gnb_param_notset(gnbp, GNB_NUM_DL_HARQ_IDX, GNB_CONFIG_STRING_NUM_DL_HARQPROCESSES);
verify_gnb_param_notset(gnbp, GNB_NUM_UL_HARQ_IDX, GNB_CONFIG_STRING_NUM_UL_HARQPROCESSES);
verify_gnb_param_notset(gnbp, GNB_DO_SINR_IDX, GNB_CONFIG_STRING_DOSINR);
verify_gnb_param_notset(gnbp, GNB_CONFIG_REP_IDX, GNB_CONFIG_STRING_CONFIG_REP);
// check for some general sections
verify_section_notset(cfg, NULL, CONFIG_STRING_L1_LIST);
@@ -1432,7 +1432,8 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
config.do_CSIRS = *GNBParamList.paramarray[0][GNB_DO_CSIRS_IDX].iptr;
config.do_SRS = *GNBParamList.paramarray[0][GNB_DO_SRS_IDX].iptr;
config.max_num_rsrp = *GNBParamList.paramarray[0][GNB_LIMIT_RSRP_REPORT_IDX].iptr;
config.do_SINR = *GNBParamList.paramarray[0][GNB_DO_SINR_IDX].iptr;
const char *report_type_s = *GNBParamList.paramarray[0][GNB_CONFIG_REP_IDX].strptr;
config.report_type = config_get_processedint(cfg, &GNBParamList.paramarray[0][GNB_CONFIG_REP_IDX]);
config.force_256qam_off = *GNBParamList.paramarray[0][GNB_FORCE256QAMOFF_IDX].iptr;
config.force_UL256qam_off = *GNBParamList.paramarray[0][GNB_FORCEUL256QAMOFF_IDX].iptr;
config.use_deltaMCS = *GNBParamList.paramarray[0][GNB_USE_DELTA_MCS_IDX].iptr != 0;
@@ -1443,10 +1444,11 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
if (config.disable_harq)
LOG_W(GNB_APP, "\"disable_harq\" is a REL17 feature and is incompatible with REL15 and REL16 UEs!\n");
LOG_I(GNB_APP,
"CSI-RS %d, SRS %d, SINR:%d, 256 QAM %s, delta_MCS %s, maxMIMO_Layers %d, HARQ feedback %s, num DLHARQ:%d, num ULHARQ:%d\n",
"CSI-RS %d, SRS %d, report type %d (%s), 256 QAM %s, delta_MCS %s, maxMIMO_Layers %d, HARQ feedback %s, num DLHARQ:%d, num ULHARQ:%d\n",
config.do_CSIRS,
config.do_SRS,
config.do_SINR,
config.report_type,
report_type_s,
config.force_256qam_off ? "force off" : "may be on",
config.use_deltaMCS ? "on" : "off",
config.maxMIMO_layers,
+8 -5
View File
@@ -137,7 +137,7 @@ typedef enum {
#define GNB_CONFIG_STRING_UESS_AGG_LEVEL_LIST "uess_agg_levels"
#define GNB_CONFIG_STRING_CU_SIB_LIST "cu_sibs"
#define GNB_CONFIG_STRING_DU_SIB_LIST "du_sibs"
#define GNB_CONFIG_STRING_DOSINR "do_SINR"
#define GNB_CONFIG_STRING_CONFIG_REP "CSI_report_type"
#define GNB_CONFIG_STRING_1ST_ACTIVE_BWP "first_active_bwp"
#define GNB_CONFIG_STRING_LIMIT_RSRP_REPORT "max_num_RSRP_reported"
@@ -153,7 +153,7 @@ typedef enum {
#define GNB_CONFIG_HLP_UESS_AGG_LEVEL_LIST "List of aggregation levels with number of candidates per level. Element 0 - aggregation level 1"
#define GNB_CONFIG_HLP_CU_SIBS "List of CU generated SIBs to be transmitted"
#define GNB_CONFIG_HLP_DU_SIBS "List of DU generated SIBs to be transmitted"
#define GNB_CONFIG_HLP_DOSINR "Enable CSI feedback using SINR measurements on SSB"
#define GNB_CONFIG_HLP_CONFIG_REP "Define quantity for CSI report (options: ssb_rsrp, ssb_sinr and cri_rsrp)"
/*-----------------------------------------------------------------------------------------------------------------------------------------*/
@@ -201,7 +201,7 @@ typedef enum {
GNB_CONFIG_HLP_UESS_AGG_LEVEL_LIST, 0, .iptr=NULL, .defintarrayval=NULL, TYPE_INTARRAY, 0}, \
{GNB_CONFIG_STRING_CU_SIB_LIST, GNB_CONFIG_HLP_CU_SIBS, 0, .iptr=NULL, .defintarrayval=0, TYPE_INTARRAY, 0}, \
{GNB_CONFIG_STRING_DU_SIB_LIST, GNB_CONFIG_HLP_DU_SIBS, 0, .iptr=NULL, .defintarrayval=0, TYPE_INTARRAY, 0}, \
{GNB_CONFIG_STRING_DOSINR, GNB_CONFIG_HLP_DOSINR, 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \
{GNB_CONFIG_STRING_CONFIG_REP, GNB_CONFIG_HLP_CONFIG_REP, 0, .strptr=NULL, .defstrval="ssb_rsrp", TYPE_STRING, 0}, \
{GNB_CONFIG_STRING_1ST_ACTIVE_BWP, NULL, 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \
{GNB_CONFIG_STRING_LIMIT_RSRP_REPORT, NULL, 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \
}
@@ -246,7 +246,7 @@ typedef enum {
#define GNB_UESS_AGG_LEVEL_LIST_IDX 35
#define GNB_CU_SIBS_IDX 36
#define GNB_DU_SIBS_IDX 37
#define GNB_DO_SINR_IDX 38
#define GNB_CONFIG_REP_IDX 38
#define GNB_1ST_ACTIVE_BWP_IDX 39
#define GNB_LIMIT_RSRP_REPORT_IDX 40
@@ -293,7 +293,10 @@ typedef enum {
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s3a = { config_checkstr_assign_integer, \
{"ssb_rsrp", "ssb_sinr", "cri_rsrp"}, \
{SSB_RSRP, SSB_SINR, CRI_RSRP}, \
3 } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
}
+9 -3
View File
@@ -431,6 +431,14 @@ typedef struct {
float_t ssb_sinr_dB;
} NR_SSB_meas_t;
typedef struct {
int rsrp_dBm;
uint8_t ri;
uint16_t i1;
uint8_t i2;
uint8_t cqi;
} NR_CSIRS_meas_t;
typedef enum ta_type {
no_ta = 0,
adjustment_ta,
@@ -601,9 +609,6 @@ typedef struct NR_UE_MAC_INST_s {
nr_csi_report_t csi_report_template[MAX_CSI_REPORTCONFIG];
/// measurements from SS or CSI-RS
fapi_nr_l1_measurements_t l1_measurements;
//// FAPI-like interface message
fapi_nr_ul_config_request_t *ul_config_request;
fapi_nr_dl_config_request_t *dl_config_request;
@@ -633,6 +638,7 @@ typedef struct NR_UE_MAC_INST_s {
int ssb_start_subcarrier;
NR_SSB_meas_t ssb_measurements[MAX_NB_SSB];
NR_CSIRS_meas_t csirs_measurements;
dci_pdu_rel15_t def_dci_pdu_rel15[NR_MAX_SLOTS_PER_FRAME][8];
+1 -1
View File
@@ -307,7 +307,7 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac, NR_UE_MAC_reset_cause_t ca
release_ul_BWP(mac, i);
memset(&mac->ssb_measurements, 0, sizeof(mac->ssb_measurements));
memset(&mac->l1_measurements, 0, sizeof(mac->l1_measurements));
memset(&mac->csirs_measurements, 0, sizeof(mac->csirs_measurements));
memset(&mac->ul_time_alignment, 0, sizeof(mac->ul_time_alignment));
for (int i = mac->TAG_list.count; i > 0 ; i--)
asn_sequence_del(&mac->TAG_list, i - 1, 1);
@@ -307,12 +307,7 @@ static void config_dci_pdu(NR_UE_MAC_INST_t *mac,
break;
}
for (int i = 0; i < sps; i++) {
if ((monitoringSymbolsWithinSlot >> (sps - 1 - i)) & 1) {
rel15->coreset.StartSymbolIndex = i;
break;
}
}
rel15->coreset.StartSymbolBitmap = monitoringSymbolsWithinSlot;
uint32_t Y = 0;
if (ss->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific)
Y = get_Y(ss, slot, rel15->rnti);
+40 -44
View File
@@ -1508,13 +1508,18 @@ nr_dci_format_t nr_ue_process_dci_indication_pdu(NR_UE_MAC_INST_t *mac, frame_t
void nr_ue_process_l1_measurements(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, fapi_nr_l1_measurements_t *l1_measurements)
{
LOG_D(NR_MAC, "(%d.%d) Received CSI-RS measurements\n", frame, slot);
memcpy(&mac->l1_measurements, l1_measurements, sizeof(*l1_measurements));
LOG_D(NR_MAC, "(%d.%d) Received measurements from L1\n", frame, slot);
bool csi_meas = l1_measurements->meas_type == NFAPI_NR_CSI_MEAS;
if (!csi_meas && !l1_measurements->is_neighboring_cell) {
int ssb_index = l1_measurements->ssb_index;
mac->ssb_measurements[ssb_index].ssb_rsrp_dBm = l1_measurements->rsrp_dBm;
mac->ssb_measurements[ssb_index].ssb_sinr_dB = l1_measurements->sinr_dB;
} else if (csi_meas) {
mac->csirs_measurements.rsrp_dBm = l1_measurements->rsrp_dBm;
mac->csirs_measurements.i1 = l1_measurements->i1;
mac->csirs_measurements.i2 = l1_measurements->i2;
mac->csirs_measurements.cqi = l1_measurements->cqi;
mac->csirs_measurements.ri = l1_measurements->rank_indicator;
}
nr_mac_rrc_meas_ind_ue(mac->ue_id,
l1_measurements->gNB_index,
@@ -2790,13 +2795,13 @@ static csi_payload_t get_ssb_sinr_payload(NR_UE_MAC_INST_t *mac,
} else
nb_meas = 2;
struct NR_CSI_SSB_ResourceSet__csi_SSB_ResourceList SSB_resource;
struct NR_CSI_SSB_ResourceSet__csi_SSB_ResourceList *SSB_resource = NULL;
for (int csi_ssb_idx = 0; csi_ssb_idx < csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.count; csi_ssb_idx++) {
if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceSetId
== *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])) {
SSB_resource = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceList;
SSB_resource = &csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceList;
/// only one SSB resource set from spec 38.331 IE CSI-ResourceConfig
nb_ssb = SSB_resource.list.count;
nb_ssb = SSB_resource->list.count;
break;
}
}
@@ -2811,7 +2816,7 @@ static csi_payload_t get_ssb_sinr_payload(NR_UE_MAC_INST_t *mac,
for (int measured_ssb_idx = 0; measured_ssb_idx < MAX_NB_SSB; measured_ssb_idx++) {
// searching for the SSB index in the SSB resource table
for (int ssb_resource = 0; ssb_resource < nb_ssb; ssb_resource++) {
if (*SSB_resource.list.array[ssb_resource] == measured_ssb_idx) {
if (*SSB_resource->list.array[ssb_resource] == measured_ssb_idx) {
sorted_sinr_measurements[sorted_idx].ssb_index = ssb_resource;
sorted_sinr_measurements[sorted_idx].ssb_rsrp_dBm = mac->ssb_measurements[measured_ssb_idx].ssb_rsrp_dBm;
sorted_sinr_measurements[sorted_idx].ssb_sinr_dB = mac->ssb_measurements[measured_ssb_idx].ssb_sinr_dB;
@@ -2822,25 +2827,20 @@ static csi_payload_t get_ssb_sinr_payload(NR_UE_MAC_INST_t *mac,
}
qsort(sorted_sinr_measurements, nb_ssb, sizeof(NR_RSRP_meas_t), compare_ssb_sinr);
uint8_t ssbi;
// TS38.212 v16.5.0: Table 6.3.1.1.2-8A
if (ssbri_bits > 0) {
ssbi = sorted_sinr_measurements[0].ssb_index;
temp_payload = reverse_bits(ssbi, ssbri_bits);
bits += ssbri_bits;
for (int i = 0; i < nb_meas; i++) {
if (ssbri_bits > 0) {
uint8_t ssbi = sorted_sinr_measurements[i].ssb_index;
temp_payload |= (reverse_bits(ssbi, ssbri_bits) << bits);
bits += ssbri_bits;
}
}
uint8_t sinr_idx = get_sinr_index(sorted_sinr_measurements[0].ssb_sinr_dB);
temp_payload |= (reverse_bits(sinr_idx, 7) << bits);
bits += 7; // 7 bits for highest SINR
// from the second SSB, differential report
for (int i = 1; i < nb_meas; i++) {
ssbi = sorted_sinr_measurements[i].ssb_index;
temp_payload |= (reverse_bits(ssbi, ssbri_bits) << bits);
bits += ssbri_bits;
sinr_idx = get_sinr_diff_index(sorted_sinr_measurements[0].ssb_sinr_dB, sorted_sinr_measurements[i].ssb_sinr_dB);
temp_payload |= (reverse_bits(sinr_idx, 4) << bits);
bits += 4; // 4 bits for differential SINR
@@ -2931,13 +2931,13 @@ static csi_payload_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac,
} else
nb_meas = 2;
struct NR_CSI_SSB_ResourceSet__csi_SSB_ResourceList SSB_resource;
struct NR_CSI_SSB_ResourceSet__csi_SSB_ResourceList *SSB_resource = NULL;
for (int csi_ssb_idx = 0; csi_ssb_idx < csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.count; csi_ssb_idx++) {
if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceSetId ==
*(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])){
SSB_resource = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceList;
SSB_resource = &csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceList;
///only one SSB resource set from spec 38.331 IE CSI-ResourceConfig
nb_ssb = SSB_resource.list.count;
nb_ssb = SSB_resource->list.count;
break;
}
}
@@ -2952,7 +2952,7 @@ static csi_payload_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac,
for (int measured_ssb_idx = 0; measured_ssb_idx < MAX_NB_SSB; measured_ssb_idx++) {
// searching for the SSB index in the SSB resource table
for (int ssb_resource = 0; ssb_resource < nb_ssb; ssb_resource++) {
if (*SSB_resource.list.array[ssb_resource] == measured_ssb_idx) {
if (*SSB_resource->list.array[ssb_resource] == measured_ssb_idx) {
sorted_rsrp_measurements[sorted_idx].ssb_index = ssb_resource;
sorted_rsrp_measurements[sorted_idx].ssb_rsrp_dBm = mac->ssb_measurements[measured_ssb_idx].ssb_rsrp_dBm;
sorted_rsrp_measurements[sorted_idx].ssb_sinr_dB = mac->ssb_measurements[measured_ssb_idx].ssb_sinr_dB;
@@ -2963,12 +2963,12 @@ static csi_payload_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac,
}
qsort(sorted_rsrp_measurements, nb_ssb, sizeof(NR_RSRP_meas_t), compare_ssb_rsrp);
uint32_t ssbi;
if (ssbri_bits > 0) {
ssbi = sorted_rsrp_measurements[0].ssb_index;
temp_payload = reverse_bits(ssbi, ssbri_bits);
bits += ssbri_bits;
for (int i = 0; i < nb_meas; i++) {
if (ssbri_bits > 0) {
uint32_t ssbi = sorted_rsrp_measurements[i].ssb_index;
temp_payload |= (reverse_bits(ssbi, ssbri_bits) << bits);
bits += ssbri_bits;
}
}
uint8_t rsrp_idx = get_rsrp_index(sorted_rsrp_measurements[0].ssb_rsrp_dBm);
@@ -2977,15 +2977,11 @@ static csi_payload_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac,
// from the second SSB, differential report
for (int i = 1; i < nb_meas; i++) {
ssbi = sorted_rsrp_measurements[i].ssb_index;
temp_payload |= (reverse_bits(ssbi, ssbri_bits) << bits);
bits += ssbri_bits;
rsrp_idx = get_rsrp_diff_index(sorted_rsrp_measurements[0].ssb_rsrp_dBm,sorted_rsrp_measurements[i].ssb_rsrp_dBm);
temp_payload |= (reverse_bits(rsrp_idx, 4) << bits);
bits += 4; // 4 bits for subsequent RSRP
}
break; // resorce found
break; // resource found
}
}
int max_bits = sizeof(((csi_payload_t *)0)->part1_payload) * 8;
@@ -3026,28 +3022,28 @@ static csi_payload_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac,
AssertFatal(csi_report, "Couldn't find CSI report with ID %ld\n", csi_reportconfig->reportConfigId);
int cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen;
int ri_bitlen = csi_report->csi_meas_bitlen.ri_bitlen;
int pmi_x1_bitlen = csi_report->csi_meas_bitlen.pmi_x1_bitlen[mac->l1_measurements.rank_indicator];
int pmi_x2_bitlen = csi_report->csi_meas_bitlen.pmi_x2_bitlen[mac->l1_measurements.rank_indicator];
int cqi_bitlen = csi_report->csi_meas_bitlen.cqi_bitlen[mac->l1_measurements.rank_indicator];
int pmi_x1_bitlen = csi_report->csi_meas_bitlen.pmi_x1_bitlen[mac->csirs_measurements.ri];
int pmi_x2_bitlen = csi_report->csi_meas_bitlen.pmi_x2_bitlen[mac->csirs_measurements.ri];
int cqi_bitlen = csi_report->csi_meas_bitlen.cqi_bitlen[mac->csirs_measurements.ri];
int padding_bitlen = 0;
// TODO: Improvements will be needed to cri_bitlen>0 and pmi_x1_bitlen>0
if (mapping_type == ON_PUSCH) {
p1_bits = cri_bitlen + ri_bitlen + cqi_bitlen;
p2_bits = pmi_x1_bitlen + pmi_x2_bitlen;
temp_payload_1 = (0/*mac->csi_measurements.cri*/ << (cqi_bitlen + ri_bitlen)) |
(mac->l1_measurements.rank_indicator << cqi_bitlen) |
(mac->l1_measurements.cqi);
temp_payload_2 = (mac->l1_measurements.i1 << pmi_x2_bitlen) |
mac->l1_measurements.i2;
(mac->csirs_measurements.ri << cqi_bitlen) |
(mac->csirs_measurements.cqi);
temp_payload_2 = (mac->csirs_measurements.i1 << pmi_x2_bitlen) |
mac->csirs_measurements.i2;
}
else {
p1_bits = nr_get_csi_bitlen(csi_report);
padding_bitlen = p1_bits - (cri_bitlen + ri_bitlen + pmi_x1_bitlen + pmi_x2_bitlen + cqi_bitlen);
temp_payload_1 = (0/*mac->csi_measurements.cri*/ << (cqi_bitlen + pmi_x2_bitlen + pmi_x1_bitlen + padding_bitlen + ri_bitlen)) |
(mac->l1_measurements.rank_indicator << (cqi_bitlen + pmi_x2_bitlen + pmi_x1_bitlen + padding_bitlen)) |
(mac->l1_measurements.i1 << (cqi_bitlen + pmi_x2_bitlen)) |
(mac->l1_measurements.i2 << (cqi_bitlen)) |
(mac->l1_measurements.cqi);
(mac->csirs_measurements.ri << (cqi_bitlen + pmi_x2_bitlen + pmi_x1_bitlen + padding_bitlen)) |
(mac->csirs_measurements.i1 << (cqi_bitlen + pmi_x2_bitlen)) |
(mac->csirs_measurements.i2 << (cqi_bitlen)) |
(mac->csirs_measurements.cqi);
}
temp_payload_1 = reverse_bits(temp_payload_1, p1_bits);
@@ -3106,7 +3102,7 @@ static csi_payload_t get_csirs_RSRP_payload(NR_UE_MAC_INST_t *mac,
}
// TODO: Improvements will be needed to cri_ssbri_bitlen>0
temp_payload = get_rsrp_index(mac->l1_measurements.rsrp_dBm);
temp_payload = get_rsrp_index(mac->csirs_measurements.rsrp_dBm);
temp_payload = reverse_bits(temp_payload, n_bits);
LOG_D(NR_MAC, "cri_ssbri_bitlen = %d\n", cri_ssbri_bitlen);
@@ -589,11 +589,13 @@ static void evaluate_rsrp_report(gNB_MAC_INST *nrmac,
rsrp_report->nr_reports = csi_report->CSI_report_bitlen.nb_ssbri_cri;
int bitlen = csi_report->CSI_report_bitlen.cri_ssbri_bitlen;
uint8_t curr_payload = pickandreverse_bits(payload, bitlen, *cumul_bits);
rsrp_report->resource_id[0] = *(index_list[bitlen > 0 ? ((curr_payload) & ~(~1U << (bitlen - 1))) : bitlen]);
*cumul_bits += bitlen;
for (int i = 0; i < rsrp_report->nr_reports; i++) {
uint8_t idx_payload = pickandreverse_bits(payload, bitlen, *cumul_bits);
rsrp_report->resource_id[i] = *(index_list[bitlen > 0 ? ((idx_payload) & ~(~1U << (bitlen - 1))) : bitlen]);
*cumul_bits += bitlen;
}
curr_payload = pickandreverse_bits(payload, 7, *cumul_bits);
uint8_t curr_payload = pickandreverse_bits(payload, 7, *cumul_bits);
int rsrp = curr_payload & 0x7f;
*cumul_bits += 7;
csi_report->nb_of_csi_ssb_report++;
@@ -605,10 +607,6 @@ static void evaluate_rsrp_report(gNB_MAC_INST *nrmac,
}
for (int i = 1; i < rsrp_report->nr_reports; i++) {
curr_payload = pickandreverse_bits(payload, bitlen, *cumul_bits);
rsrp_report->resource_id[i] = *(index_list[bitlen > 0 ? ((curr_payload) & ~(~1U << (bitlen - 1))) : bitlen]);
*cumul_bits += bitlen;
curr_payload = pickandreverse_bits(payload, 4, *cumul_bits);
csi_report->nb_of_csi_ssb_report++;
rsrp_report->RSRP[i] = get_diff_rsrp(curr_payload & 0x0f, rsrp_report->RSRP[0]);
@@ -967,6 +967,8 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc)
ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup);
UE->CellGroup = oldUE->CellGroup;
oldUE->CellGroup = NULL;
UE->capability = oldUE->capability;
oldUE->capability = NULL;
UE->mac_stats = oldUE->mac_stats;
UE->measgap_config = oldUE->measgap_config;
/* 38.331 5.3.7.2 says that the UE releases the spCellConfig, so we drop it
+7 -1
View File
@@ -179,6 +179,12 @@ typedef struct {
int location_and_bw;
} nr_bwp_config_t;
typedef enum {
SSB_RSRP,
CRI_RSRP,
SSB_SINR,
} nr_config_report_type_t;
typedef struct nr_mac_config_t {
int sib1_tda;
nr_pdsch_AntennaPorts_t pdsch_AntennaPorts;
@@ -207,7 +213,7 @@ typedef struct nr_mac_config_t {
int num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS];
nr_redcap_config_t *redcap;
nr_ptrs_config_t *ptrs;
bool do_SINR;
nr_config_report_type_t report_type;
} nr_mac_config_t;
typedef struct NR_preamble_ue {
+17 -11
View File
@@ -2144,7 +2144,7 @@ static void config_rsrp_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
for (int csi_list = 0; csi_list < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count; csi_list++) {
NR_CSI_ResourceConfig_t *csires = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_list];
if (csires->csi_RS_ResourceSetList.present == NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB) {
if (configuration->do_CSIRS && num_antenna_ports < 4) {
if (configuration->report_type == CRI_RSRP && configuration->do_CSIRS && num_antenna_ports < 4) {
if (csires->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList)
resource_id = csires->csi_ResourceConfigId;
} else {
@@ -2166,20 +2166,19 @@ static void config_rsrp_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
csirep->reportConfigType.choice.periodic = calloc(1, sizeof(*csirep->reportConfigType.choice.periodic));
set_csi_meas_periodicity(servingcellconfigcommon, csirep, uid, curr_bwp, true);
asn1cSeqAdd(&csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list, pucchcsires);
if (configuration->do_CSIRS && num_antenna_ports < 4) {
if (configuration->report_type == SSB_SINR) {
csirep->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_none;
csirep->reportQuantity.choice.none = (NULL_t)0;
csirep->ext2 = calloc(1, sizeof(*csirep->ext2));
csirep->ext2->reportQuantity_r16 = calloc(1, sizeof(*csirep->ext2->reportQuantity_r16));
csirep->ext2->reportQuantity_r16->present = NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_ssb_Index_SINR_r16;
csirep->ext2->reportQuantity_r16->choice.ssb_Index_SINR_r16 = (NULL_t)0;
} else if (configuration->report_type == CRI_RSRP && configuration->do_CSIRS && num_antenna_ports < 4) {
csirep->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP;
csirep->reportQuantity.choice.cri_RSRP = (NULL_t)0;
} else {
csirep->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP;
csirep->reportQuantity.choice.ssb_Index_RSRP = (NULL_t)0;
if (configuration->do_SINR) {
csirep->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_none;
csirep->reportQuantity.choice.none = (NULL_t)0;
csirep->ext2 = calloc(1, sizeof(*csirep->ext2));
csirep->ext2->reportQuantity_r16 = calloc(1, sizeof(*csirep->ext2->reportQuantity_r16));
csirep->ext2->reportQuantity_r16->present = NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_ssb_Index_SINR_r16;
csirep->ext2->reportQuantity_r16->choice.ssb_Index_SINR_r16 = (NULL_t)0;
}
}
csirep->groupBasedBeamReporting.present = NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled;
csirep->groupBasedBeamReporting.choice.disabled = calloc(1, sizeof(*csirep->groupBasedBeamReporting.choice.disabled));
@@ -3867,8 +3866,15 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
NR_CSI_MeasConfig_t *csi_MeasConfig = spCellConfigDedicated->csi_MeasConfig->choice.setup;
for (int report = 0; report < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; report++) {
NR_CSI_ReportConfig_t *csirep = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[report];
if(csirep->codebookConfig)
if (csirep->codebookConfig)
config_csi_codebook(&configuration->pdsch_AntennaPorts, *pdsch_servingcellconfig->ext1->maxMIMO_Layers, csirep->codebookConfig);
if (csirep->groupBasedBeamReporting.present == NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled
&& csirep->groupBasedBeamReporting.choice.disabled
&& csirep->groupBasedBeamReporting.choice.disabled->nrofReportedRS)
*csirep->groupBasedBeamReporting.choice.disabled->nrofReportedRS = config_nrofReportedRS(uecap,
get_ssb_bitmap(scc),
scc,
configuration->max_num_rsrp);
}
NR_UplinkConfig_t *uplinkConfig = spCellConfigDedicated->uplinkConfig;
+21 -4
View File
@@ -141,6 +141,24 @@ static instance_t get_f1_gtp_instance(void)
return inst->gtpInst;
}
/** @brief Add bearer in PDCP/SDAP for 5GC association (SA) */
static void e1_add_bearers(const int ue_id, const NR_DRB_ToAddModList_t *addMod, const nr_pdcp_entity_security_keys_and_algos_t *sp)
{
for (int i = 0; i < addMod->list.count; i++) {
NR_DRB_ToAddMod_t *drb = addMod->list.array[i];
DevAssert(drb->cnAssociation);
DevAssert(drb->cnAssociation->present != NR_DRB_ToAddMod__cnAssociation_PR_NOTHING);
DevAssert(drb->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config);
DevAssert(drb->cnAssociation->choice.sdap_Config);
// get SDAP config
sdap_config_t sdap = nr_sdap_get_config(GNB_FLAG_YES, drb->cnAssociation->choice.sdap_Config, drb->drb_Identity);
// add SDAP entity
nr_sdap_addmod_entity(GNB_FLAG_YES, ue_id, sdap);
// add PDCP entity
nr_pdcp_add_drb(GNB_FLAG_YES, ue_id, drb->pdcp_Config, &sdap, sp);
}
}
void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req)
{
bool need_ue_id_mgmt = e1_used();
@@ -208,11 +226,10 @@ void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req)
security_parameters.integrity_algorithm = req->secInfo.integrityProtectionAlgorithm;
memcpy(security_parameters.ciphering_key, req->secInfo.encryptionKey, NR_K_KEY_SIZE);
memcpy(security_parameters.integrity_key, req->secInfo.integrityProtectionKey, NR_K_KEY_SIZE);
nr_pdcp_add_drbs(true, // set this to notify PDCP that his not UE
cu_up_ue_id,
&DRB_configList,
&security_parameters);
e1_add_bearers(cu_up_ue_id, &DRB_configList, &security_parameters);
ASN_STRUCT_RESET(asn_DEF_NR_DRB_ToAddModList, &DRB_configList.list);
if (f1inst >= 0) { /* we have F1(-U) */
teid_t dummy_teid = 0xffff; // we will update later with answer from DU
in_addr_t dummy_address = {0}; // IPv4, updated later with answer from DU
+37 -92
View File
@@ -575,75 +575,32 @@ void add_srb(int is_gnb,
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
}
void add_drb(int is_gnb,
ue_id_t UEid,
struct NR_DRB_ToAddMod *s,
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters)
void nr_pdcp_add_drb(int is_gnb,
const ue_id_t UEid,
const NR_PDCP_Config_t *pdcp,
const sdap_config_t *sdap,
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters)
{
nr_pdcp_entity_t *pdcp_drb;
nr_pdcp_ue_t *ue;
int drb_id = s->drb_Identity;
if (!s->pdcp_Config || !s->pdcp_Config->drb) {
LOG_E(PDCP, "DRB field mandatory present at setup. DRB %d not configured.\n", drb_id);
if (!pdcp->drb) {
LOG_E(PDCP, "Missing PDCP config. DRB %d not configured.\n", sdap->drb_id);
return;
}
struct NR_PDCP_Config__drb *drb = s->pdcp_Config->drb;
struct NR_PDCP_Config__drb *drb = pdcp->drb;
int sn_size_ul = decode_sn_size_ul(*drb->pdcp_SN_SizeUL);
int sn_size_dl = decode_sn_size_dl(*drb->pdcp_SN_SizeDL);
int discard_timer = decode_discard_timer(*drb->discardTimer);
int has_integrity;
int has_ciphering;
/* if pdcp_Config->t_Reordering is not present, it means infinity (-1) */
int t_reordering = -1;
if (s->pdcp_Config->t_Reordering != NULL) {
t_reordering = decode_t_reordering(*s->pdcp_Config->t_Reordering);
if (pdcp->t_Reordering != NULL) {
t_reordering = decode_t_reordering(*pdcp->t_Reordering);
}
if (drb->integrityProtection != NULL)
has_integrity = 1;
else
has_integrity = 0;
if (s->pdcp_Config->ext1 != NULL && s->pdcp_Config->ext1->cipheringDisabled != NULL)
has_ciphering = 0;
else
has_ciphering = 1;
if ((!s->cnAssociation) || s->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_NOTHING) {
LOG_E(PDCP, "fatal, cnAssociation is missing or present is NR_DRB_ToAddMod__cnAssociation_PR_NOTHING\n");
exit(-1);
}
int pdusession_id;
bool has_sdap_rx = false;
bool has_sdap_tx = false;
bool is_sdap_DefaultDRB = false;
NR_QFI_t *mappedQFIs2Add = NULL;
uint8_t mappedQFIs2AddCount=0;
if (s->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity)
pdusession_id = s->cnAssociation->choice.eps_BearerIdentity;
else {
if (!s->cnAssociation->choice.sdap_Config) {
LOG_E(PDCP,"fatal, sdap_Config is null");
exit(-1);
}
pdusession_id = s->cnAssociation->choice.sdap_Config->pdu_Session;
has_sdap_rx = is_sdap_rx(is_gnb, s->cnAssociation->choice.sdap_Config);
has_sdap_tx = is_sdap_tx(is_gnb, s->cnAssociation->choice.sdap_Config);
is_sdap_DefaultDRB = s->cnAssociation->choice.sdap_Config->defaultDRB == true ? 1 : 0;
mappedQFIs2Add = (NR_QFI_t*)s->cnAssociation->choice.sdap_Config->mappedQoS_FlowsToAdd->list.array[0];
mappedQFIs2AddCount = s->cnAssociation->choice.sdap_Config->mappedQoS_FlowsToAdd->list.count;
LOG_D(SDAP, "Captured mappedQoS_FlowsToAdd from RRC: %ld \n", *mappedQFIs2Add);
}
/* TODO(?): accept different UL and DL SN sizes? */
if (sn_size_ul != sn_size_dl) {
LOG_E(PDCP, "fatal, bad SN sizes, must be same. ul=%d, dl=%d\n", sn_size_ul, sn_size_dl);
exit(1);
}
int has_integrity = (drb->integrityProtection != NULL) ? 1 : 0;
int has_ciphering = (pdcp->ext1 != NULL && pdcp->ext1->cipheringDisabled != NULL) ? 0 : 1;
/* get actual ciphering and integrity algorithm based on pdcp_Config */
nr_pdcp_entity_security_keys_and_algos_t actual_security_parameters = *security_parameters;
@@ -652,29 +609,33 @@ void add_drb(int is_gnb,
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, UEid);
if (nr_pdcp_get_rb(ue, drb_id, false) != NULL) {
LOG_W(PDCP, "warning DRB %d already exist for UE ID %ld, do nothing\n", drb_id, UEid);
if (nr_pdcp_get_rb(ue, sdap->drb_id, false) != NULL) {
LOG_W(PDCP, "warning DRB %d already exist for UE ID %ld, do nothing\n", sdap->drb_id, UEid);
} else {
pdcp_drb = new_nr_pdcp_entity(NR_PDCP_DRB_AM, is_gnb, drb_id, pdusession_id,
has_sdap_rx, has_sdap_tx, deliver_sdu_drb, ue,
is_gnb ?
deliver_pdu_drb_gnb : deliver_pdu_drb_ue,
ue,
sn_size_dl, t_reordering, discard_timer,
&actual_security_parameters);
nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb);
// code assumption: same SN size for both DL and UL
if (sn_size_ul != sn_size_dl) {
LOG_E(PDCP, "fatal, bad SN sizes, must be same. ul=%d, dl=%d\n", sn_size_ul, sn_size_dl);
exit(1);
}
LOG_I(PDCP, "added drb %d to UE ID %ld\n", drb_id, UEid);
/* add new SDAP entity for the PDU session the DRB belongs to */
new_nr_sdap_entity(is_gnb,
has_sdap_rx,
has_sdap_tx,
UEid,
pdusession_id,
is_sdap_DefaultDRB,
drb_id,
mappedQFIs2Add,
mappedQFIs2AddCount);
// add PDCP entity
nr_pdcp_entity_t *pdcp_drb = new_nr_pdcp_entity(NR_PDCP_DRB_AM,
is_gnb,
sdap->drb_id,
sdap->pdusession_id,
(sdap->role & (SDAP_UL_RX | SDAP_DL_RX)) != 0,
(sdap->role & (SDAP_UL_TX | SDAP_DL_TX)) != 0,
deliver_sdu_drb,
ue,
is_gnb ? deliver_pdu_drb_gnb : deliver_pdu_drb_ue,
ue,
sn_size_dl,
t_reordering,
discard_timer,
&actual_security_parameters);
nr_pdcp_ue_add_drb_pdcp_entity(ue, sdap->drb_id, pdcp_drb);
LOG_I(PDCP, "Added DRB %d to UE ID %ld\n", sdap->drb_id, UEid);
}
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
}
@@ -692,22 +653,6 @@ void nr_pdcp_add_srbs(eNB_flag_t enb_flag,
LOG_W(PDCP, "nr_pdcp_add_srbs() with void list\n");
}
void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
ue_id_t UEid,
NR_DRB_ToAddModList_t *const drb2add_list,
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters)
{
if (drb2add_list != NULL) {
for (int i = 0; i < drb2add_list->list.count; i++) {
add_drb(enb_flag,
UEid,
drb2add_list->list.array[i],
security_parameters);
}
} else
LOG_W(PDCP, "nr_pdcp_add_drbs() with void list\n");
}
uint64_t get_pdcp_optmask(void)
{
return pdcp_optmask;
+6 -9
View File
@@ -33,6 +33,7 @@
#include "nr_pdcp_ue_manager.h"
struct NR_DRB_ToAddMod;
struct NR_SRB_ToAddMod;
struct sdap_configuration_s;
void nr_pdcp_layer_init(void);
@@ -42,20 +43,16 @@ bool nr_pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP,
const sdu_size_t sdu_buffer_size,
uint8_t *const sdu_buffer);
void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
ue_id_t UEid,
NR_DRB_ToAddModList_t *const drb2add_list,
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters);
void nr_pdcp_add_srbs(eNB_flag_t enb_flag,
ue_id_t UEid,
NR_SRB_ToAddModList_t *const srb2add_list,
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters);
void add_drb(int is_gnb,
ue_id_t UEid,
struct NR_DRB_ToAddMod *s,
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters);
void nr_pdcp_add_drb(int is_gnb,
const ue_id_t UEid,
const NR_PDCP_Config_t *pdcp,
const struct sdap_configuration_s *sdap,
const nr_pdcp_entity_security_keys_and_algos_t *security_parameters);
void nr_pdcp_remove_UE(ue_id_t ue_id);
void nr_pdcp_reestablishment(ue_id_t ue_id,
+1 -1
View File
@@ -1020,7 +1020,7 @@ int do_RRCReestablishment(int8_t nh_ncc, uint8_t *const buffer, size_t buffer_si
rrcReestablishment->criticalExtensions.choice.rrcReestablishment = CALLOC(1, sizeof(NR_RRCReestablishment_IEs_t));
// 3GPP TS 33.501 Section 6.11 Security handling for RRC connection re-establishment procedure
rrcReestablishment->criticalExtensions.choice.rrcReestablishment->nextHopChainingCount = nh_ncc >= 0 ? nh_ncc : 0;
rrcReestablishment->criticalExtensions.choice.rrcReestablishment->nextHopChainingCount = nh_ncc;
rrcReestablishment->criticalExtensions.choice.rrcReestablishment->lateNonCriticalExtension = NULL;
rrcReestablishment->criticalExtensions.choice.rrcReestablishment->nonCriticalExtension = NULL;
+2 -1
View File
@@ -188,7 +188,6 @@ typedef struct gNB_RRC_UE_s {
/* KgNB as derived from KASME received from EPC */
uint8_t kgnb[32];
int8_t kgnb_ncc;
uint8_t nh[32];
int8_t nh_ncc;
@@ -209,6 +208,8 @@ typedef struct gNB_RRC_UE_s {
uint64_t amf_ue_ngap_id;
// Globally Unique AMF Identifier
nr_guami_t ue_guami;
// Serving PLMN of the UE
plmn_id_t serving_plmn;
ngap_security_capabilities_t security_capabilities;
//NSA block
+1 -2
View File
@@ -998,8 +998,7 @@ static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context
const f1ap_served_cell_info_t *cell_info = &du->setup_req->cell[0].info;
uint32_t ssb_arfcn = get_ssb_arfcn(du);
LOG_I(NR_RRC, "Reestablishment update key pci=%d, earfcn_dl=%u\n", cell_info->nr_pci, ssb_arfcn);
nr_derive_key_ng_ran_star(cell_info->nr_pci, ssb_arfcn, ue_p->nh_ncc >= 0 ? ue_p->nh : ue_p->kgnb, ue_p->kgnb);
ue_p->kgnb_ncc = 0;
nr_derive_key_ng_ran_star(cell_info->nr_pci, ssb_arfcn, ue_p->nh_ncc > 0 ? ue_p->nh : ue_p->kgnb, ue_p->kgnb);
int size = do_RRCReestablishment(ue_context_pP->ue_context.nh_ncc, buffer, NR_RRC_BUF_SIZE, xid);
LOG_A(NR_RRC, "Send RRCReestablishment [%d bytes] to RNTI %04x\n", size, ue_p->rnti);
+55 -11
View File
@@ -110,6 +110,24 @@ static const uint16_t NGAP_INTEGRITY_NIA3_MASK = 0x2000;
static void set_UE_security_algos(const gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const ngap_security_capabilities_t *cap);
/** @brief Validates PLMN against allowed PLMN list and returns pointer to matching PLMN
* @param rrc RRC instance
* @param plmn PLMN to validate
* @return pointer to matching PLMN in configuration, or NULL if not found */
static const plmn_id_t *get_serving_plmn(gNB_RRC_INST *rrc, const plmn_id_t *plmn)
{
// Find matching PLMN in configuration
for (int idx = 0; idx < rrc->configuration.num_plmn; idx++) {
const plmn_id_t *allowed = &rrc->configuration.plmn[idx];
if (allowed->mcc == plmn->mcc && allowed->mnc == plmn->mnc && allowed->mnc_digit_length == plmn->mnc_digit_length) {
LOG_D(NR_RRC, "PLMN (MCC:%d, MNC:%*d) matched with allowed PLMN[%d]\n", plmn->mcc, plmn->mnc_digit_length, plmn->mnc, idx);
return allowed;
}
}
LOG_W(NR_RRC, "PLMN (MCC:%d, MNC:%*d) not found in allowed PLMN list\n", plmn->mcc, plmn->mnc_digit_length, plmn->mnc);
return NULL;
}
/*!
*\brief save security key.
*\param UE UE context.
@@ -122,7 +140,9 @@ static void set_UE_security_key(gNB_RRC_UE_t *UE, uint8_t *security_key_pP)
/* Saves the security key */
memcpy(UE->kgnb, security_key_pP, SECURITY_KEY_LENGTH);
memset(UE->nh, 0, SECURITY_KEY_LENGTH);
UE->nh_ncc = -1;
/* 3GPP TS 33.501 §6.9.2.1.1: On Initial Context Setup, AMF does not send NH;
* gNB shall initialize NCC to 0. */
UE->nh_ncc = 0;
char ascii_buffer[65];
for (i = 0; i < 32; i++) {
@@ -165,9 +185,7 @@ static nr_guami_t get_guami(const uint32_t amf_Id, const plmn_id_t plmn)
guami.amf_region_id = (amf_Id >> 16) & 0xff;
guami.amf_set_id = (amf_Id >> 6) & 0x3ff;
guami.amf_pointer = amf_Id & 0x3f;
guami.mcc = plmn.mcc;
guami.mnc = plmn.mnc;
guami.mnc_len = plmn.mnc_digit_length;
guami.plmn = plmn;
return guami;
}
@@ -223,17 +241,22 @@ void rrc_gNB_send_NGAP_NAS_FIRST_REQ(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, NR_RRC
req->nas_pdu = create_byte_array(rrcSetupComplete->dedicatedNAS_Message.size, rrcSetupComplete->dedicatedNAS_Message.buf);
/* Selected PLMN Identity (Optional)
* selectedPLMN-Identity in RRCSetupComplete: Index of the PLMN selected by the UE from the plmn-IdentityInfoList (SIB1)
* Selected PLMN Identity in INITIAL UE MESSAGE: Indicates the selected PLMN id for the non-3GPP access.*/
if (rrcSetupComplete->selectedPLMN_Identity > rrc->configuration.num_plmn) {
* selectedPLMN-Identity in RRCSetupComplete: Index of the PLMN selected by the UE from the plmn-IdentityInfoList (SIB1) */
int idx = rrcSetupComplete->selectedPLMN_Identity - 1; // Convert 1-based PLMN Identity IE to 0-based index
if (idx < 0 || idx >= rrc->configuration.num_plmn) {
LOG_E(NGAP,
"Failed to send Initial UE Message: selected PLMN (%ld) identity is out of bounds (%d)\n",
rrcSetupComplete->selectedPLMN_Identity,
"Failed to send Initial UE Message: selected PLMN index (%d) is out of bounds [0..%d)\n",
idx,
rrc->configuration.num_plmn);
return;
}
int selected_plmn_identity = rrcSetupComplete->selectedPLMN_Identity - 1; // Convert 1-based PLMN Identity IE to 0-based index
req->plmn = rrc->configuration.plmn[selected_plmn_identity]; // Select from the stored list
req->plmn = rrc->configuration.plmn[idx]; // Select from the stored list
/* UE is connected to only one PLMN at a time: store this as the serving PLMN */
UE->serving_plmn = req->plmn;
// Cell ID (NR CGI)
req->nr_cell_id = UE->nr_cellid;
// PLMN (NR CGI and TAI)
plmn_id_t *p = &req->plmn;
LOG_I(NGAP, "Selected PLMN in the NG Initial UE Message: MCC=%03d MNC=%0*d\n", p->mcc, p->mnc_digit_length, p->mnc);
@@ -721,6 +744,10 @@ void rrc_gNB_send_NGAP_UPLINK_NAS(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const NR_
NGAP_UPLINK_NAS(msg_p).gNB_ue_ngap_id = UE->rrc_ue_id;
NGAP_UPLINK_NAS(msg_p).nas_pdu.len = nas->size;
NGAP_UPLINK_NAS(msg_p).nas_pdu.buf = buf;
/* Fill PLMN and location info: use serving PLMN of the UE */
NGAP_UPLINK_NAS(msg_p).plmn = UE->serving_plmn;
NGAP_UPLINK_NAS(msg_p).nr_cell_id = rrc->nr_cellid;
NGAP_UPLINK_NAS(msg_p).tac = rrc->configuration.tac;
itti_send_msg_to_task(TASK_NGAP, rrc->module_id, msg_p);
}
@@ -1154,6 +1181,20 @@ int rrc_gNB_process_Handover_Request(gNB_RRC_INST *rrc, instance_t instance, nga
rrc_gNB_send_NGAP_HANDOVER_FAILURE(rrc, &fail);
return -1;
}
// Validate PLMN from GUAMI against allowed PLMN list
const plmn_id_t *serving_plmn = get_serving_plmn(rrc, &msg->guami.plmn);
if (!serving_plmn) {
LOG_E(NR_RRC, "PLMN from GUAMI not supported - rejecting handover\n");
ngap_handover_failure_t fail = {
.amf_ue_ngap_id = msg->amf_ue_ngap_id,
.cause.type = NGAP_CAUSE_RADIO_NETWORK,
.cause.value = NGAP_CAUSE_RADIO_NETWORK_HO_TARGET_NOT_ALLOWED,
};
rrc_gNB_send_NGAP_HANDOVER_FAILURE(rrc, &fail);
return -1;
}
uint16_t pci = du->setup_req->cell[0].info.nr_pci;
LOG_I(NR_RRC, "Received Handover Request (on NR Cell ID=%lu, PCI=%u) \n", msg->nr_cell_id, pci);
@@ -1169,6 +1210,9 @@ int rrc_gNB_process_Handover_Request(gNB_RRC_INST *rrc, instance_t instance, nga
// Store IDs in UE context
UE->amf_ue_ngap_id = msg->amf_ue_ngap_id;
UE->ue_guami = msg->guami;
// Store the serving PLMN
UE->serving_plmn = *serving_plmn;
UE->ho_context->target->ue_ho_prep_info = copy_byte_array(msg->ue_ho_prep_info);
// store the received UE Security Capabilities in the UE context
FREE_AND_ZERO_BYTE_ARRAY(UE->ue_cap_buffer);
+23 -4
View File
@@ -161,6 +161,28 @@ static NR_RadioBearerConfig_t *get_default_rbconfig(int eps_bearer_id,
return rbconfig;
}
static void rrc_nsa_add_drb(const int ue_id,
const NR_DRB_ToAddModList_t *addMod,
const nr_pdcp_entity_security_keys_and_algos_t *sp)
{
for (int i = 0; i < addMod->list.count; i++) {
NR_DRB_ToAddMod_t *drb = addMod->list.array[i];
DevAssert(drb->cnAssociation);
DevAssert(drb->cnAssociation->present != NR_DRB_ToAddMod__cnAssociation_PR_NOTHING);
DevAssert(drb->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity);
// get SDAP config
sdap_config_t sdap = {0};
// EPC association
sdap.pdusession_id = drb->cnAssociation->choice.eps_BearerIdentity;
sdap.drb_id = drb->drb_Identity;
sdap.defaultDRB = true;
// add SDAP entity (terminated at gNB, since it's EPC)
nr_sdap_addmod_entity(GNB_FLAG_YES, ue_id, sdap);
// add PDCP entity
nr_pdcp_add_drb(GNB_FLAG_YES, ue_id, drb->pdcp_Config, &sdap, sp);
}
}
/* generate prototypes for the tree management functions (RB_INSERT used in rrc_add_nsa_user) */
RB_PROTOTYPE(rrc_nr_ue_tree_s, rrc_gNB_ue_context_s, entries,
rrc_gNB_compare_ue_rnti_id);
@@ -304,10 +326,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, x2ap_ENDC_sgnb_addition_req_t *m, sctp_
}
DevAssert(UE->rb_config != NULL);
nr_pdcp_add_drbs(GNB_FLAG_YES,
UE->rrc_ue_id,
UE->rb_config->drb_ToAddModList,
&security_parameters);
rrc_nsa_add_drb(UE->rrc_ue_id, UE->rb_config->drb_ToAddModList, &security_parameters);
/* assumption: only a single bearer, see above */
NR_DRB_ToAddModList_t *rb_list = UE->rb_config->drb_ToAddModList;
+26 -4
View File
@@ -599,6 +599,31 @@ static void nr_rrc_process_dedicatedNAS_MessageList(NR_UE_RRC_INST_t *rrc, NR_RR
}
}
/** @brief Add bearer in PDCP/SDAP for 5GC association (SA) */
static void rrc_ue_add_bearer(const int ue_id, const NR_DRB_ToAddMod_t *drb, const nr_pdcp_entity_security_keys_and_algos_t *sp)
{
DevAssert(drb->cnAssociation);
DevAssert(drb->cnAssociation->present != NR_DRB_ToAddMod__cnAssociation_PR_NOTHING);
// get SDAP config
sdap_config_t sdap = {0};
if (drb->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity) {
DevAssert(drb->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity);
// EPC association
sdap.pdusession_id = drb->cnAssociation->choice.eps_BearerIdentity;
sdap.drb_id = drb->drb_Identity;
sdap.defaultDRB = true;
} else {
DevAssert(drb->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config);
DevAssert(drb->cnAssociation->choice.sdap_Config);
sdap = nr_sdap_get_config(GNB_FLAG_NO, drb->cnAssociation->choice.sdap_Config, drb->drb_Identity);
}
// add SDAP entity
nr_sdap_addmod_entity(GNB_FLAG_NO, ue_id, sdap);
// add PDCP entity
nr_pdcp_add_drb(GNB_FLAG_NO, ue_id, drb->pdcp_Config, &sdap, sp);
}
/**
* @brief add, modify and release SRBs and/or DRBs
* @ref 3GPP TS 38.331
@@ -706,10 +731,7 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, NR_Rad
nr_reconfigure_sdap_entity(sdap_Config, ue_rrc->ue_id, sdap_Config->pdu_Session, DRB_id);
} else {
set_DRB_status(ue_rrc ,DRB_id, RB_ESTABLISHED);
add_drb(false,
ue_rrc->ue_id,
radioBearerConfig->drb_ToAddModList->list.array[cnt],
&security_up_parameters);
rrc_ue_add_bearer(ue_rrc->ue_id, radioBearerConfig->drb_ToAddModList->list.array[cnt], &security_up_parameters);
}
}
} // drb_ToAddModList //
+1 -7
View File
@@ -47,7 +47,6 @@ static void reblock_tun_socket(int fd)
bool sdap_data_req(protocol_ctxt_t *ctxt_p,
const ue_id_t ue_id,
const srb_flag_t srb_flag,
const rb_id_t rb_id,
const mui_t mui,
const confirm_t confirm,
const sdu_size_t sdu_buffer_size,
@@ -69,7 +68,6 @@ bool sdap_data_req(protocol_ctxt_t *ctxt_p,
bool ret = sdap_entity->tx_entity(sdap_entity,
ctxt_p,
srb_flag,
rb_id,
mui,
confirm,
sdu_buffer_size,
@@ -82,7 +80,7 @@ bool sdap_data_req(protocol_ctxt_t *ctxt_p,
return ret;
}
void sdap_data_ind(rb_id_t pdcp_entity,
void sdap_data_ind(int pdcp_entity,
int is_gnb,
bool has_sdap_rx,
int pdusession_id,
@@ -100,7 +98,6 @@ void sdap_data_ind(rb_id_t pdcp_entity,
sdap_entity->rx_entity(sdap_entity,
pdcp_entity,
is_gnb,
has_sdap_rx,
pdusession_id,
ue_id,
buf,
@@ -116,8 +113,6 @@ static void *sdap_tun_read_thread(void *arg)
int len;
reblock_tun_socket(entity->pdusession_sock);
int rb_id = 1;
while (!entity->stop_thread) {
len = read(entity->pdusession_sock, &rx_buf, NL_MAX_PAYLOAD);
if (len == -1) {
@@ -148,7 +143,6 @@ static void *sdap_tun_read_thread(void *arg)
entity->tx_entity(entity,
&ctxt,
SRB_FLAG_NO,
rb_id,
RLC_MUI_UNDEFINED,
RLC_SDU_CONFIRM_NO,
len,
+1 -2
View File
@@ -35,7 +35,6 @@
bool sdap_data_req(protocol_ctxt_t *ctxt_p,
const ue_id_t ue_id,
const srb_flag_t srb_flag,
const rb_id_t rb_id,
const mui_t mui,
const confirm_t confirm,
const sdu_size_t sdu_buffer_size,
@@ -53,7 +52,7 @@ bool sdap_data_req(protocol_ctxt_t *ctxt_p,
* Uplink - gNB
* Downlink - nrUE
*/
void sdap_data_ind(rb_id_t pdcp_entity,
void sdap_data_ind(int pdcp_entity,
int is_gnb,
bool has_sdap_rx,
int pdusession_id,
+212 -190
View File
@@ -34,6 +34,8 @@
#include "tun_if.h"
#include "nr_sdap.h"
#define NO_SDAP_HEADER 0
typedef struct {
nr_sdap_entity_t *sdap_entity_llist;
} nr_sdap_entity_info;
@@ -42,35 +44,22 @@ static nr_sdap_entity_info sdap_info;
instance_t *N3GTPUInst = NULL;
/**
* @brief indicates whether it is a receiving SDAP entity
* i.e. for UE, header for DL data is present
* for gNB, header for UL data is present
*/
bool is_sdap_rx(bool is_gnb, NR_SDAP_Config_t *sdap_config)
/** @brief Returns a bitmap indicating the SDAP entity role,
* i.e. for UL transmission, header for UL data is present in RX/TX
* for DL transmission, header for DL data is present in RX/TX */
static int get_sdap_role(bool is_gnb, const NR_SDAP_Config_t *sdap_config)
{
if (is_gnb) {
return sdap_config->sdap_HeaderUL == NR_SDAP_Config__sdap_HeaderUL_present;
} else {
return sdap_config->sdap_HeaderDL == NR_SDAP_Config__sdap_HeaderDL_present;
}
sdap_role_t role_ul = is_gnb ? SDAP_UL_RX : SDAP_UL_TX;
sdap_role_t role_dl = is_gnb ? SDAP_DL_TX : SDAP_DL_RX;
int role = NO_SDAP_HEADER;
if (sdap_config->sdap_HeaderUL == NR_SDAP_Config__sdap_HeaderUL_present)
role |= role_ul;
if (sdap_config->sdap_HeaderDL == NR_SDAP_Config__sdap_HeaderDL_present)
role |= role_dl;
return role;
}
/**
* @brief indicates whether it is a transmitting SDAP entity
* i.e. for UE, header for UL data is present
* for gNB, header for DL data is present
*/
bool is_sdap_tx(bool is_gnb, NR_SDAP_Config_t *sdap_config)
{
if (is_gnb) {
return sdap_config->sdap_HeaderDL == NR_SDAP_Config__sdap_HeaderDL_present;
} else {
return sdap_config->sdap_HeaderUL == NR_SDAP_Config__sdap_HeaderUL_present;
}
}
void nr_pdcp_submit_sdap_ctrl_pdu(ue_id_t ue_id, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu)
void nr_pdcp_submit_sdap_ctrl_pdu(ue_id_t ue_id, int sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu)
{
protocol_ctxt_t ctxt = { .rntiMaybeUEid = ue_id };
@@ -84,7 +73,7 @@ void nr_pdcp_submit_sdap_ctrl_pdu(ue_id_t ue_id, rb_id_t sdap_ctrl_pdu_drb, nr_s
PDCP_TRANSMISSION_MODE_UNKNOWN,
NULL,
NULL);
LOG_D(SDAP, "Control PDU - Submitting Control PDU to DRB ID: %ld\n", sdap_ctrl_pdu_drb);
LOG_D(SDAP, "Control PDU - Submitting Control PDU to DRB ID: %d\n", sdap_ctrl_pdu_drb);
LOG_D(SDAP, "QFI: %u\n R: %u\n D/C: %u\n", ctrl_pdu.QFI, ctrl_pdu.R, ctrl_pdu.DC);
return;
}
@@ -92,7 +81,6 @@ void nr_pdcp_submit_sdap_ctrl_pdu(ue_id_t ue_id, rb_id_t sdap_ctrl_pdu_drb, nr_s
static bool nr_sdap_tx_entity(nr_sdap_entity_t *entity,
protocol_ctxt_t *ctxt_p,
const srb_flag_t srb_flag,
const rb_id_t rb_id,
const mui_t mui,
const confirm_t confirm,
const sdu_size_t sdu_buffer_size,
@@ -105,9 +93,8 @@ static bool nr_sdap_tx_entity(nr_sdap_entity_t *entity,
/* The offset of the SDAP header, it might be 0 if has_sdap_tx is not true in the pdcp entity. */
int offset=0;
bool ret = false;
/*Hardcode DRB ID given from upper layer (ue/gnb_tun_read_thread rb_id), it will change if we have SDAP*/
rb_id_t sdap_drb_id = rb_id;
int pdcp_ent_has_sdap = 0;
bool sdap_ul_tx = false;
bool sdap_dl_tx = false;
if(sdu_buffer == NULL) {
LOG_E(SDAP, "%s:%d:%s: NULL sdu_buffer \n", __FILE__, __LINE__, __FUNCTION__);
@@ -115,19 +102,22 @@ static bool nr_sdap_tx_entity(nr_sdap_entity_t *entity,
}
uint8_t sdap_buf[SDAP_MAX_PDU];
rb_id_t pdcp_entity = entity->qfi2drb_map(entity, qfi);
int drb_id = entity->qfi2drb_map(entity, qfi);
if(pdcp_entity){
sdap_drb_id = pdcp_entity;
pdcp_ent_has_sdap = entity->qfi2drb_table[qfi].has_sdap_tx;
LOG_D(SDAP, "TX - QFI: %u is mapped to DRB ID: %ld\n", qfi, entity->qfi2drb_table[qfi].drb_id);
if (drb_id != SDAP_MAP_RULE_EMPTY) {
sdap_ul_tx = entity->qfi2drb_table[qfi].entity_role & SDAP_UL_TX; // UE TX entity
sdap_dl_tx = entity->qfi2drb_table[qfi].entity_role & SDAP_DL_TX; // gNB TX entity
LOG_D(SDAP, "TX - QFI: %u is mapped to DRB ID: %d\n", qfi, entity->qfi2drb_table[qfi].drb_id);
} else {
LOG_E(SDAP, "QFI %u not mapped to any DRB - dropping SDU of size %d\n", qfi, sdu_buffer_size);
return false;
}
if(!pdcp_ent_has_sdap){
LOG_D(SDAP, "TX - DRB ID: %ld does not have SDAP\n", entity->qfi2drb_table[qfi].drb_id);
if (!sdap_ul_tx && !sdap_dl_tx) {
LOG_D(SDAP, "TX - DRB ID: %d does not have SDAP header\n", entity->qfi2drb_table[qfi].drb_id);
ret = nr_pdcp_data_req_drb(ctxt_p,
srb_flag,
sdap_drb_id,
drb_id,
mui,
confirm,
sdu_buffer_size,
@@ -147,7 +137,7 @@ static bool nr_sdap_tx_entity(nr_sdap_entity_t *entity,
return 0;
}
if(ctxt_p->enb_flag) { // gNB
if (sdap_dl_tx) { // create DL Data PDU with SDAP header
offset = SDAP_HDR_LENGTH;
/*
* TS 37.324 4.4 Functions
@@ -165,7 +155,7 @@ static bool nr_sdap_tx_entity(nr_sdap_entity_t *entity,
LOG_D(SDAP, "TX Entity QFI: %u \n", sdap_hdr.QFI);
LOG_D(SDAP, "TX Entity RQI: %u \n", sdap_hdr.RQI);
LOG_D(SDAP, "TX Entity RDI: %u \n", sdap_hdr.RDI);
} else { // nrUE
} else if (sdap_ul_tx) { // create UL Data PDU with SDAP header
offset = SDAP_HDR_LENGTH;
/*
* TS 37.324 4.4 Functions
@@ -195,7 +185,7 @@ static bool nr_sdap_tx_entity(nr_sdap_entity_t *entity,
*/
ret = nr_pdcp_data_req_drb(ctxt_p,
srb_flag,
sdap_drb_id,
drb_id,
mui,
confirm,
sdu_buffer_size + offset,
@@ -211,9 +201,8 @@ static bool nr_sdap_tx_entity(nr_sdap_entity_t *entity,
}
static void nr_sdap_rx_entity(nr_sdap_entity_t *entity,
rb_id_t pdcp_entity,
int pdcp_entity,
int is_gnb,
bool has_sdap_rx,
int pdusession_id,
ue_id_t ue_id,
char *buf,
@@ -221,9 +210,18 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity,
{
/* The offset of the SDAP header, it might be 0 if has_sdap_rx is not true in the pdcp entity. */
int offset=0;
int qfi = buf[0] & 0x3F; // QFI is always the first 6 bits in the first octet
if (qfi <= 0 || qfi >= SDAP_MAX_QFI) {
LOG_E(SDAP, "Invalid QFI %d received in SDAP header\n", qfi);
return;
}
// Fetch entity role from the qfi2drb_table
bool sdap_ul_rx = entity->qfi2drb_table[qfi].entity_role & SDAP_UL_RX; // gNB RX entity
bool sdap_dl_rx = entity->qfi2drb_table[qfi].entity_role & SDAP_DL_RX; // UE RX entity
if (is_gnb) { // gNB
if (has_sdap_rx) { // Handling the SDAP Header
if (sdap_ul_rx) { // UL Data/Control PDU with SDAP header
offset = SDAP_HDR_LENGTH;
nr_sdap_ul_hdr_t *sdap_hdr = (nr_sdap_ul_hdr_t *)buf;
LOG_D(SDAP, "RX Entity Received QFI: %u\n", sdap_hdr->QFI);
@@ -255,7 +253,7 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity,
* 5.2.2 Downlink
* if the DRB from which this SDAP data PDU is received is configured by RRC with the presence of SDAP header.
*/
if (has_sdap_rx) { // Handling the SDAP Header
if (sdap_dl_rx) { // DL Data/Control PDU with SDAP header
offset = SDAP_HDR_LENGTH;
/*
* TS 37.324 5.2 Data transfer
@@ -281,7 +279,7 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity,
*/
if(!entity->qfi2drb_table[sdap_hdr->QFI].drb_id && entity->default_drb){
nr_sdap_ul_hdr_t sdap_ctrl_pdu = entity->sdap_construct_ctrl_pdu(sdap_hdr->QFI);
rb_id_t sdap_ctrl_pdu_drb = entity->sdap_map_ctrl_pdu(entity, pdcp_entity, SDAP_CTRL_PDU_MAP_DEF_DRB, sdap_hdr->QFI);
int sdap_ctrl_pdu_drb = entity->sdap_map_ctrl_pdu(entity, SDAP_CTRL_PDU_MAP_DEF_DRB, sdap_hdr->QFI);
entity->sdap_submit_ctrl_pdu(ue_id, sdap_ctrl_pdu_drb, sdap_ctrl_pdu);
}
@@ -296,7 +294,7 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity,
*/
if (pdcp_entity != entity->qfi2drb_table[sdap_hdr->QFI].drb_id) {
nr_sdap_ul_hdr_t sdap_ctrl_pdu = entity->sdap_construct_ctrl_pdu(sdap_hdr->QFI);
rb_id_t sdap_ctrl_pdu_drb = entity->sdap_map_ctrl_pdu(entity, pdcp_entity, SDAP_CTRL_PDU_MAP_RULE_DRB, sdap_hdr->QFI);
int sdap_ctrl_pdu_drb = entity->sdap_map_ctrl_pdu(entity, SDAP_CTRL_PDU_MAP_RULE_DRB, sdap_hdr->QFI);
entity->sdap_submit_ctrl_pdu(ue_id, sdap_ctrl_pdu_drb, sdap_ctrl_pdu);
}
@@ -333,51 +331,52 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity,
}
}
/**
* @brief update QFI to DRB mapping rules
*/
void nr_sdap_qfi2drb_map_update(nr_sdap_entity_t *entity, uint8_t qfi, rb_id_t drb, bool has_sdap_rx, bool has_sdap_tx)
static void nr_sdap_qfi2drb_map_add(nr_sdap_entity_t *entity,
const uint8_t qfi,
const uint8_t drb_id,
const uint8_t role)
{
if(qfi < SDAP_MAX_QFI &&
qfi > SDAP_MAP_RULE_EMPTY &&
drb > 0 &&
drb <= AVLBL_DRB){
entity->qfi2drb_table[qfi].drb_id = drb;
entity->qfi2drb_table[qfi].has_sdap_rx = has_sdap_rx;
entity->qfi2drb_table[qfi].has_sdap_tx = has_sdap_tx;
LOG_D(SDAP, "Updated mapping: QFI %u -> DRB %ld \n", qfi, entity->qfi2drb_table[qfi].drb_id);
} else {
LOG_D(SDAP, "Map updated failed, QFI: %u, DRB: %ld\n", qfi, drb);
}
qfi2drb_t *qfi2drb = &entity->qfi2drb_table[qfi];
LOG_D(SDAP, "%s mapping: QFI %u -> DRB %d \n", qfi2drb->drb_id == SDAP_NO_MAPPING_RULE ? "Add" : "Update", qfi, drb_id);
qfi2drb->drb_id = drb_id;
qfi2drb->entity_role = role;
}
void nr_sdap_qfi2drb_map_del(nr_sdap_entity_t *entity, uint8_t qfi){
entity->qfi2drb_table[qfi].drb_id = SDAP_NO_MAPPING_RULE;
LOG_D(SDAP, "Deleted mapping for QFI: %u \n", qfi);
static void nr_sdap_qfi2drb_map_del(nr_sdap_entity_t *entity, const uint8_t qfi)
{
qfi2drb_t *qfi2drb = &entity->qfi2drb_table[qfi];
qfi2drb->drb_id = SDAP_NO_MAPPING_RULE;
LOG_D(SDAP, "Deleted mapping for QFI=%d, DRB=%d\n", qfi, qfi2drb->drb_id);
}
/**
* @brief maps the QFIs to the default DRB if not mapping rule exists
* @return DRB that is mapped to the QFI, 0 if no mapping and no default DRB exists for that QFI
*/
rb_id_t nr_sdap_qfi2drb_map(nr_sdap_entity_t *entity, uint8_t qfi){
rb_id_t pdcp_entity;
pdcp_entity = entity->qfi2drb_table[qfi].drb_id;
if(pdcp_entity){
LOG_D(SDAP, "Mapping rule exists for QFI: %u\n", qfi);
return pdcp_entity;
} else if(entity->default_drb) {
LOG_D(SDAP, "Mapping QFI: %u to Default DRB: %ld\n", qfi, entity->default_drb);
entity->qfi2drb_map_update(entity, qfi, entity->default_drb, entity->qfi2drb_table[qfi].has_sdap_rx, entity->qfi2drb_table[qfi].has_sdap_tx);
* @brief get the DRB ID mapped to the QFI, for both DL and UL
* @return DRB that is mapped to the QFI
* or the default DRB if no mapping rule exists
* or 0 if no mapping and no default DRB exists for that QFI
* @ref TS 37.324, 5.2.1 Uplink
* If there is no stored QoS flow to DRB mapping rule for the
* QoS flow as specified in the subclause 5.3, and a default DRB is configured,
* map the SDAP SDU to the default DRB else, map the SDAP SDU to the DRB according
* to the stored QoS flow to DRB mapping rule. */
static int nr_sdap_qfi2drb(nr_sdap_entity_t *entity, uint8_t qfi)
{
/* Fetch DRB ID mapped to QFI */
int drb_id = entity->qfi2drb_table[qfi].drb_id;
if (drb_id) {
/* QoS flow to DRB mapping rule exists, return corresponding DRB ID */
LOG_D(SDAP, "Existing QoS flow to DRB mapping rule: QFI %u to DRB %d\n", qfi, drb_id);
return drb_id;
} else if (entity->default_drb) {
/* QoS flow to DRB mapping rule does not exist, map SDAP SDU to default DRB, e.g. return default DRB of the SDAP entity */
LOG_D(SDAP, "QoS flow to DRB mapping rule does not exists! mapping SDU to Default DRB: %d\n", entity->default_drb);
return entity->default_drb;
} else {
LOG_D(SDAP, "Mapping rule and default DRB do not exist for QFI:%u\n", qfi);
/* Note: UE undefined behaviour when neither a default DRB
nor a stored QoS flow to DRB mapping rule exists */
LOG_E(SDAP, "Mapping rule and default DRB do not exist for QFI:%u\n", qfi);
return SDAP_MAP_RULE_EMPTY;
}
return pdcp_entity;
}
nr_sdap_ul_hdr_t nr_sdap_construct_ctrl_pdu(uint8_t qfi){
@@ -391,15 +390,16 @@ nr_sdap_ul_hdr_t nr_sdap_construct_ctrl_pdu(uint8_t qfi){
return sdap_end_marker_hdr;
}
rb_id_t nr_sdap_map_ctrl_pdu(nr_sdap_entity_t *entity, rb_id_t pdcp_entity, int map_type, uint8_t dl_qfi){
rb_id_t drb_of_endmarker = 0;
int nr_sdap_map_ctrl_pdu(nr_sdap_entity_t *entity, int map_type, uint8_t dl_qfi)
{
int drb_of_endmarker = 0;
if(map_type == SDAP_CTRL_PDU_MAP_DEF_DRB){
drb_of_endmarker = entity->default_drb;
LOG_D(SDAP, "Mapping Control PDU QFI: %u to Default DRB: %ld\n", dl_qfi, drb_of_endmarker);
LOG_D(SDAP, "Mapping Control PDU QFI: %u to Default DRB: %d\n", dl_qfi, drb_of_endmarker);
}
if(map_type == SDAP_CTRL_PDU_MAP_RULE_DRB){
drb_of_endmarker = entity->qfi2drb_map(entity, dl_qfi);
LOG_D(SDAP, "Mapping Control PDU QFI: %u to DRB: %ld\n", dl_qfi, drb_of_endmarker);
LOG_D(SDAP, "Mapping Control PDU QFI: %u to DRB: %d\n", dl_qfi, drb_of_endmarker);
}
return drb_of_endmarker;
}
@@ -407,7 +407,7 @@ rb_id_t nr_sdap_map_ctrl_pdu(nr_sdap_entity_t *entity, rb_id_t pdcp_entity, int
/**
* @brief Submit the end-marker control PDU to PDCP according to TS 37.324, clause 5.3
*/
void nr_sdap_submit_ctrl_pdu(ue_id_t ue_id, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu)
void nr_sdap_submit_ctrl_pdu(ue_id_t ue_id, int sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu)
{
if(sdap_ctrl_pdu_drb){
nr_pdcp_submit_sdap_ctrl_pdu(ue_id, sdap_ctrl_pdu_drb, ctrl_pdu);
@@ -415,116 +415,113 @@ void nr_sdap_submit_ctrl_pdu(ue_id_t ue_id, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_u
}
}
/**
* @brief UL QoS flow to DRB mapping configuration for an existing SDAP entity
* according to TS 37.324, 5.3 QoS flow to DRB Mapping, clause 5.3.1 Configuration Procedures
*/
static void nr_sdap_ue_qfi2drb_config(nr_sdap_entity_t *existing_sdap_entity,
rb_id_t pdcp_entity,
ue_id_t ue_id,
NR_QFI_t *mapped_qfi_2_add,
uint8_t mappedQFIs2AddCount,
uint8_t drb_identity,
bool has_sdap_rx,
bool has_sdap_tx)
/** @brief UL QoS flow to DRB mapping configuration for a SDAP entity has already been established
* according to TS 37.324, 5.3 QoS flow to DRB Mapping, 5.3.1 Configuration Procedures. */
static void nr_sdap_ue_control_pdu_config(nr_sdap_entity_t *entity, const ue_id_t ue_id, const sdap_config_t *sdap)
{
LOG_D(SDAP, "RRC Configuring SDAP Entity\n");
for(int i = 0; i < mappedQFIs2AddCount; i++){
uint8_t qfi = mapped_qfi_2_add[i];
/* a default DRB exists and there is no QFI to DRB mapping rule for the QFI */
if (existing_sdap_entity->default_drb && existing_sdap_entity->qfi2drb_table[qfi].drb_id == SDAP_NO_MAPPING_RULE) {
nr_sdap_ul_hdr_t sdap_ctrl_pdu = existing_sdap_entity->sdap_construct_ctrl_pdu(qfi);
rb_id_t sdap_ctrl_pdu_drb =
existing_sdap_entity->sdap_map_ctrl_pdu(existing_sdap_entity, pdcp_entity, SDAP_CTRL_PDU_MAP_DEF_DRB, qfi);
existing_sdap_entity->sdap_submit_ctrl_pdu(ue_id, sdap_ctrl_pdu_drb, sdap_ctrl_pdu);
// handle QFIs to DRB mapping rule to add
for (int i = 0; i < sdap->mappedQFIs2AddCount; i++) {
uint8_t qfi = sdap->mappedQFIs2Add[i];
/* a default DRB exists and there is no stored QFI to DRB mapping rule for the QFI */
if (entity->default_drb && entity->qfi2drb_table[qfi].drb_id == SDAP_NO_MAPPING_RULE) {
// construct an end-marker control PDU (6.2.3 TS 37.324)
nr_sdap_ul_hdr_t sdap_ctrl_pdu = entity->sdap_construct_ctrl_pdu(qfi);
// map the end-marker control PDU to the default DRB
int sdap_ctrl_pdu_drb = entity->sdap_map_ctrl_pdu(entity, SDAP_CTRL_PDU_MAP_DEF_DRB, qfi);
// submit the end-marker control PDU to the lower layers
entity->sdap_submit_ctrl_pdu(ue_id, sdap_ctrl_pdu_drb, sdap_ctrl_pdu);
}
/* the stored UL QFI to DRB mapping rule is different from the configured one and has UL SDAP header*/
if (existing_sdap_entity->qfi2drb_table[qfi].drb_id != drb_identity && existing_sdap_entity->qfi2drb_table[qfi].has_sdap_tx) {
nr_sdap_ul_hdr_t sdap_ctrl_pdu = existing_sdap_entity->sdap_construct_ctrl_pdu(qfi);
rb_id_t sdap_ctrl_pdu_drb =
existing_sdap_entity->sdap_map_ctrl_pdu(existing_sdap_entity, pdcp_entity, SDAP_CTRL_PDU_MAP_RULE_DRB, qfi);
existing_sdap_entity->sdap_submit_ctrl_pdu(ue_id, sdap_ctrl_pdu_drb, sdap_ctrl_pdu);
/* the stored UL QFI to DRB mapping rule is different from the configured one and has UL SDAP header */
bool ul_sdap_header = (entity->qfi2drb_table[qfi].entity_role & SDAP_UL_TX) != 0;
if (entity->qfi2drb_table[qfi].drb_id != sdap->drb_id && ul_sdap_header) {
// construct an end-marker control PDU (6.2.3 TS 37.324)
nr_sdap_ul_hdr_t sdap_ctrl_pdu = entity->sdap_construct_ctrl_pdu(qfi);
// map the end-marker control PDU to the DRB according to the stored QoS flow to DRB mapping rule
int sdap_ctrl_pdu_drb = entity->sdap_map_ctrl_pdu(entity, SDAP_CTRL_PDU_MAP_RULE_DRB, qfi);
// submit the end-marker control PDU to the lower layers
entity->sdap_submit_ctrl_pdu(ue_id, sdap_ctrl_pdu_drb, sdap_ctrl_pdu);
}
/* update QFI to DRB mapping rules */
LOG_D(SDAP, "Storing the configured QoS flow to DRB mapping rule\n");
existing_sdap_entity->qfi2drb_map_update(existing_sdap_entity, qfi, drb_identity, has_sdap_rx, has_sdap_tx);
}
}
/** @brief Add QoS flows to a DRB */
static void nr_sdap_add_qos_flows_to_drb(nr_sdap_entity_t *entity, const sdap_config_t *sdap)
{
for (int i = 0; i < sdap->mappedQFIs2AddCount; i++) {
uint8_t qfi = sdap->mappedQFIs2Add[i];
LOG_D(SDAP, "Adding QFI to DRB mapping rules: %d mapped QFIs for DRB %d\n", sdap->mappedQFIs2AddCount, sdap->drb_id);
if (qfi < SDAP_MAX_QFI && qfi > SDAP_MAP_RULE_EMPTY && sdap->drb_id > 0 && sdap->drb_id <= MAX_DRBS_PER_UE) {
entity->qfi2drb_map_add(entity, qfi, sdap->drb_id, sdap->role);
} else {
LOG_E(SDAP, "Failed to add qfi2drb mapping: QFI=%d, DRB=%d\n", qfi, sdap->drb_id);
}
}
}
/** @brief Remove QoS flows from a DRB */
static void nr_sdap_rm_qos_flows_from_drb(nr_sdap_entity_t *entity, const sdap_config_t *sdap)
{
for (int i = 0; i < sdap->mappedQFIs2ReleaseCount; i++) {
uint8_t qfi = sdap->mappedQFIs2Release[i];
LOG_D(SDAP, "Removing QFI from DRB mapping rules: QFI=%d for DRB=%d\n", qfi, sdap->drb_id);
entity->qfi2drb_map_delete(entity, qfi);
}
}
/** @brief Update QFI to DRB mapping rules
* @param qfi the QoS Flow index, used as unique index of the qfi2drb mapping table
* @param drb the DRB ID to be mapped */
static void nr_sdap_qfi2drb_map_update(nr_sdap_entity_t *entity, const sdap_config_t *sdap)
{
if (!entity->is_gnb) { // UE control PDU configuration
nr_sdap_ue_control_pdu_config(entity, entity->ue_id, sdap);
}
nr_sdap_add_qos_flows_to_drb(entity, sdap);
nr_sdap_rm_qos_flows_from_drb(entity, sdap);
}
/**
* @brief add a new SDAP entity according to 5.1.1. of 3GPP TS 37.324
* @note there is one SDAP entity per PDU session
*
* @param is_gnb, indicates whether it is for gNB or UE
* @param has_sdap_rx, indicates whether it is a receiving SDAP entity
* @param has_sdap_tx, indicates whether it is a transmitting SDAP entity
* @param ue_id, UE ID
* @param pdusession_id, PDU session ID
* @param is_defaultDRB, indicates whether the entity has a default DRB
* @param mapped_qfi_2_add, list of QoS flows to add/update
* @param mappedQFIs2AddCount, number of QoS flows to add/update
*/
nr_sdap_entity_t *new_nr_sdap_entity(int is_gnb,
bool has_sdap_rx,
bool has_sdap_tx,
ue_id_t ue_id,
int pdusession_id,
bool is_defaultDRB,
uint8_t drb_identity,
NR_QFI_t *mapped_qfi_2_add,
uint8_t mappedQFIs2AddCount)
* @param sdap, SDAP configuration */
static void nr_sdap_add_entity(const int is_gnb, const ue_id_t ue_id, const sdap_config_t sdap)
{
/* check whether the SDAP entity already exists and
update QFI to DRB mapping rules in that case */
if (nr_sdap_get_entity(ue_id, pdusession_id)) {
LOG_E(SDAP, "SDAP Entity for UE already exists with RNTI/UE ID: %lu and PDU SESSION ID: %d\n", ue_id, pdusession_id);
nr_sdap_entity_t *existing_sdap_entity = nr_sdap_get_entity(ue_id, pdusession_id);
rb_id_t pdcp_entity = existing_sdap_entity->default_drb;
if(!is_gnb)
nr_sdap_ue_qfi2drb_config(existing_sdap_entity,
pdcp_entity,
ue_id,
mapped_qfi_2_add,
mappedQFIs2AddCount,
drb_identity,
has_sdap_rx,
has_sdap_tx);
return existing_sdap_entity;
}
nr_sdap_entity_t *sdap_entity;
sdap_entity = calloc(1, sizeof(nr_sdap_entity_t));
if(sdap_entity == NULL) {
LOG_E(SDAP, "SDAP Entity creation failed, out of memory\n");
exit(1);
}
nr_sdap_entity_t *sdap_entity = calloc_or_fail(1, sizeof(*sdap_entity));
// SDAP entity ids
sdap_entity->ue_id = ue_id;
sdap_entity->pdusession_id = pdusession_id;
sdap_entity->pdusession_id = sdap.pdusession_id;
sdap_entity->is_gnb = is_gnb;
// rx/tx entities
sdap_entity->tx_entity = nr_sdap_tx_entity;
sdap_entity->rx_entity = nr_sdap_rx_entity;
// control pdu function pointers
sdap_entity->sdap_construct_ctrl_pdu = nr_sdap_construct_ctrl_pdu;
sdap_entity->sdap_map_ctrl_pdu = nr_sdap_map_ctrl_pdu;
sdap_entity->sdap_submit_ctrl_pdu = nr_sdap_submit_ctrl_pdu;
// QFI to DRB mapping functions pointers
sdap_entity->qfi2drb_map_update = nr_sdap_qfi2drb_map_update;
sdap_entity->qfi2drb_map_add = nr_sdap_qfi2drb_map_add;
sdap_entity->qfi2drb_map_delete = nr_sdap_qfi2drb_map_del;
sdap_entity->qfi2drb_map = nr_sdap_qfi2drb_map;
sdap_entity->qfi2drb_map = nr_sdap_qfi2drb;
sdap_entity->pdusession_sock = -1;
if(is_defaultDRB) {
sdap_entity->default_drb = drb_identity;
LOG_I(SDAP, "Default DRB for the created SDAP entity: %ld \n", sdap_entity->default_drb);
LOG_D(SDAP, "RRC updating mapping rules: %d\n", mappedQFIs2AddCount);
for (int i = 0; i < mappedQFIs2AddCount; i++)
sdap_entity->qfi2drb_map_update(sdap_entity, mapped_qfi_2_add[i], sdap_entity->default_drb, has_sdap_rx, has_sdap_tx);
// set default DRB
if (sdap.defaultDRB) {
sdap_entity->default_drb = sdap.drb_id;
LOG_I(SDAP, "Default DRB for the created SDAP entity: DRB %d \n", sdap_entity->default_drb);
}
// Add QoS flows to the DRB (initial configuration)
nr_sdap_add_qos_flows_to_drb(sdap_entity, &sdap);
// update SDAP entity list pointers
sdap_entity->next_entity = sdap_info.sdap_entity_llist;
sdap_info.sdap_entity_llist = sdap_entity;
@@ -533,7 +530,17 @@ nr_sdap_entity_t *new_nr_sdap_entity(int is_gnb,
// PDCP SDUs to/from the TUN interface.
start_sdap_tun_gnb_first_ue_default_pdu_session(ue_id);
}
return sdap_entity;
}
/** @brief Add or modify an SDAP entity if it already exists */
void nr_sdap_addmod_entity(const int is_gnb, const ue_id_t ue_id, const sdap_config_t sdap)
{
nr_sdap_entity_t *sdap_entity = nr_sdap_get_entity(ue_id, sdap.pdusession_id);
if (sdap_entity) {
sdap_entity->qfi2drb_map_update(sdap_entity, &sdap);
} else {
nr_sdap_add_entity(is_gnb, ue_id, sdap);
}
}
/**
@@ -653,6 +660,40 @@ bool nr_sdap_delete_ue_entities(ue_id_t ue_id)
return ret;
}
/** @brief This function gets the relevant SDAP config from the received SDAP-Config */
sdap_config_t nr_sdap_get_config(const int is_gnb, const NR_SDAP_Config_t *sdap_Config, const int drb_id)
{
DevAssert(sdap_Config);
sdap_config_t sdapConfig = {0};
sdapConfig.drb_id = drb_id;
sdapConfig.role = get_sdap_role(is_gnb, sdap_Config);
LOG_D(SDAP, "SDAP headers %s\n", sdapConfig.role == NO_SDAP_HEADER ? "absent" : "present");
sdapConfig.defaultDRB = sdap_Config->defaultDRB;
// 3GPP TS 38.331 The network sets sdap-HeaderUL to present if the field defaultDRB is set to true
if (sdapConfig.defaultDRB && (sdap_Config->sdap_HeaderUL != NR_SDAP_Config__sdap_HeaderUL_present))
LOG_D(SDAP, "Received SDAP-Config with defaultDRB but sdap-HeaderUL is not present\n");
if (sdap_Config->mappedQoS_FlowsToAdd) {
sdapConfig.mappedQFIs2AddCount = sdap_Config->mappedQoS_FlowsToAdd->list.count;
DevAssert(sdapConfig.mappedQFIs2AddCount <= SDAP_MAX_QFI);
LOG_D(SDAP, "DRB %d: mapped QFIs = %d \n", sdapConfig.drb_id, sdapConfig.mappedQFIs2AddCount);
for (int i = 0; i < sdapConfig.mappedQFIs2AddCount; i++){
DevAssert(i < SDAP_MAX_QFI);
sdapConfig.mappedQFIs2Add[i] = *sdap_Config->mappedQoS_FlowsToAdd->list.array[i];
LOG_D(SDAP, "Captured mappedQoS_FlowsToAdd[%d] from RRC: %ld\n", i, sdapConfig.mappedQFIs2Add[i]);
}
}
sdapConfig.pdusession_id = sdap_Config->pdu_Session;
if (sdap_Config->mappedQoS_FlowsToRelease) {
sdapConfig.mappedQFIs2ReleaseCount = sdap_Config->mappedQoS_FlowsToRelease->list.count;
DevAssert(sdapConfig.mappedQFIs2ReleaseCount <= SDAP_MAX_QFI);
for (int i = 0; i < sdapConfig.mappedQFIs2ReleaseCount; i++) {
DevAssert(i < SDAP_MAX_QFI);
sdapConfig.mappedQFIs2Release[i] = *sdap_Config->mappedQoS_FlowsToRelease->list.array[i];
}
}
return sdapConfig;
}
/**
* @brief SDAP Entity reconfiguration at UE according to TS 37.324
* and triggered by RRC reconfiguration events according to clause 5.3.5.6.5 of TS 38.331.
@@ -670,27 +711,8 @@ void nr_reconfigure_sdap_entity(NR_SDAP_Config_t *sdap_config, ue_id_t ue_id, in
ue_id,
pdusession_id);
/* QFI to DRB mapping */
NR_QFI_t *mappedQFIs2Add = (NR_QFI_t *)sdap_config->mappedQoS_FlowsToAdd->list.array[0];
uint8_t mappedQFIs2AddCount = sdap_config->mappedQoS_FlowsToAdd->list.count;
bool has_sdap_rx = is_sdap_rx(is_gnb, sdap_config);
bool has_sdap_tx = is_sdap_tx(is_gnb, sdap_config);
nr_sdap_ue_qfi2drb_config(sdap_entity,
sdap_entity->default_drb,
ue_id,
mappedQFIs2Add,
mappedQFIs2AddCount,
drb_id,
has_sdap_rx,
has_sdap_tx);
/* handle QFIs to DRB mapping rule to release */
if (sdap_config->mappedQoS_FlowsToRelease) {
NR_QFI_t *mappedQFIs2release = (NR_QFI_t *)sdap_config->mappedQoS_FlowsToRelease->list.array[0];
uint8_t mappedQFIs2RemoveCount = sdap_config->mappedQoS_FlowsToRelease->list.count;
for(int i = 0; i < mappedQFIs2RemoveCount; i++){
uint8_t qfi = mappedQFIs2release[i];
sdap_entity->qfi2drb_map_delete(sdap_entity, qfi);
}
}
sdap_config_t sdap = nr_sdap_get_config(is_gnb, sdap_config, drb_id);
sdap_entity->qfi2drb_map_update(sdap_entity, &sdap);
}
void set_qfi(uint8_t qfi, uint8_t pduid, ue_id_t ue_id)
+39 -61
View File
@@ -38,7 +38,6 @@
#define SDAP_HDR_LENGTH (1)
#define SDAP_MAX_QFI (64)
#define SDAP_MAP_RULE_EMPTY (0)
#define AVLBL_DRB (5)
#define SDAP_NO_MAPPING_RULE (0)
#define SDAP_REFLECTIVE_MAPPING (1)
#define SDAP_RQI_HANDLING (1)
@@ -69,17 +68,34 @@ typedef struct nr_sdap_ul_hdr_s {
uint8_t DC:1;
} __attribute__((packed)) nr_sdap_ul_hdr_t;
typedef enum {
SDAP_UL_TX = (1 << 0),
SDAP_UL_RX = (1 << 1),
SDAP_DL_TX = (1 << 2),
SDAP_DL_RX = (1 << 3)
} sdap_role_t;
typedef struct qfi2drb_s {
rb_id_t drb_id;
bool has_sdap_rx;
bool has_sdap_tx;
int drb_id;
int entity_role;
} qfi2drb_t;
void nr_pdcp_submit_sdap_ctrl_pdu(ue_id_t ue_id, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu);
void nr_pdcp_submit_sdap_ctrl_pdu(ue_id_t ue_id, int sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu);
typedef struct sdap_configuration_s {
int pdusession_id;
int drb_id;
int role;
bool defaultDRB;
NR_QFI_t mappedQFIs2Add[SDAP_MAX_QFI];
uint8_t mappedQFIs2AddCount;
NR_QFI_t mappedQFIs2Release[SDAP_MAX_QFI];
uint8_t mappedQFIs2ReleaseCount;
} sdap_config_t;
typedef struct nr_sdap_entity_s {
ue_id_t ue_id;
rb_id_t default_drb;
int default_drb;
/// sdap_tun_read_thread needs to know if we are gNB/UE, so for noS1 mode,
/// store which one we are
bool is_gnb;
@@ -91,18 +107,21 @@ typedef struct nr_sdap_entity_s {
qfi2drb_t qfi2drb_table[SDAP_MAX_QFI];
void (*qfi2drb_map_update)(struct nr_sdap_entity_s *entity, uint8_t qfi, rb_id_t drb, bool has_sdap_rx, bool has_sdap_tx);
void (*qfi2drb_map_delete)(struct nr_sdap_entity_s *entity, uint8_t qfi);
rb_id_t (*qfi2drb_map)(struct nr_sdap_entity_s *entity, uint8_t qfi);
void (*qfi2drb_map_update)(struct nr_sdap_entity_s *entity, const sdap_config_t *sdap);
void (*qfi2drb_map_delete)(struct nr_sdap_entity_s *entity, const uint8_t qfi);
void (*qfi2drb_map_add)(struct nr_sdap_entity_s *entity,
const uint8_t qfi,
const uint8_t drb_id,
const uint8_t role);
int (*qfi2drb_map)(struct nr_sdap_entity_s *entity, uint8_t qfi);
nr_sdap_ul_hdr_t (*sdap_construct_ctrl_pdu)(uint8_t qfi);
rb_id_t (*sdap_map_ctrl_pdu)(struct nr_sdap_entity_s *entity, rb_id_t pdcp_entity, int map_type, uint8_t dl_qfi);
void (*sdap_submit_ctrl_pdu)(ue_id_t ue_id, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu);
int (*sdap_map_ctrl_pdu)(struct nr_sdap_entity_s *entity, int map_type, uint8_t dl_qfi);
void (*sdap_submit_ctrl_pdu)(ue_id_t ue_id, int sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu);
bool (*tx_entity)(struct nr_sdap_entity_s *entity,
protocol_ctxt_t *ctxt_p,
const srb_flag_t srb_flag,
const rb_id_t rb_id,
const mui_t mui,
const confirm_t confirm,
const sdu_size_t sdu_buffer_size,
@@ -114,9 +133,8 @@ typedef struct nr_sdap_entity_s {
const bool rqi);
void (*rx_entity)(struct nr_sdap_entity_s *entity,
rb_id_t pdcp_entity,
int pdcp_entity,
int is_gnb,
bool has_sdap_rx,
int pdusession_id,
ue_id_t ue_id,
char *buf,
@@ -126,23 +144,6 @@ typedef struct nr_sdap_entity_s {
struct nr_sdap_entity_s *next_entity;
} nr_sdap_entity_t;
/* QFI to DRB Mapping Related Function */
void nr_sdap_qfi2drb_map_update(nr_sdap_entity_t *entity, uint8_t qfi, rb_id_t drb, bool has_sdap_rx, bool has_sdap_tx);
/* QFI to DRB Mapping Related Function */
void nr_sdap_qfi2drb_map_del(nr_sdap_entity_t *entity, uint8_t qfi);
/*
* TS 37.324
* 4.4 Functions
* Mapping between a QoS flow and a DRB for both DL and UL.
*
* 5.2.1 Uplink
* If there is no stored QoS flow to DRB mapping rule for the QoS flow as specified in the subclause 5.3, map the SDAP SDU to the default DRB
* else, map the SDAP SDU to the DRB according to the stored QoS flow to DRB mapping rule.
*/
rb_id_t nr_sdap_qfi2drb_map(nr_sdap_entity_t *entity, uint8_t qfi);
/*
* TS 37.324 5.3 QoS flow to DRB Mapping
* construct an end-marker control PDU, as specified in the subclause 6.2.3, for the QoS flow;
@@ -155,33 +156,24 @@ nr_sdap_ul_hdr_t nr_sdap_construct_ctrl_pdu(uint8_t qfi);
* 1.) default DRB or
* 2.) DRB according to the stored QoS flow to DRB mapping rule
*/
rb_id_t nr_sdap_map_ctrl_pdu(nr_sdap_entity_t *entity, rb_id_t pdcp_entity, int map_type, uint8_t dl_qfi);
int nr_sdap_map_ctrl_pdu(nr_sdap_entity_t *entity, int map_type, uint8_t dl_qfi);
/*
* TS 37.324 5.3 QoS flow to DRB Mapping
* Submit the end-marker control PDU to the lower layer.
*/
void nr_sdap_submit_ctrl_pdu(ue_id_t ue_id, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu);
/*
* TS 37.324 4.4 5.1.1 SDAP entity establishment
* Establish an SDAP entity.
*/
nr_sdap_entity_t *new_nr_sdap_entity(int is_gnb,
bool has_sdap_rx,
bool has_sdap_tx,
ue_id_t ue_id,
int pdusession_id,
bool is_defaultDRB,
uint8_t default_DRB,
NR_QFI_t *mapped_qfi_2_add,
uint8_t mappedQFIs2AddCount);
void nr_sdap_submit_ctrl_pdu(ue_id_t ue_id, int sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu);
/* Entity Handling Related Functions */
nr_sdap_entity_t *nr_sdap_get_entity(ue_id_t ue_id, int pdusession_id);
sdap_config_t nr_sdap_get_config(const int is_gnb, const NR_SDAP_Config_t *sdap_Config, const int drb_id);
void nr_sdap_release_drb(ue_id_t ue_id, int drb_id, int pdusession_id);
/** @brief Add or modify an SDAP entity based on whether it already exists */
void nr_sdap_addmod_entity(const int is_gnb, const ue_id_t ue_id, const sdap_config_t sdap);
/**
* @brief Function to delete a single SDAP Entity based on the ue_id and pdusession_id.
* @note 1. SDAP entities may have the same ue_id.
@@ -200,20 +192,6 @@ bool nr_sdap_delete_entity(ue_id_t ue_id, int pdusession_id);
*/
bool nr_sdap_delete_ue_entities(ue_id_t ue_id);
/**
* @brief indicates whether it is a receiving SDAP entity
* i.e. for UE, header for DL data is present
* for gNB, header for UL data is present
*/
bool is_sdap_rx(bool is_gnb, NR_SDAP_Config_t *sdap_config);
/**
* @brief indicates whether it is a transmitting SDAP entity
* i.e. for UE, header for UL data is present
* for gNB, header for DL data is present
*/
bool is_sdap_tx(bool is_gnb, NR_SDAP_Config_t *sdap_config);
/**
* @brief Run the SDAP reconfiguration for the DRB
* @param[in] ue_id Unique identifier for the User Equipment. ID Range [0, 65536].
+1 -1
View File
@@ -106,7 +106,7 @@ ngap_cause_t decode_ngap_cause(const NGAP_Cause_t *in)
nr_guami_t decode_ngap_guami(const NGAP_GUAMI_t *in)
{
nr_guami_t out = {0};
TBCD_TO_MCC_MNC(&in->pLMNIdentity, out.mcc, out.mnc, out.mnc_len);
TBCD_TO_MCC_MNC(&in->pLMNIdentity, out.plmn.mcc, out.plmn.mnc, out.plmn.mnc_digit_length);
OCTET_STRING_TO_INT8(&in->aMFRegionID, out.amf_region_id);
OCTET_STRING_TO_INT16(&in->aMFSetID, out.amf_set_id);
OCTET_STRING_TO_INT8(&in->aMFPointer, out.amf_pointer);
+19 -19
View File
@@ -76,9 +76,9 @@ static ngap_gNB_amf_data_t *select_amf(ngap_gNB_instance_t *instance_p, const ng
const nr_guami_t *guami = &msg->ue_identity.guami;
LOG_D(NGAP,
"GUAMI is present: MCC=%03d MNC=%0*d RegionID=%d SetID=%d Pointer=%d\n",
guami->mcc,
guami->mnc_len,
guami->mnc,
guami->plmn.mcc,
guami->plmn.mnc_digit_length,
guami->plmn.mnc,
guami->amf_region_id,
guami->amf_set_id,
guami->amf_pointer);
@@ -89,9 +89,9 @@ static ngap_gNB_amf_data_t *select_amf(ngap_gNB_instance_t *instance_p, const ng
msg->gNB_ue_ngap_id,
amf->amf_name,
amf->assoc_id,
guami->mcc,
guami->mnc_len,
guami->mnc,
guami->plmn.mcc,
guami->plmn.mnc_digit_length,
guami->plmn.mnc,
guami->amf_region_id,
guami->amf_set_id,
guami->amf_pointer);
@@ -181,7 +181,6 @@ int ngap_gNB_handle_nas_first_req(instance_t instance, ngap_nas_first_req_t *UEf
.amf_ref = amf,
.gNB_ue_ngap_id = UEfirstReq->gNB_ue_ngap_id,
.gNB_instance = instance_p,
.selected_plmn_identity = UEfirstReq->plmn,
};
// RAN UE NGAP ID (M)
@@ -211,16 +210,14 @@ int ngap_gNB_handle_nas_first_req(instance_t instance, ngap_nas_first_req_t *UEf
ie->value.choice.UserLocationInformation.present = NGAP_UserLocationInformation_PR_userLocationInformationNR;
asn1cCalloc(ie->value.choice.UserLocationInformation.choice.userLocationInformationNR, userinfo_nr_p);
/* Set nRCellIdentity. default userLocationInformationNR */
MACRO_GNB_ID_TO_CELL_IDENTITY(instance_p->gNB_id,
0, // Cell ID
&userinfo_nr_p->nR_CGI.nRCellIdentity);
/* NR CGI: use gNB ID and Cell ID passed from RRC */
MACRO_GNB_ID_TO_CELL_IDENTITY(instance_p->gNB_id, UEfirstReq->nr_cell_id, &userinfo_nr_p->nR_CGI.nRCellIdentity);
plmn_id_t *plmn = &ue_desc_p.selected_plmn_identity;
/* Use UE's selected PLMN for nR-CGI (from Initial UE Message) */
plmn_id_t *plmn = &UEfirstReq->plmn;
MCC_MNC_TO_TBCD(plmn->mcc, plmn->mnc, plmn->mnc_digit_length, &userinfo_nr_p->nR_CGI.pLMNIdentity);
/* In case of network sharing,
the selected PLMN is indicated by the PLMN Identity IE within the TAI IE */
/* Set TAI - use UE's selected PLMN */
INT24_TO_OCTET_STRING(instance_p->tac, &userinfo_nr_p->tAI.tAC);
MCC_MNC_TO_PLMNID(plmn->mcc, plmn->mnc, plmn->mnc_digit_length, &userinfo_nr_p->tAI.pLMNIdentity);
}
@@ -444,17 +441,20 @@ int ngap_gNB_nas_uplink(instance_t instance, ngap_uplink_nas_t *ngap_uplink_nas_
ie->value.choice.UserLocationInformation.present = NGAP_UserLocationInformation_PR_userLocationInformationNR;
asn1cCalloc(ie->value.choice.UserLocationInformation.choice.userLocationInformationNR, userinfo_nr_p);
/* Set nRCellIdentity. default userLocationInformationNR */
/* Set nRCellIdentity: use gNB ID and Cell ID */
MACRO_GNB_ID_TO_CELL_IDENTITY(ngap_gNB_instance_p->gNB_id,
0, // Cell ID
ngap_uplink_nas_p->nr_cell_id,
&userinfo_nr_p->nR_CGI.nRCellIdentity);
plmn_id_t *plmn = &ue_context_p->selected_plmn_identity;
/* NR CGI */
plmn_id_t *plmn = &ngap_uplink_nas_p->plmn;
MCC_MNC_TO_TBCD(plmn->mcc, plmn->mnc, plmn->mnc_digit_length, &userinfo_nr_p->nR_CGI.pLMNIdentity);
/* Set TAI */
INT24_TO_OCTET_STRING(ngap_gNB_instance_p->tac, &userinfo_nr_p->tAI.tAC);
/* TAI */
INT24_TO_OCTET_STRING(ngap_uplink_nas_p->tac, &userinfo_nr_p->tAI.tAC);
MCC_MNC_TO_PLMNID(plmn->mcc, plmn->mnc, plmn->mnc_digit_length, &userinfo_nr_p->tAI.pLMNIdentity);
}
if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) {
NGAP_ERROR("Failed to encode uplink NAS transport\n");
/* Encode procedure has failed... */
+5 -7
View File
@@ -286,8 +286,7 @@ ngap_gNB_amf_data_t *ngap_gNB_nnsf_select_amf_by_guami(ngap_gNB_instance_t *inst
struct plmn_identity_s *served_plmn_p = NULL;
STAILQ_FOREACH(served_plmn_p, &guami_p->served_plmns, next) {
if ((served_plmn_p->mcc == guami.mcc) &&
(served_plmn_p->mnc == guami.mnc)) {
if ((served_plmn_p->mcc == guami.plmn.mcc) && (served_plmn_p->mnc == guami.plmn.mnc)) {
break;
}
}
@@ -322,9 +321,9 @@ ngap_gNB_amf_data_t *ngap_gNB_nnsf_select_amf_by_guami(ngap_gNB_instance_t *inst
}
NGAP_WARN("No matching AMF found for GUAMI (MCC=%03d MNC=%0*d RegionID=%d SetID=%d Pointer=%d)\n",
guami.mcc,
guami.mnc_len,
guami.mnc,
guami.plmn.mcc,
guami.plmn.mnc_digit_length,
guami.plmn.mnc,
guami.amf_region_id,
guami.amf_set_id,
guami.amf_pointer);
@@ -373,8 +372,7 @@ ngap_gNB_amf_data_t *ngap_gNB_nnsf_select_amf_by_guami_no_cause(ngap_gNB_instanc
struct plmn_identity_s *served_plmn_p = NULL;
STAILQ_FOREACH(served_plmn_p, &guami_p->served_plmns, next) {
if ((served_plmn_p->mcc == guami.mcc) &&
(served_plmn_p->mnc == guami.mnc)) {
if ((served_plmn_p->mcc == guami.plmn.mcc) && (served_plmn_p->mnc == guami.plmn.mnc)) {
break;
}
}
-5
View File
@@ -69,11 +69,6 @@ typedef struct ngap_gNB_ue_context_s {
/* Reference to AMF data this UE is attached to */
struct ngap_gNB_amf_data_s *amf_ref;
/* Signaled by the UE in RRC Connection Setup Complete and used in NAS Uplink
* to route NAS messages correctly. 0-based, not 1-based as in TS 36.331
* 6.2.2 RRC Connection Setup Complete! */
plmn_id_t selected_plmn_identity;
/* Reference to gNB data this UE is attached to */
ngap_gNB_instance_t *gNB_instance;
} ngap_gNB_ue_context_t;

Some files were not shown because too many files have changed in this diff Show More