Commit 46a1d2a6 authored by Robert Schmidt's avatar Robert Schmidt

Merge branch 'integration_2024_w34' into 'develop'

Integration: `2024.w34`

See merge request oai/openairinterface5g!2923

* !2906 mod: Improve signal processing speed of rotate_cpx_vector function
* !2909 NR UE SIB1 free fix
* !2917 Cleanup NR UE NAS instance handling
* !2924 Fix misalignment issues in TLVEncoder macros ENCODE_U16, ENCODE_U24
* !2907 CI: add new testcases to RFSim-5G pipeline, reduce ping and iperf test time
* !2893 LEO satellite delay and Doppler simulation and adjusted NR_UE time sync
parents 2ec8fefb 68b29301
...@@ -932,8 +932,11 @@ class OaiCiTest(): ...@@ -932,8 +932,11 @@ class OaiCiTest():
global_status = CONST.ALL_PROCESSES_OK global_status = CONST.ALL_PROCESSES_OK
for line in ue_log_file.readlines(): for line in ue_log_file.readlines():
result = re.search('nr_synchro_time|Starting NR UE soft modem', str(line)) result = re.search('nr_synchro_time|Starting NR UE soft modem', str(line))
sidelink = re.search('sl-mode', str(line))
if result is not None: if result is not None:
nrUEFlag = True nrUEFlag = True
if sidelink is not None:
nrUEFlag = False
if nrUEFlag: if nrUEFlag:
result = re.search('decode mib', str(line)) result = re.search('decode mib', str(line))
if result is not None: if result is not None:
......
Active_gNBs = ( "5G-GOA-gNB");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
gNBs =
(
{
////////// Identification parameters:
gNB_ID = 0xe00;
gNB_name = "5G-GOA-gNB";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0xffffff }) });
nr_cellid = 12345678L;
////////// Physical parameters:
sib1_tda = 5;
min_rxtxtime = 6;
disable_harq = 1;
servingCellConfigCommon = (
{
#spCellConfigCommon
physCellId = 0;
# downlinkConfigCommon
#frequencyInfoDL
# this is 2150.43 MHz + 14 PRBs@15kHz SCS (same as initial BWP), points to Subcarrier 0 of RB#10 of SSB block
absoluteFrequencySSB = 430590;
dl_frequencyBand = 66;
# this is 2150.43 MHz
dl_absoluteFrequencyPointA = 430086;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing = 0;
dl_carrierBandwidth = 25;
#initialDownlinkBWP
#genericParameters
# this is RBstart=0,L=25 (275*(L-1))+RBstart
initialDLBWPlocationAndBandwidth = 6600;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 0;
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 2;
initialDLBWPsearchSpaceZero = 0;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 66;
# this is 1750.43 MHz
ul_absoluteFrequencyPointA = 350086;
#scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
ul_subcarrierSpacing = 0;
ul_carrierBandwidth = 25;
pMax = 20;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 6600;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 0;
#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 = -118;
#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;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#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;
#oneHalf (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
#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 = 0;
# 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_PositionsInBurs_BitmapPR
# 1=short, 2=medium, 3=long
ssb_PositionsInBurst_PR = 2;
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 = 0;
#tdd-UL-DL-ConfigurationCommon
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
referenceSubcarrierSpacing = 0;
# 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;
#ext2
#ntn_Config_r17
cellSpecificKoffset_r17 = 478;
}
);
TIMERS :
{
sr_ProhibitTimer = 0;
sr_TransMax = 64;
sr_ProhibitTimer_v1700 = 512;
t300 = 2000;
t301 = 2000;
t319 = 2000;
};
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// AMF parameters:
amf_ip_address = ({ ipv4 = "192.168.71.132"; });
NETWORK_INTERFACES :
{
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.71.140/26";
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.71.140/26";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 150;
pucch_TargetSNRx10 = 200;
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
prach_dtx_threshold = 120;
pucch0_dtx_threshold = 150;
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 = [7];
max_pdschReferenceSignalPower = -27;
max_rxgain = 114;
sf_extension = 0;
eNB_instances = [0];
##beamforming 1x2 matrix: 1 layer x 2 antennas
bf_weights = [0x00007fff, 0x0000];
##beamforming 1x4 matrix: 1 layer x 4 antennas
#bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
## beamforming 2x2 matrix:
# bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
## beamforming 4x4 matrix:
#bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
sdr_addrs = "type=x300";
clock_src = "internal";
# if_freq = 3700000000L;
# if_offset = 1000000;
}
);
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_DISABLE";
}
);
rfsimulator :
{
serveraddr = "server";
serverport = 4043;
options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs";
};
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";
};
...@@ -32,20 +32,20 @@ gNBs = ...@@ -32,20 +32,20 @@ gNBs =
# downlinkConfigCommon # downlinkConfigCommon
#frequencyInfoDL #frequencyInfoDL
# this is 3300.60 MHz + 53*12*30e-3 MHz = 3319.68 # this is 3300.60 MHz + 53*12*30e-3 MHz = 3319.68
absoluteFrequencySSB = 621312; absoluteFrequencySSB = 630048;
dl_frequencyBand = 78; dl_frequencyBand = 78;
# this is 3300.60 MHz # this is 3300.60 MHz
dl_absoluteFrequencyPointA = 620040; dl_absoluteFrequencyPointA = 626772;
#scs-SpecificCarrierList #scs-SpecificCarrierList
dl_offstToCarrier = 0; dl_offstToCarrier = 0;
# subcarrierSpacing # subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing = 1; dl_subcarrierSpacing = 1;
dl_carrierBandwidth = 106; dl_carrierBandwidth = 273;
#initialDownlinkBWP #initialDownlinkBWP
#genericParameters #genericParameters
# this is RBstart=27,L=48 (275*(L-1))+RBstart # this is RBstart=27,L=48 (275*(L-1))+RBstart
initialDLBWPlocationAndBandwidth = 28875; # 6366 12925 12956 28875 12952 initialDLBWPlocationAndBandwidth = 1099; # 6366 12925 12956 28875 12952
# subcarrierSpacing # subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 1; initialDLBWPsubcarrierSpacing = 1;
...@@ -61,11 +61,11 @@ gNBs = ...@@ -61,11 +61,11 @@ gNBs =
# subcarrierSpacing # subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
ul_subcarrierSpacing = 1; ul_subcarrierSpacing = 1;
ul_carrierBandwidth = 106; ul_carrierBandwidth = 273;
pMax = 20; pMax = 20;
#initialUplinkBWP #initialUplinkBWP
#genericParameters #genericParameters
initialULBWPlocationAndBandwidth = 28875; initialULBWPlocationAndBandwidth = 1099;
# subcarrierSpacing # subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1; initialULBWPsubcarrierSpacing = 1;
...@@ -140,10 +140,10 @@ gNBs = ...@@ -140,10 +140,10 @@ gNBs =
# pattern1 # pattern1
# dl_UL_TransmissionPeriodicity # dl_UL_TransmissionPeriodicity
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
dl_UL_TransmissionPeriodicity = 6; dl_UL_TransmissionPeriodicity = 5;
nrofDownlinkSlots = 7; nrofDownlinkSlots = 3;
nrofDownlinkSymbols = 6; nrofDownlinkSymbols = 6;
nrofUplinkSlots = 2; nrofUplinkSlots = 1;
nrofUplinkSymbols = 4; nrofUplinkSymbols = 4;
ssPBCH_BlockPower = -25; ssPBCH_BlockPower = -25;
...@@ -179,9 +179,6 @@ MACRLCs = ( ...@@ -179,9 +179,6 @@ MACRLCs = (
num_cc = 1; num_cc = 1;
tr_s_preference = "local_L1"; tr_s_preference = "local_L1";
tr_n_preference = "local_RRC"; tr_n_preference = "local_RRC";
#pusch_TargetSNRx10 = 150;
#pucch_TargetSNRx10 = 200;
dl_max_mcs = 16; # there are retransmissions if more
} }
); );
...@@ -190,7 +187,6 @@ L1s = ( ...@@ -190,7 +187,6 @@ L1s = (
num_cc = 1; num_cc = 1;
tr_n_preference = "local_mac"; tr_n_preference = "local_mac";
prach_dtx_threshold = 120; prach_dtx_threshold = 120;
#pucch0_dtx_threshold = 120;
} }
); );
......
...@@ -86,7 +86,7 @@ ...@@ -86,7 +86,7 @@
<testCase id="030021"> <testCase id="030021">
<class>Iperf</class> <class>Iperf</class>
<desc>Iperf (DL/5Mbps/UDP)(30 sec)</desc> <desc>Iperf (DL/5Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 5M -t 30 -R</iperf_args> <iperf_args>-u -b 5M -t 20 -R</iperf_args>
<id>rfsim5g_ue</id> <id>rfsim5g_ue</id>
<svr_id>rfsim5g_ext_dn</svr_id> <svr_id>rfsim5g_ext_dn</svr_id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold> <iperf_packetloss_threshold>5</iperf_packetloss_threshold>
...@@ -96,7 +96,7 @@ ...@@ -96,7 +96,7 @@
<testCase id="030022"> <testCase id="030022">
<class>Iperf</class> <class>Iperf</class>
<desc>Iperf (UL/3Mbps/UDP)(30 sec)</desc> <desc>Iperf (UL/3Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 3M -t 30</iperf_args> <iperf_args>-u -b 3M -t 20</iperf_args>
<id>rfsim5g_ue</id> <id>rfsim5g_ue</id>
<svr_id>rfsim5g_ext_dn</svr_id> <svr_id>rfsim5g_ext_dn</svr_id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold> <iperf_packetloss_threshold>5</iperf_packetloss_threshold>
......
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
<class>Ping</class> <class>Ping</class>
<desc>Ping ext-dn from NR-UE</desc> <desc>Ping ext-dn from NR-UE</desc>
<id>rfsim5g_ue</id> <id>rfsim5g_ue</id>
<ping_args> -c 20 192.168.72.135</ping_args> <ping_args>-c 20 -i 0.25 192.168.72.135</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold> <ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase> </testCase>
...@@ -80,7 +80,7 @@ ...@@ -80,7 +80,7 @@
<class>Ping</class> <class>Ping</class>
<desc>Ping NR-UE from ext-dn</desc> <desc>Ping NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id> <id>rfsim5g_ext_dn</id>
<ping_args>-c 20 12.1.1.2</ping_args> <ping_args>-c 20 -i 0.25 12.1.1.2</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold> <ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase> </testCase>
......
...@@ -127,7 +127,7 @@ ...@@ -127,7 +127,7 @@
<class>Ping</class> <class>Ping</class>
<desc>Ping ext-dn from NR-UE</desc> <desc>Ping ext-dn from NR-UE</desc>
<id>rfsim5g_ue</id> <id>rfsim5g_ue</id>
<ping_args> -c 20 192.168.72.135</ping_args> <ping_args> -c 20 -i 0.25 192.168.72.135</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold> <ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase> </testCase>
...@@ -135,7 +135,7 @@ ...@@ -135,7 +135,7 @@
<class>Ping</class> <class>Ping</class>
<desc>Ping NR-UE from ext-dn</desc> <desc>Ping NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id> <id>rfsim5g_ext_dn</id>
<ping_args>-c 20 12.1.1.2</ping_args> <ping_args>-c 20 -i 0.25 12.1.1.2</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold> <ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase> </testCase>
...@@ -143,7 +143,7 @@ ...@@ -143,7 +143,7 @@
<class>Ping</class> <class>Ping</class>
<desc>Ping ext-dn from Second NR-UE</desc> <desc>Ping ext-dn from Second NR-UE</desc>
<id>rfsim5g_ue</id> <id>rfsim5g_ue</id>
<ping_args> -c 20 192.168.72.135</ping_args> <ping_args> -c 20 -i 0.25 192.168.72.135</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold> <ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase> </testCase>
...@@ -151,7 +151,7 @@ ...@@ -151,7 +151,7 @@
<class>Ping</class> <class>Ping</class>
<desc>Ping Second NR-UE from ext-dn</desc> <desc>Ping Second NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id> <id>rfsim5g_ext_dn</id>
<ping_args>-c 20 12.1.1.3</ping_args> <ping_args>-c 20 -i 0.25 12.1.1.3</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold> <ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase> </testCase>
...@@ -159,7 +159,7 @@ ...@@ -159,7 +159,7 @@
<class>Ping</class> <class>Ping</class>
<desc>Ping ext-dn from both UEs</desc> <desc>Ping ext-dn from both UEs</desc>
<id>rfsim5g_ue rfsim5g_ue2</id> <id>rfsim5g_ue rfsim5g_ue2</id>
<ping_args>-c 20 192.168.72.135</ping_args> <ping_args>-c 20 -i 0.25 192.168.72.135</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold> <ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase> </testCase>
...@@ -167,7 +167,7 @@ ...@@ -167,7 +167,7 @@
<class>Ping</class> <class>Ping</class>
<desc>Ping ext-dn from both UEs</desc> <desc>Ping ext-dn from both UEs</desc>
<id>rfsim5g_ue rfsim5g_ue2</id> <id>rfsim5g_ue rfsim5g_ue2</id>
<ping_args>-c 20 192.168.72.135</ping_args> <ping_args>-c 20 -i 0.25 192.168.72.135</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold> <ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase> </testCase>
...@@ -175,14 +175,14 @@ ...@@ -175,14 +175,14 @@
<class>Ping</class> <class>Ping</class>
<desc>Ping ext-dn from all UEs</desc> <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> <id>rfsim5g_ue rfsim5g_ue2 rfsim5g_ue3 rfsim5g_ue4 rfsim5g_ue5 rfsim5g_ue6 rfsim5g_ue7 rfsim5g_ue8 rfsim5g_ue9 rfsim5g_ue10</id>
<ping_args>-c 100 192.168.72.135 -i 0.2 -s 1016</ping_args> <ping_args>-c 20 192.168.72.135 -i 0.25 -s 1016</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold> <ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase> </testCase>
<testCase id="030001"> <testCase id="030001">
<class>Iperf</class> <class>Iperf</class>
<desc>Iperf (DL/3Mbps/UDP)(30 sec)</desc> <desc>Iperf (DL/3Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 3M -t 30 -R</iperf_args> <iperf_args>-u -b 3M -t 20 -R</iperf_args>
<id>rfsim5g_ue</id> <id>rfsim5g_ue</id>
<svr_id>rfsim5g_ext_dn</svr_id> <svr_id>rfsim5g_ext_dn</svr_id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold> <iperf_packetloss_threshold>5</iperf_packetloss_threshold>
...@@ -192,7 +192,7 @@ ...@@ -192,7 +192,7 @@
<testCase id="030002"> <testCase id="030002">
<class>Iperf</class> <class>Iperf</class>
<desc>Iperf (UL/1Mbps/UDP)(30 sec)</desc> <desc>Iperf (UL/1Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 1M -t 30</iperf_args> <iperf_args>-u -b 1M -t 20</iperf_args>
<id>rfsim5g_ue</id> <id>rfsim5g_ue</id>
<svr_id>rfsim5g_ext_dn</svr_id> <svr_id>rfsim5g_ext_dn</svr_id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold> <iperf_packetloss_threshold>5</iperf_packetloss_threshold>
......
...@@ -87,7 +87,7 @@ ...@@ -87,7 +87,7 @@
<testCase id="030001"> <testCase id="030001">
<class>Iperf</class> <class>Iperf</class>
<desc>Iperf (DL/3Mbps/UDP)(30 sec)</desc> <desc>Iperf (DL/3Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 3M -t 30 -R</iperf_args> <iperf_args>-u -b 3M -t 20 -R</iperf_args>
<id>rfsim5g_ue</id> <id>rfsim5g_ue</id>
<svr_id>rfsim5g_ext_dn</svr_id> <svr_id>rfsim5g_ext_dn</svr_id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold> <iperf_packetloss_threshold>5</iperf_packetloss_threshold>
...@@ -97,7 +97,7 @@ ...@@ -97,7 +97,7 @@
<testCase id="030002"> <testCase id="030002">
<class>Iperf</class> <class>Iperf</class>
<desc>Iperf (UL/1Mbps/UDP)(30 sec)</desc> <desc>Iperf (UL/1Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 1M -t 30</iperf_args> <iperf_args>-u -b 1M -t 20</iperf_args>
<id>rfsim5g_ue</id> <id>rfsim5g_ue</id>
<svr_id>rfsim5g_ext_dn</svr_id> <svr_id>rfsim5g_ext_dn</svr_id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold> <iperf_packetloss_threshold>5</iperf_packetloss_threshold>
......
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
<class>Ping</class> <class>Ping</class>
<desc>Ping ext-dn from NR-UE</desc> <desc>Ping ext-dn from NR-UE</desc>
<id>rfsim5g_ue</id> <id>rfsim5g_ue</id>
<ping_args> -c 20 192.168.72.135</ping_args> <ping_args>-c 20 -i 0.25 192.168.72.135</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold> <ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase> </testCase>
...@@ -80,14 +80,14 @@ ...@@ -80,14 +80,14 @@
<class>Ping</class> <class>Ping</class>
<desc>Ping NR-UE from ext-dn</desc> <desc>Ping NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id> <id>rfsim5g_ext_dn</id>
<ping_args>-c 20 12.1.1.2</ping_args> <ping_args>-c 20 -i 0.25 12.1.1.2</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold> <ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase> </testCase>
<testCase id="030001"> <testCase id="030001">
<class>Iperf</class> <class>Iperf</class>
<desc>Iperf (DL/3Mbps/UDP)(30 sec)</desc> <desc>Iperf (DL/10Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 3M -t 30 -R</iperf_args> <iperf_args>-u -b 10M -t 20 -R</iperf_args>
<id>rfsim5g_ue</id> <id>rfsim5g_ue</id>
<svr_id>rfsim5g_ext_dn</svr_id> <svr_id>rfsim5g_ext_dn</svr_id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold> <iperf_packetloss_threshold>5</iperf_packetloss_threshold>
...@@ -96,8 +96,8 @@ ...@@ -96,8 +96,8 @@
<testCase id="030002"> <testCase id="030002">
<class>Iperf</class> <class>Iperf</class>
<desc>Iperf (UL/1Mbps/UDP)(30 sec)</desc> <desc>Iperf (UL/4Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 1M -t 30</iperf_args> <iperf_args>-u -b 4M -t 20</iperf_args>
<id>rfsim5g_ue</id> <id>rfsim5g_ue</id>
<svr_id>rfsim5g_ext_dn</svr_id> <svr_id>rfsim5g_ext_dn</svr_id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold> <iperf_packetloss_threshold>5</iperf_packetloss_threshold>
......
...@@ -88,7 +88,7 @@ ...@@ -88,7 +88,7 @@
<testCase id="030011"> <testCase id="030011">
<class>Iperf</class> <class>Iperf</class>
<desc>Iperf (DL/30kbps/UDP)(30 sec)</desc> <desc>Iperf (DL/30kbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 0.03M -t 30 -R -c 10.0.1.1</iperf_args> <iperf_args>-u -b 0.03M -t 20 -R -c 10.0.1.1</iperf_args>
<id>rfsim5g_ue</id> <id>rfsim5g_ue</id>
<svr_id>rfsim5g_gnb_nos1</svr_id> <svr_id>rfsim5g_gnb_nos1</svr_id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold> <iperf_packetloss_threshold>5</iperf_packetloss_threshold>
...@@ -98,7 +98,7 @@ ...@@ -98,7 +98,7 @@
<testCase id="030012"> <testCase id="030012">
<class>Iperf</class> <class>Iperf</class>
<desc>Iperf (UL/30kbps/UDP)(30 sec)</desc> <desc>Iperf (UL/30kbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 0.03M -t 30 -c 10.0.1.1</iperf_args> <iperf_args>-u -b 0.03M -t 20 -c 10.0.1.1</iperf_args>
<id>rfsim5g_ue</id> <id>rfsim5g_ue</id>
<svr_id>rfsim5g_gnb_nos1</svr_id> <svr_id>rfsim5g_gnb_nos1</svr_id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold> <iperf_packetloss_threshold>5</iperf_packetloss_threshold>
......
<!--
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>rfsim-5gnr-ntn-geo</htmlTabRef>
<htmlTabName>Monolithic SA NTN GEO gNB</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
111111
100001
000001
000002
000003
020001
020002
100001
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="111111">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<test_svr_id>0</test_svr_id>
<images_to_pull>oai-gnb-asan oai-nr-ue-asan</images_to_pull>
</testCase>
<testCase id="000001">
<class>DeployGenObject</class>
<desc>Deploy OAI 5G CoreNetwork</desc>
<yaml_path>yaml_files/5g_rfsimulator_ntn_geo</yaml_path>
<services>mysql oai-amf oai-smf oai-upf oai-ext-dn</services>
<nb_healthy>5</nb_healthy>
</testCase>
<testCase id="000002">
<class>DeployGenObject</class>
<desc>Deploy OAI 5G gNB+nrUE RF sim SA</desc>
<yaml_path>yaml_files/5g_rfsimulator_ntn_geo</yaml_path>
<services>oai-gnb oai-nr-ue</services>
<nb_healthy>7</nb_healthy>
</testCase>
<testCase id="000003">
<class>Attach_UE</class>
<desc>Attach OAI UE (Wait for IP)</desc>
<id>rfsim5g_ue</id>
</testCase>
<testCase id="020001">
<class>Ping</class>
<desc>Ping ext-dn from NR-UE</desc>
<id>rfsim5g_ue</id>
<ping_args>-c 20 -i 0.25 192.168.72.135</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="020002">
<class>Ping</class>
<desc>Ping NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id>
<ping_args>-c 20 -i 0.25 12.1.1.2</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="100001">
<class>UndeployGenObject</class>
<desc>Undeploy all OAI 5G stack</desc>
<yaml_path>yaml_files/5g_rfsimulator_ntn_geo</yaml_path>
</testCase>
</testCaseList>
<!--
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>rfsim-5gnr-ntn-geo-down</htmlTabRef>
<htmlTabName>CleanUp SA Monolithic NTN GEO gNB</htmlTabName>
<htmlTabIcon>trash</htmlTabIcon>
<TestCaseRequestedList>
100002
222222
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="100002">
<class>UndeployGenObject</class>
<desc>Undeploy all OAI 5G stack</desc>
<yaml_path>yaml_files/5g_rfsimulator_ntn_geo</yaml_path>
</testCase>
<testCase id="222222">
<class>Clean_Test_Server_Images</class>
<desc>Clean Test Images on Test Server</desc>
<test_svr_id>0</test_svr_id>
</testCase>
</testCaseList>
<!--
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>rfsim-5gnr-sidelink</htmlTabRef>
<htmlTabName>Sidelink test</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
111111
000002
000003
000004
000005
100001
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="111111">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<test_svr_id>0</test_svr_id>
<images_to_pull>oai-nr-ue-asan</images_to_pull>
</testCase>
<testCase id="000002">
<class>DeployGenObject</class>
<desc>Deploy OAI 5G UE 1</desc>
<yaml_path>yaml_files/5g_rfsimulator_sidelink</yaml_path>
<services>oai-nr-ue-1</services>
<nb_healthy>1</nb_healthy>
</testCase>
<testCase id="000003">
<class>DeployGenObject</class>
<desc>Deploy OAI 5G UE 2</desc>
<yaml_path>yaml_files/5g_rfsimulator_sidelink</yaml_path>
<services>oai-nr-ue-2</services>
<nb_healthy>1</nb_healthy>
</testCase>
<testCase id="000004">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>20</idle_sleep_time_in_sec>
</testCase>
<testCase id="000005">
<class>Custom_Command</class>
<desc>Check that UE synched</desc>
<node>localhost</node>
<command>docker logs rfsim5g-oai-nr-ue-2 | grep -m 1 "PSBCH RX:OK"</command>
<command_fail>yes</command_fail>
</testCase>
<testCase id="100001">
<class>UndeployGenObject</class>
<desc>Undeploy all OAI 5G stack</desc>
<yaml_path>yaml_files/5g_rfsimulator_sidelink</yaml_path>
<d_retx_th>1,0,0,0</d_retx_th>
<u_retx_th>1,0,0,0</u_retx_th>
</testCase>
</testCaseList>
<!--
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>rfsim-5gnr-sidelink-down</htmlTabRef>
<htmlTabName>CleanUp sidelink test</htmlTabName>
<htmlTabIcon>trash</htmlTabIcon>
<TestCaseRequestedList>
100002
222222
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="100002">
<class>UndeployGenObject</class>
<desc>Undeploy all OAI 5G stack</desc>
<yaml_path>yaml_files/5g_rfsimulator_sidelink</yaml_path>
</testCase>
<testCase id="222222">
<class>Clean_Test_Server_Images</class>
<desc>Clean Test Images on Test Server</desc>
<test_svr_id>0</test_svr_id>
</testCase>
</testCaseList>
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
<class>Ping</class> <class>Ping</class>
<desc>Ping ext-dn from NR-UE</desc> <desc>Ping ext-dn from NR-UE</desc>
<id>rfsim5g_ue</id> <id>rfsim5g_ue</id>
<ping_args> -c 20 192.168.72.135</ping_args> <ping_args>-c 20 -i 0.25 192.168.72.135</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold> <ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase> </testCase>
...@@ -80,14 +80,14 @@ ...@@ -80,14 +80,14 @@
<class>Ping</class> <class>Ping</class>
<desc>Ping NR-UE from ext-dn</desc> <desc>Ping NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id> <id>rfsim5g_ext_dn</id>
<ping_args>-c 20 12.1.1.2</ping_args> <ping_args>-c 20 -i 0.25 12.1.1.2</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold> <ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase> </testCase>
<testCase id="030001"> <testCase id="030001">
<class>Iperf</class> <class>Iperf</class>
<desc>Iperf (DL/3Mbps/UDP)(30 sec)</desc> <desc>Iperf (DL/3Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 3M -t 30 -R</iperf_args> <iperf_args>-u -b 3M -t 20 -R</iperf_args>
<id>rfsim5g_ue</id> <id>rfsim5g_ue</id>
<svr_id>rfsim5g_ext_dn</svr_id> <svr_id>rfsim5g_ext_dn</svr_id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold> <iperf_packetloss_threshold>5</iperf_packetloss_threshold>
...@@ -97,7 +97,7 @@ ...@@ -97,7 +97,7 @@
<testCase id="030002"> <testCase id="030002">
<class>Iperf</class> <class>Iperf</class>
<desc>Iperf (UL/1Mbps/UDP)(30 sec)</desc> <desc>Iperf (UL/1Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 1M -t 30</iperf_args> <iperf_args>-u -b 1M -t 20</iperf_args>
<id>rfsim5g_ue</id> <id>rfsim5g_ue</id>
<svr_id>rfsim5g_ext_dn</svr_id> <svr_id>rfsim5g_ext_dn</svr_id>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold> <iperf_packetloss_threshold>5</iperf_packetloss_threshold>
......
...@@ -94,7 +94,7 @@ services: ...@@ -94,7 +94,7 @@ services:
public_net: public_net:
ipv4_address: 192.168.71.140 ipv4_address: 192.168.71.140
volumes: volumes:
- ../../conf_files/gnb.sa.band78.106prb.rfsim.2x2.conf:/opt/oai-gnb/etc/gnb.conf - ../../conf_files/gnb.sa.band78.273prb.rfsim.2x2.conf:/opt/oai-gnb/etc/gnb.conf
healthcheck: healthcheck:
test: /bin/bash -c "pgrep nr-softmodem" test: /bin/bash -c "pgrep nr-softmodem"
interval: 10s interval: 10s
...@@ -110,7 +110,7 @@ services: ...@@ -110,7 +110,7 @@ services:
- NET_ADMIN # for interface bringup - NET_ADMIN # for interface bringup
- NET_RAW # for ping - NET_RAW # for ping
environment: environment:
USE_ADDITIONAL_OPTIONS: --sa --rfsim -r 106 --numerology 1 --band 78 -C 3319680000 --ue-nb-ant-tx 2 --uicc0.imsi 208990100001100 --ue-nb-ant-rx 2 --uecap_file /opt/oai-nr-ue/etc/uecap.xml --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time USE_ADDITIONAL_OPTIONS: --sa --rfsim -r 273 --numerology 1 --band 78 -C 3450720000 --ssb 1518 --ue-nb-ant-tx 2 --uicc0.imsi 208990100001100 --ue-nb-ant-rx 2 --uecap_file /opt/oai-nr-ue/etc/uecap.xml --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
depends_on: depends_on:
- oai-gnb - oai-gnb
networks: networks:
......
services:
mysql:
container_name: "rfsim5g-mysql"
image: mysql:8.0
volumes:
- ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
- ../5g_rfsimulator/mysql-healthcheck.sh:/tmp/mysql-healthcheck.sh
environment:
- TZ=Europe/Paris
- MYSQL_DATABASE=oai_db
- MYSQL_USER=test
- MYSQL_PASSWORD=test
- MYSQL_ROOT_PASSWORD=linux
healthcheck:
test: /bin/bash -c "/tmp/mysql-healthcheck.sh"
interval: 10s
timeout: 5s
retries: 30
networks:
public_net:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.0.0
environment:
- TZ=Europe/paris
volumes:
- ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-amf/etc/config.yaml
depends_on:
- mysql
networks:
public_net:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.0.0
environment:
- TZ=Europe/Paris
volumes:
- ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-smf/etc/config.yaml
depends_on:
- oai-amf
networks:
public_net:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.0.0
environment:
- TZ=Europe/Paris
volumes:
- ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-upf/etc/config.yaml
depends_on:
- oai-smf
cap_add:
- NET_ADMIN
- SYS_ADMIN
cap_drop:
- ALL
privileged: true
networks:
public_net:
ipv4_address: 192.168.71.134
traffic_net:
ipv4_address: 192.168.72.134
oai-ext-dn:
privileged: true
container_name: rfsim5g-oai-ext-dn
image: oaisoftwarealliance/trf-gen-cn5g:focal
entrypoint: /bin/bash -c \
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\
"ip route add 12.1.1.0/24 via 192.168.72.134 dev eth0; sleep infinity"
depends_on:
- oai-upf
networks:
traffic_net:
ipv4_address: 192.168.72.135
healthcheck:
test: /bin/bash -c "ping -c 2 192.168.72.134"
interval: 10s
timeout: 5s
retries: 5
oai-gnb:
image: oaisoftwarealliance/oai-gnb:develop
container_name: rfsim5g-oai-gnb
cap_drop:
- ALL
environment:
USE_ADDITIONAL_OPTIONS: --sa --rfsim --rfsimulator.prop_delay 238.74 --log_config.global_log_options level,nocolor,time
ASAN_OPTIONS: detect_leaks=0
depends_on:
- oai-ext-dn
networks:
public_net:
ipv4_address: 192.168.71.140
volumes:
- ../../conf_files/gnb.sa.band66.ntn.25prb.rfsim.conf:/opt/oai-gnb/etc/gnb.conf
healthcheck:
test: /bin/bash -c "pgrep nr-softmodem"
interval: 10s
timeout: 5s
retries: 5
oai-nr-ue:
image: oaisoftwarealliance/oai-nr-ue:develop
container_name: rfsim5g-oai-nr-ue
cap_drop:
- ALL
cap_add:
- NET_ADMIN # for interface bringup
- NET_RAW # for ping
environment:
USE_ADDITIONAL_OPTIONS: --band 66 -C 2152680000 --CO -400000000 -r 25 --numerology 0 --ssb 48 --sa --rfsim --rfsimulator.prop_delay 238.74 --ntn-koffset 478 --ntn-ta-common 477.48 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
depends_on:
- oai-gnb
networks:
public_net:
ipv4_address: 192.168.71.150
devices:
- /dev/net/tun:/dev/net/tun
volumes:
- ../../conf_files/nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf
healthcheck:
test: /bin/bash -c "pgrep nr-uesoftmodem"
interval: 10s
timeout: 5s
retries: 5
networks:
public_net:
driver: bridge
name: rfsim5g-oai-public-net
ipam:
config:
- subnet: 192.168.71.128/26
driver_opts:
com.docker.network.bridge.name: "rfsim5g-public"
traffic_net:
driver: bridge
name: rfsim5g-oai-traffic-net
ipam:
config:
- subnet: 192.168.72.128/26
driver_opts:
com.docker.network.bridge.name: "rfsim5g-traffic"
services:
oai-nr-ue-1:
image: oaisoftwarealliance/oai-nr-ue:develop
container_name: rfsim5g-oai-nr-ue-1
cap_drop:
- ALL
cap_add:
- NET_ADMIN
- NET_RAW
environment:
USE_ADDITIONAL_OPTIONS: --sl-mode 2 --sync-ref 4 --rfsim --rfsimulator.serveraddr server --log_config.global_log_options level,nocolor,time
networks:
public_net:
ipv4_address: 192.168.71.140
devices:
- /dev/net/tun:/dev/net/tun
volumes:
- ../../conf_files/nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf
healthcheck:
test: /bin/bash -c "pgrep nr-uesoftmodem"
interval: 10s
timeout: 5s
retries: 5
oai-nr-ue-2:
image: oaisoftwarealliance/oai-nr-ue:develop
container_name: rfsim5g-oai-nr-ue-2
cap_drop:
- ALL
cap_add:
- NET_ADMIN # for interface bringup
- NET_RAW # for ping
environment:
USE_ADDITIONAL_OPTIONS: --sl-mode 2 --rfsim --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
depends_on:
- oai-nr-ue-1
networks:
public_net:
ipv4_address: 192.168.71.150
devices:
- /dev/net/tun:/dev/net/tun
volumes:
- ../../conf_files/nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf
healthcheck:
test: /bin/bash -c "pgrep nr-uesoftmodem"
interval: 10s
timeout: 5s
retries: 5
networks:
public_net:
driver: bridge
name: rfsim5g-oai-public-net
ipam:
config:
- subnet: 192.168.71.128/26
driver_opts:
com.docker.network.bridge.name: "rfsim5g-public"
traffic_net:
driver: bridge
name: rfsim5g-oai-traffic-net
ipam:
config:
- subnet: 192.168.72.128/26
driver_opts:
com.docker.network.bridge.name: "rfsim5g-traffic"
...@@ -216,7 +216,10 @@ static inline uint64_t BIT_STRING_to_uint64(const BIT_STRING_t *asn) { ...@@ -216,7 +216,10 @@ static inline uint64_t BIT_STRING_to_uint64(const BIT_STRING_t *asn) {
#define asn1cSeqAdd(VaR, PtR) if (ASN_SEQUENCE_ADD(VaR,PtR)!=0) AssertFatal(false, "ASN.1 encoding error " #VaR "\n") #define asn1cSeqAdd(VaR, PtR) if (ASN_SEQUENCE_ADD(VaR,PtR)!=0) AssertFatal(false, "ASN.1 encoding error " #VaR "\n")
#define asn1cCallocOne(VaR, VaLue) \ #define asn1cCallocOne(VaR, VaLue) \
VaR = calloc(1,sizeof(*VaR)); *VaR=VaLue do { \
VaR = calloc(1,sizeof(*VaR)); \
*VaR = VaLue; \
} while (0)
#define asn1cCalloc(VaR, lOcPtr) \ #define asn1cCalloc(VaR, lOcPtr) \
typeof(VaR) lOcPtr = VaR = calloc(1,sizeof(*VaR)) typeof(VaR) lOcPtr = VaR = calloc(1,sizeof(*VaR))
#define asn1cSequenceAdd(VaR, TyPe, lOcPtr) \ #define asn1cSequenceAdd(VaR, TyPe, lOcPtr) \
......
...@@ -157,6 +157,42 @@ E.g. to perform a simple simulation of a satellite in geostationary orbit (GEO), ...@@ -157,6 +157,42 @@ E.g. to perform a simple simulation of a satellite in geostationary orbit (GEO),
--rfsimulator.prop_delay 238.74 --rfsimulator.prop_delay 238.74
``` ```
For simulation of a satellite in low earth orbit (LEO), two channel models have been added to rfsimulator:
- `SAT_LEO_TRANS`: transparent LEO satellite with gNB on ground
- `SAT_LEO_REGEN`: regenerative LEO satellite with gNB on board
Both channel models simulate the delay and Doppler for a circular orbit at 600 km height according to the Matlab function [dopplerShiftCircularOrbit](https://de.mathworks.com/help/satcom/ref/dopplershiftcircularorbit.html).
An example configuration to simulate a transparent LEO satellite with rfsimulator would be:
```
channelmod = {
max_chan=10;
modellist="modellist_rfsimu_1";
modellist_rfsimu_1 = (
{
model_name = "rfsimu_channel_enB0"
type = "SAT_LEO_TRANS";
noise_power_dB = -100;
},
{
model_name = "rfsimu_channel_ue0"
type = "SAT_LEO_TRANS";
noise_power_dB = -100;
}
);
};
```
This configuration is also provided in the file `targets/PROJECTS/GENERIC-NR-5GC/CONF/channelmod_rfsimu_LEO_satellite.conf`.
Additionally, rfsimulator has to be configured to apply the channel model.
This can be done by either providing this line in the conf file in section `rfsimulator`:
```
options = ("chanmod");
```
Or by providing this the the command line parameters:
```
--rfsimulator.options chanmod
```
### gNB ### gNB
The main parameter to cope with the large NTN propagation delay is the cellSpecificKoffset. The main parameter to cope with the large NTN propagation delay is the cellSpecificKoffset.
...@@ -166,11 +202,12 @@ The unit of the field Koffset is number of slots for a given subcarrier spacing ...@@ -166,11 +202,12 @@ The unit of the field Koffset is number of slots for a given subcarrier spacing
This parameter can be provided to the gNB in the conf file as `cellSpecificKoffset_r17` in the section `servingCellConfigCommon`. This parameter can be provided to the gNB in the conf file as `cellSpecificKoffset_r17` in the section `servingCellConfigCommon`.
``` ```
... ...
cellSpecificKoffset_r17 = 478; cellSpecificKoffset_r17 = 478; # GEO satellite
# cellSpecificKoffset_r17 = 40; # LEO satellite
... ...
``` ```
Besides this, some timers, e.g. `sr_ProhibitTimer_v1700`, `t300`, `t301` and `t319`, in the conf file section `gNBs.[0].TIMERS` might need to be extended. Besides this, some timers, e.g. `sr_ProhibitTimer_v1700`, `t300`, `t301` and `t319`, in the conf file section `gNBs.[0].TIMERS` might need to be extended for GEO satellites.
``` ```
... ...
TIMERS : TIMERS :
...@@ -185,7 +222,7 @@ Besides this, some timers, e.g. `sr_ProhibitTimer_v1700`, `t300`, `t301` and `t3 ...@@ -185,7 +222,7 @@ Besides this, some timers, e.g. `sr_ProhibitTimer_v1700`, `t300`, `t301` and `t3
... ...
``` ```
To improve the achievable UL and DL throughput in conditions with large RTT, there is a feature defined in REL17 to disable HARQ feedback. To improve the achievable UL and DL throughput in conditions with large RTT (esp. GEO satellites), there is a feature defined in REL17 to disable HARQ feedback.
This allows to reuse HARQ processes immediately, but it breaks compatibility with UEs not supporting this REL17 feature. This allows to reuse HARQ processes immediately, but it breaks compatibility with UEs not supporting this REL17 feature.
To enable this feature, the `disable_harq` flag has to be added to the gNB conf file in the section `gNBs.[0]` To enable this feature, the `disable_harq` flag has to be added to the gNB conf file in the section `gNBs.[0]`
``` ```
...@@ -199,7 +236,7 @@ To enable this feature, the `disable_harq` flag has to be added to the gNB conf ...@@ -199,7 +236,7 @@ To enable this feature, the `disable_harq` flag has to be added to the gNB conf
... ...
``` ```
So with these modifications to the file `targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf` an example gNB command for FDD, 5 MHz BW, 15 kHz SCS, GEO satellite 5G NR NTN is this: So with these modifications to the file `targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf` an example gNB command for FDD, 5 MHz BW, 15 kHz SCS, transparent GEO satellite 5G NR NTN is this:
``` ```
cd cmake_targets cd cmake_targets
sudo ./ran_build/build/nr-softmodem -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf --sa --rfsim --rfsimulator.prop_delay 238.74 sudo ./ran_build/build/nr-softmodem -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf --sa --rfsim --rfsimulator.prop_delay 238.74
...@@ -213,18 +250,39 @@ To configure NTN gNB with 32 HARQ processes in downlink and uplink, add these se ...@@ -213,18 +250,39 @@ To configure NTN gNB with 32 HARQ processes in downlink and uplink, add these se
... ...
``` ```
To simulate a LEO satellite channel model with rfsimulator in UL (DL is simulated at the UE side) either the `channelmod` section as shown before has to be added to the gNB conf file, or a channelmod conf file has to be included like this:
```
@include "channelmod_rfsimu_LEO_satellite.conf"
```
So with these modifications to the file `targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf` an example gNB command for FDD, 5 MHz BW, 15 kHz SCS, trasparent LEO satellite 5G NR NTN is this:
```
cd cmake_targets
sudo ./ran_build/build/nr-softmodem -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf --sa --rfsim --rfsimulator.prop_delay 20
```
### NR UE ### NR UE
At UE side, there are two main parameters to cope with the large NTN propagation delay, cellSpecificKoffset and ta-Common. At UE side, there are two main parameters to cope with the large NTN propagation delay, cellSpecificKoffset and ta-Common.
`cellSpecificKoffset` is the same as for gNB and can be provided to the UE via command line parameter `--ntn-koffset`. `cellSpecificKoffset` is the same as for gNB and can be provided to the UE via command line parameter `--ntn-koffset`.
`ta-Common` is a common timong advance and can be provided to the UE via command line parameter `--ntn-ta-common` in milliseconds. `ta-Common` is a common timing advance and can be provided to the UE via command line parameter `--ntn-ta-common` in milliseconds.
So an example NR UE command for FDD, 5MHz BW, 15 kHz SCS, GEO satellite 5G NR NTN is this: So an example NR UE command for FDD, 5MHz BW, 15 kHz SCS, transparent GEO satellite 5G NR NTN is this:
``` ```
cd cmake_targets cd cmake_targets
sudo ./ran_build/build/nr-uesoftmodem --band 66 -C 2152680000 --CO -400000000 -r 25 --numerology 0 --ssb 48 --sa --rfsim --rfsimulator.prop_delay 238.74 --ntn-koffset 478 --ntn-ta-common 477.48 sudo ./ran_build/build/nr-uesoftmodem --band 66 -C 2152680000 --CO -400000000 -r 25 --numerology 0 --ssb 48 --sa --rfsim --rfsimulator.prop_delay 238.74 --ntn-koffset 478 --ntn-ta-common 477.48
``` ```
For LEO satellites a third parameter specifying the NTN propagation delay drift has ben added, ta-CommonDrift.
`ta-CommonDrift` provides the drift rate of the common timing advance and can be provided to the UE via command line parameter `--ntn-ta-commondrift` in microseconds per second.
Also, to perform an autonomous TA update based on the DL drift, the boolean parameter `--autonomous-ta` should be added in case of a LEO satellite scenario.
So an example NR UE command for FDD, 5MHz BW, 15 kHz SCS, transparent LEO satellite 5G NR NTN is this:
```
cd cmake_targets
sudo ./ran_build/build/nr-uesoftmodem --band 66 -C 2152680000 --CO -400000000 -r 25 --numerology 0 --ssb 48 --sa --rfsim --rfsimulator.prop_delay 20 --rfsimulator.options chanmod -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/channelmod_rfsimu_LEO_satellite.conf --ntn-koffset 40 --ntn-ta-common 37.74 --ntn-ta-commondrift -50 --autonomous-ta
```
# Specific OAI modes # Specific OAI modes
## phy-test setup with OAI UE ## phy-test setup with OAI UE
......
...@@ -98,7 +98,6 @@ ...@@ -98,7 +98,6 @@
#define CONFIG_HLP_TELN "Start embedded telnet server \n" #define CONFIG_HLP_TELN "Start embedded telnet server \n"
#define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\n" #define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\n"
#define CONFIG_HLP_NOS1 "Disable s1 interface\n" #define CONFIG_HLP_NOS1 "Disable s1 interface\n"
#define CONFIG_HLP_AGC "Rx Gain control used for UE"
/*--------------------------------------------------------------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters for LOG utility */ /* command line parameters for LOG utility */
......
...@@ -597,7 +597,7 @@ void processSlotTX(void *arg) ...@@ -597,7 +597,7 @@ void processSlotTX(void *arg)
static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE, const UE_nr_rxtx_proc_t *proc, int *tx_wait_for_dlsch, nr_phy_data_t *phy_data) static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE, const UE_nr_rxtx_proc_t *proc, int *tx_wait_for_dlsch, nr_phy_data_t *phy_data)
{ {
int sampleShift = 0; int sampleShift = INT_MAX;
NR_DL_FRAME_PARMS *fp = &UE->frame_parms; NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
if (UE->sl_mode == 2) if (UE->sl_mode == 2)
fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params; fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params;
...@@ -802,7 +802,7 @@ void *UE_thread(void *arg) ...@@ -802,7 +802,7 @@ void *UE_thread(void *arg)
bool syncRunning = false; bool syncRunning = false;
const int nb_slot_frame = fp->slots_per_frame; const int nb_slot_frame = fp->slots_per_frame;
int absolute_slot = 0, decoded_frame_rx = INT_MAX, trashed_frames = 0; int absolute_slot = 0, decoded_frame_rx = MAX_FRAME_NUMBER - 1, trashed_frames = 0;
int tx_wait_for_dlsch[NR_MAX_SLOTS_PER_FRAME]; int tx_wait_for_dlsch[NR_MAX_SLOTS_PER_FRAME];
int num_ind_fifo = nb_slot_frame; int num_ind_fifo = nb_slot_frame;
...@@ -886,7 +886,12 @@ void *UE_thread(void *arg) ...@@ -886,7 +886,12 @@ void *UE_thread(void *arg)
stream_status = STREAM_STATUS_SYNCING; stream_status = STREAM_STATUS_SYNCING;
syncInFrame(UE, &sync_timestamp, intialSyncOffset); syncInFrame(UE, &sync_timestamp, intialSyncOffset);
openair0_write_reorder_clear_context(&UE->rfdevice); openair0_write_reorder_clear_context(&UE->rfdevice);
shiftForNextFrame = 0; // will be used to track clock drift UE->max_pos_acc = get_nrUE_params()->ntn_ta_commondrift * 1e-6 * fp->samples_per_frame / get_nrUE_params()->time_sync_I; // ntn_ta_commondrift is in µs/s, max_pos_acc * time_sync_I is in samples/frame
shiftForNextFrame = -(UE->init_sync_frame + trashed_frames + 2) * UE->max_pos_acc * get_nrUE_params()->time_sync_I; // compensate for the time drift that happened during initial sync
LOG_D(PHY, "max_pos_acc = %d, shiftForNextFrame = %d\n", UE->max_pos_acc, shiftForNextFrame);
// TODO: remove this autonomous TA and use up-to-date values of ta-Common, ta-CommonDrift and ta-CommonDriftVariant from received SIB19 instead
if (get_nrUE_params()->autonomous_ta)
UE->timing_advance -= 2 * shiftForNextFrame;
// read in first symbol // read in first symbol
AssertFatal(fp->ofdm_symbol_size + fp->nb_prefix_samples0 AssertFatal(fp->ofdm_symbol_size + fp->nb_prefix_samples0
== UE->rfdevice.trx_read_func(&UE->rfdevice, == UE->rfdevice.trx_read_func(&UE->rfdevice,
...@@ -897,7 +902,7 @@ void *UE_thread(void *arg) ...@@ -897,7 +902,7 @@ void *UE_thread(void *arg)
""); "");
// we have the decoded frame index in the return of the synch process // we have the decoded frame index in the return of the synch process
// and we shifted above to the first slot of next frame // and we shifted above to the first slot of next frame
decoded_frame_rx++; decoded_frame_rx = (decoded_frame_rx + 1) % MAX_FRAME_NUMBER;
// we do ++ first in the regular processing, so it will be begin of frame; // we do ++ first in the regular processing, so it will be begin of frame;
absolute_slot = decoded_frame_rx * nb_slot_frame - 1; absolute_slot = decoded_frame_rx * nb_slot_frame - 1;
if (UE->sl_mode == 2) { if (UE->sl_mode == 2) {
...@@ -947,7 +952,10 @@ void *UE_thread(void *arg) ...@@ -947,7 +952,10 @@ void *UE_thread(void *arg)
if (slot_nr == nb_slot_frame - 1) { if (slot_nr == nb_slot_frame - 1) {
// we shift of half of measured drift, at each beginning of frame for both rx and tx // we shift of half of measured drift, at each beginning of frame for both rx and tx
iq_shift_to_apply = shiftForNextFrame; iq_shift_to_apply = shiftForNextFrame;
shiftForNextFrame = 0; // We will get a new measured offset if we decode PBCH // TODO: remove this autonomous TA and use up-to-date values of ta-Common, ta-CommonDrift and ta-CommonDriftVariant from received SIB19 instead
if (get_nrUE_params()->autonomous_ta)
UE->timing_advance -= 2 * shiftForNextFrame;
shiftForNextFrame = -round(UE->max_pos_acc * get_nrUE_params()->time_sync_I);
} }
const int readBlockSize = get_readBlockSize(slot_nr, fp) - iq_shift_to_apply; const int readBlockSize = get_readBlockSize(slot_nr, fp) - iq_shift_to_apply;
...@@ -991,10 +999,7 @@ void *UE_thread(void *arg) ...@@ -991,10 +999,7 @@ void *UE_thread(void *arg)
nr_rxtx_thread_data_t *curMsgRx = (nr_rxtx_thread_data_t *)NotifiedFifoData(newRx); nr_rxtx_thread_data_t *curMsgRx = (nr_rxtx_thread_data_t *)NotifiedFifoData(newRx);
*curMsgRx = (nr_rxtx_thread_data_t){.proc = curMsg.proc, .UE = UE}; *curMsgRx = (nr_rxtx_thread_data_t){.proc = curMsg.proc, .UE = UE};
int ret = UE_dl_preprocessing(UE, &curMsgRx->proc, tx_wait_for_dlsch, &curMsgRx->phy_data); int ret = UE_dl_preprocessing(UE, &curMsgRx->proc, tx_wait_for_dlsch, &curMsgRx->phy_data);
if (ret) if (ret != INT_MAX)
// if ret is 0, no rx_offset has been computed,
// or the computed value is 0 = no offset to do
// we store it to apply the drift compensation at beginning of next frame
shiftForNextFrame = ret; shiftForNextFrame = ret;
pushTpool(&(get_nrUE_params()->Tpool), newRx); pushTpool(&(get_nrUE_params()->Tpool), newRx);
......
...@@ -9,8 +9,13 @@ ...@@ -9,8 +9,13 @@
#define CONFIG_HLP_DLSCH_PARA "number of threads for dlsch processing 0 for no parallelization\n" #define CONFIG_HLP_DLSCH_PARA "number of threads for dlsch processing 0 for no parallelization\n"
#define CONFIG_HLP_OFFSET_DIV "Divisor for computing OFDM symbol offset in Rx chain (num samples in CP/<the value>). Default value is 8. To set the sample offset to 0, set this value ~ 10e6\n" #define CONFIG_HLP_OFFSET_DIV "Divisor for computing OFDM symbol offset in Rx chain (num samples in CP/<the value>). Default value is 8. To set the sample offset to 0, set this value ~ 10e6\n"
#define CONFIG_HLP_MAX_LDPC_ITERATIONS "Maximum LDPC decoder iterations\n" #define CONFIG_HLP_MAX_LDPC_ITERATIONS "Maximum LDPC decoder iterations\n"
#define CONFIG_HLP_TIME_SYNC_P "coefficient for Proportional part of time sync PI controller\n"
#define CONFIG_HLP_TIME_SYNC_I "coefficient for Integrating part of time sync PI controller\n"
#define CONFIG_HLP_NTN_KOFFSET "NTN cellSpecificKoffset-r17 (number of slots for a given subcarrier spacing of 15 kHz)\n" #define CONFIG_HLP_NTN_KOFFSET "NTN cellSpecificKoffset-r17 (number of slots for a given subcarrier spacing of 15 kHz)\n"
#define CONFIG_HLP_NTN_TA_COMMON "NTN ta-Common, but given in ms\n" #define CONFIG_HLP_NTN_TA_COMMON "NTN ta-Common, but given in ms\n"
#define CONFIG_HLP_NTN_TA_COMMONDRIFT "NTN ta-CommonDrift, but given in µs/s\n"
#define CONFIG_HLP_AUTONOMOUS_TA "Autonomously update TA based on DL drift (useful if main contribution to DL drift is movement, e.g. LEO satellite)\n"
#define CONFIG_HLP_AGC "Rx Gain control used for UE\n"
/***************************************************************************************************************************************/ /***************************************************************************************************************************************/
/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument /* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
...@@ -59,8 +64,12 @@ ...@@ -59,8 +64,12 @@
{"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, .iptr=&(nrUE_params.no_timing_correction), .defintval=0, TYPE_INT, 0}, \ {"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, .iptr=&(nrUE_params.no_timing_correction), .defintval=0, TYPE_INT, 0}, \
{"SLC", CONFIG_HLP_SLF, 0, .u64ptr=&(sidelink_frequency[0][0]), .defuintval=2600000000,TYPE_UINT64,0}, \ {"SLC", CONFIG_HLP_SLF, 0, .u64ptr=&(sidelink_frequency[0][0]), .defuintval=2600000000,TYPE_UINT64,0}, \
{"num-ues", NULL, 0, .iptr=&(NB_UE_INST), .defuintval=1, TYPE_INT, 0}, \ {"num-ues", NULL, 0, .iptr=&(NB_UE_INST), .defuintval=1, TYPE_INT, 0}, \
{"time-sync-P", CONFIG_HLP_TIME_SYNC_P, 0, .dblptr=&(nrUE_params.time_sync_P), .defdblval=0.5, TYPE_DOUBLE, 0}, \
{"time-sync-I", CONFIG_HLP_TIME_SYNC_I, 0, .dblptr=&(nrUE_params.time_sync_I), .defdblval=0.2, TYPE_DOUBLE, 0}, \
{"ntn-koffset", CONFIG_HLP_NTN_KOFFSET, 0, .uptr=&(nrUE_params.ntn_koffset), .defuintval=0, TYPE_UINT, 0}, \ {"ntn-koffset", CONFIG_HLP_NTN_KOFFSET, 0, .uptr=&(nrUE_params.ntn_koffset), .defuintval=0, TYPE_UINT, 0}, \
{"ntn-ta-common", CONFIG_HLP_NTN_TA_COMMON, 0, .dblptr=&(nrUE_params.ntn_ta_common), .defdblval=0.0, TYPE_DOUBLE, 0}, \ {"ntn-ta-common", CONFIG_HLP_NTN_TA_COMMON, 0, .dblptr=&(nrUE_params.ntn_ta_common), .defdblval=0.0, TYPE_DOUBLE, 0}, \
{"ntn-ta-commondrift", CONFIG_HLP_NTN_TA_COMMONDRIFT, 0, .dblptr=&(nrUE_params.ntn_ta_commondrift), .defdblval=0.0, TYPE_DOUBLE, 0}, \
{"autonomous-ta", CONFIG_HLP_AUTONOMOUS_TA, PARAMFLAG_BOOL, .iptr=&(nrUE_params.autonomous_ta), .defintval=0, TYPE_INT, 0}, \
{"agc", CONFIG_HLP_AGC, PARAMFLAG_BOOL, .iptr=&(nrUE_params.agc), .defintval=0, TYPE_INT, 0}, \ {"agc", CONFIG_HLP_AGC, PARAMFLAG_BOOL, .iptr=&(nrUE_params.agc), .defintval=0, TYPE_INT, 0}, \
} }
// clang-format on // clang-format on
...@@ -82,8 +91,12 @@ typedef struct { ...@@ -82,8 +91,12 @@ typedef struct {
int N_RB_DL; int N_RB_DL;
int ssb_start_subcarrier; int ssb_start_subcarrier;
int ldpc_offload_flag; int ldpc_offload_flag;
double time_sync_P;
double time_sync_I;
unsigned int ntn_koffset; unsigned int ntn_koffset;
double ntn_ta_common; double ntn_ta_common;
double ntn_ta_commondrift;
int autonomous_ta;
int agc; int agc;
char *usrp_args; char *usrp_args;
char *tx_subdev; char *tx_subdev;
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h" #include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
#include "PHY/impl_defs_top.h" #include "PHY/impl_defs_top.h"
#include "executables/softmodem-common.h" #include "executables/nr-uesoftmodem.h"
#include "common/utils/LOG/vcd_signal_dumper.h" #include "common/utils/LOG/vcd_signal_dumper.h"
//#define DEBUG_PHY //#define DEBUG_PHY
...@@ -43,12 +43,9 @@ int nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, ...@@ -43,12 +43,9 @@ int nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
short coef) short coef)
{ {
int max_val = 0, max_pos = 0; int max_val = 0, max_pos = 0;
uint8_t sync_offset = 0;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_IN); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_IN);
short ncoef = 32767 - coef;
// search for maximum position within the cyclic prefix // search for maximum position within the cyclic prefix
for (int i = -frame_parms->nb_prefix_samples/2; i < frame_parms->nb_prefix_samples/2; i++) { for (int i = -frame_parms->nb_prefix_samples/2; i < frame_parms->nb_prefix_samples/2; i++) {
int temp = 0; int temp = 0;
...@@ -67,32 +64,37 @@ int nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, ...@@ -67,32 +64,37 @@ int nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
} }
// filter position to reduce jitter // filter position to reduce jitter
ue->max_pos_avg = ((ue->max_pos_avg * coef) >> 15) + (max_pos * ncoef); const int ncoef = 32767 - coef;
ue->max_pos_iir = ((ue->max_pos_iir * coef) >> 15) + (max_pos * ncoef);
int diff = ue->max_pos_avg >> 15; const int diff = (ue->max_pos_iir + 16384) >> 15;
// FIXME: Do we really need this hysteresis for FR2?
int sampleShift = diff;
if (frame_parms->freq_range == FR2) if (frame_parms->freq_range == FR2)
sync_offset = 2; if (abs(diff) <= 2)
else sampleShift = 0;
sync_offset = 0;
int sampleShift = 0; // PI controller
if (abs(diff) > (NR_SYNCH_HYST + sync_offset)) const double PID_P = get_nrUE_params()->time_sync_P;
sampleShift = diff; const double PID_I = get_nrUE_params()->time_sync_I;
int sample_shift = -round(sampleShift * PID_P + ue->max_pos_acc * PID_I);
const int sample_shift = -(sampleShift / 2);
// reset IIR filter for next offset calculation
ue->max_pos_avg += sample_shift * 32768;
LOG_D(PHY, LOG_D(PHY,
"Slot %d: diff = %i, rx_offset (final) = %i : max_pos = %d, max_pos filtered = %ld, max_power = %d\n", "Frame %d, Slot %d: max_pos = %d, max_pos filtered = %f, diff = %i, sampleShift = %i, max_pos_acc = %d, sample_shift (final) = %d, max_power = %d\n",
frame,
slot, slot,
max_pos,
ue->max_pos_iir / 32768.0,
diff, diff,
sampleShift, sampleShift,
max_pos, ue->max_pos_acc,
ue->max_pos_avg, sample_shift,
max_val); max_val);
// reset IIR filter for next offset calculation
ue->max_pos_iir += -round(sampleShift * PID_P) * 32768;
ue->max_pos_acc += max_pos;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT);
return sample_shift; return sample_shift;
} }
...@@ -29,9 +29,6 @@ ...@@ -29,9 +29,6 @@
* @{ * @{
*/ */
/*!\brief Timing drift hysterisis in samples*/
#define NR_SYNCH_HYST 1
/* A function to perform the channel estimation of DL PRS signal */ /* A function to perform the channel estimation of DL PRS signal */
int nr_prs_channel_estimation(uint8_t gNB_id, int nr_prs_channel_estimation(uint8_t gNB_id,
uint8_t rsc_id, uint8_t rsc_id,
......
...@@ -160,7 +160,6 @@ void rotate_cpx_vector(const c16_t *const x, const c16_t *const alpha, c16_t *y, ...@@ -160,7 +160,6 @@ void rotate_cpx_vector(const c16_t *const x, const c16_t *const alpha, c16_t *y,
int32_t *xd=(int32_t *)x; int32_t *xd=(int32_t *)x;
simde__m128i shift = simde_mm_cvtsi32_si128(output_shift); simde__m128i shift = simde_mm_cvtsi32_si128(output_shift);
register simd_q15_t m0,m1,m2,m3;
((int16_t *)&alpha_128)[0] = alpha->r; ((int16_t *)&alpha_128)[0] = alpha->r;
((int16_t *)&alpha_128)[1] = -alpha->i; ((int16_t *)&alpha_128)[1] = -alpha->i;
...@@ -174,17 +173,23 @@ void rotate_cpx_vector(const c16_t *const x, const c16_t *const alpha, c16_t *y, ...@@ -174,17 +173,23 @@ void rotate_cpx_vector(const c16_t *const x, const c16_t *const alpha, c16_t *y,
for(i=0; i<N>>2; i++) { for(i=0; i<N>>2; i++) {
m0 = simde_mm_setr_epi32(xd[0],xd[0],xd[1],xd[1]); y_128[i] = simde_mm_packs_epi32( // pack in 16bit integers with saturation [re im re im re im re im]
m1 = simde_mm_setr_epi32(xd[2],xd[2],xd[3],xd[3]); simde_mm_sra_epi32( // shift right by shift in order to compensate for the input amplitude
m2 = simde_mm_madd_epi16(m0,alpha_128); //complex multiply. result is 32bit [Re Im Re Im] simde_mm_madd_epi16( // complex multiply. result is 32bit [Re Im Re Im]
m3 = simde_mm_madd_epi16(m1,alpha_128); //complex multiply. result is 32bit [Re Im Re Im] simde_mm_setr_epi32( xd[0+i*4], xd[0+i*4], xd[1+i*4], xd[1+i*4]),
m2 = simde_mm_sra_epi32(m2,shift); // shift right by shift in order to compensate for the input amplitude alpha_128
m3 = simde_mm_sra_epi32(m3,shift); // shift right by shift in order to compensate for the input amplitude ),
shift
y_128[0] = simde_mm_packs_epi32(m2,m3); // pack in 16bit integers with saturation [re im re im re im re im] ),
simde_mm_sra_epi32( // shift right by shift in order to compensate for the input amplitude
simde_mm_madd_epi16( // complex multiply. result is 32bit [Re Im Re Im]
simde_mm_setr_epi32( xd[2+i*4], xd[2+i*4], xd[3+i*4], xd[3+i*4]),
alpha_128
),
shift
)
);
//print_ints("y_128[0]=", &y_128[0]); //print_ints("y_128[0]=", &y_128[0]);
xd+=4;
y_128+=1;
} }
#if defined(__x86__) || defined(__x86_64__) #if defined(__x86__) || defined(__x86_64__)
} }
......
...@@ -456,7 +456,8 @@ typedef struct PHY_VARS_NR_UE_s { ...@@ -456,7 +456,8 @@ typedef struct PHY_VARS_NR_UE_s {
/// temporary offset during cell search prior to MIB decoding /// temporary offset during cell search prior to MIB decoding
int ssb_offset; int ssb_offset;
uint16_t symbol_offset; /// offset in terms of symbols for detected ssb in sync uint16_t symbol_offset; /// offset in terms of symbols for detected ssb in sync
int64_t max_pos_avg; /// Timing offset IIR filter int64_t max_pos_iir; /// Timing offset IIR filter
int max_pos_acc; /// Timing offset accumuluated error for PI filter
/// Timing Advance updates variables /// Timing Advance updates variables
/// Timing advance update computed from the TA command signalled from gNB /// Timing advance update computed from the TA command signalled from gNB
......
...@@ -877,7 +877,7 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_ ...@@ -877,7 +877,7 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_
fapi_nr_config_request_t *cfg = &ue->nrUE_config; fapi_nr_config_request_t *cfg = &ue->nrUE_config;
NR_DL_FRAME_PARMS *fp = &ue->frame_parms; NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config; NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config;
int sampleShift = 0; int sampleShift = INT_MAX;
nr_ue_dlsch_init(phy_data->dlsch, NR_MAX_NB_LAYERS>4 ? 2:1, ue->max_ldpc_iterations); 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); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
......
...@@ -168,7 +168,7 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr ...@@ -168,7 +168,7 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr
int nr_slot_rx = proc->nr_slot_rx; int nr_slot_rx = proc->nr_slot_rx;
sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS; sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS;
NR_DL_FRAME_PARMS *fp = &sl_phy_params->sl_frame_params; NR_DL_FRAME_PARMS *fp = &sl_phy_params->sl_frame_params;
int sampleShift = 0; int sampleShift = INT_MAX;
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX_SL, VCD_FUNCTION_IN); // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX_SL, VCD_FUNCTION_IN);
start_meas(&sl_phy_params->phy_proc_sl_rx); start_meas(&sl_phy_params->phy_proc_sl_rx);
......
...@@ -128,6 +128,7 @@ void fill_channel_desc(channel_desc_t *chan_desc, ...@@ -128,6 +128,7 @@ void fill_channel_desc(channel_desc_t *chan_desc,
chan_desc->first_run = 1; chan_desc->first_run = 1;
chan_desc->ip = 0.0; chan_desc->ip = 0.0;
chan_desc->max_Doppler = max_Doppler; chan_desc->max_Doppler = max_Doppler;
chan_desc->Doppler_phase_cur = calloc(nb_rx, sizeof(double));
chan_desc->ch = calloc(nb_tx*nb_rx, sizeof(struct complexd *)); chan_desc->ch = calloc(nb_tx*nb_rx, sizeof(struct complexd *));
chan_desc->chF = calloc(nb_tx*nb_rx, sizeof(struct complexd *)); chan_desc->chF = calloc(nb_tx*nb_rx, sizeof(struct complexd *));
chan_desc->a = calloc(nb_taps, sizeof(struct complexd *)); chan_desc->a = calloc(nb_taps, sizeof(struct complexd *));
...@@ -1653,6 +1654,37 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, ...@@ -1653,6 +1654,37 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
0); 0);
break; break;
case SAT_LEO_TRANS:
case SAT_LEO_REGEN:
nb_taps = 1;
Td = 0;
channel_length = 1;
ricean_factor = 0.0;
aoa = 0.0;
maxDoppler = 0;
chan_desc->sat_height = 600e3;
chan_desc->enable_dynamic_delay = true;
chan_desc->enable_dynamic_Doppler = false; // TODO: requires UE to support continuous Doppler estimation, compensation and pre-compensation
fill_channel_desc(chan_desc,nb_tx,
nb_rx,
nb_taps,
channel_length,
default_amp_lin,
NULL,
NULL,
Td,
sampling_rate,
channel_bandwidth,
ricean_factor,
aoa,
forgetting_factor,
maxDoppler,
channel_offset,
path_loss_dB,
0);
printf("%s: satellite orbit height %f km\n", map_int_to_str(channelmod_names, channel_model), chan_desc->sat_height / 1000);
break;
default: default:
LOG_W(OCM,"channel model not yet supported\n"); LOG_W(OCM,"channel model not yet supported\n");
free(chan_desc); free(chan_desc);
...@@ -1711,6 +1743,7 @@ void free_channel_desc_scm(channel_desc_t *ch) { ...@@ -1711,6 +1743,7 @@ void free_channel_desc_scm(channel_desc_t *ch) {
free(ch->R_sqrt[i]); free(ch->R_sqrt[i]);
free(ch->R_sqrt); free(ch->R_sqrt);
free(ch->Doppler_phase_cur);
free(ch->ch); free(ch->ch);
free(ch->chF); free(ch->chF);
free(ch->a); free(ch->a);
...@@ -1743,9 +1776,9 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { ...@@ -1743,9 +1776,9 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) {
struct complexd phase, alpha, beta; struct complexd phase, alpha, beta;
start_meas(&desc->random_channel); start_meas(&desc->random_channel);
// For AWGN channel, the received signal (Srx) is equal to transmitted signal (Stx) plus noise (N), i.e., Srx = Stx + N, // For AWGN and SAT_LEO_* channels, the received signal (Srx) is equal to transmitted signal (Stx) plus noise (N), i.e., Srx = Stx + N,
// therefore, the channel matrix is the identity matrix. // therefore, the channel matrix is the identity matrix.
if (desc->modelid == AWGN) { if (desc->modelid == AWGN || desc->modelid == SAT_LEO_TRANS || desc->modelid == SAT_LEO_REGEN) {
for (aarx=0; aarx<desc->nb_rx; aarx++) { for (aarx=0; aarx<desc->nb_rx; aarx++) {
for (aatx = 0; aatx < desc->nb_tx; aatx++) { for (aatx = 0; aatx < desc->nb_tx; aatx++) {
desc->ch[aarx+(aatx*desc->nb_rx)][0].r = aarx%desc->nb_tx == aatx ? 1.0 : 0.0; desc->ch[aarx+(aatx*desc->nb_rx)][0].r = aarx%desc->nb_tx == aatx ? 1.0 : 0.0;
...@@ -2071,6 +2104,8 @@ static void display_channelmodel(channel_desc_t *cd,int debug, telnet_printfunc_ ...@@ -2071,6 +2104,8 @@ static void display_channelmodel(channel_desc_t *cd,int debug, telnet_printfunc_
cd->forgetting_factor); cd->forgetting_factor);
prnt("Initial phase: %lf nb_path: %i \n", prnt("Initial phase: %lf nb_path: %i \n",
cd->ip, cd->nb_paths); cd->ip, cd->nb_paths);
if (cd->modelid == SAT_LEO_TRANS || cd->modelid == SAT_LEO_REGEN)
prnt("satellite orbit height: %f\n", cd->sat_height);
for (int i=0; i<cd->nb_taps ; i++) { for (int i=0; i<cd->nb_taps ; i++) {
prnt("taps: %i lin. ampli. : %lf delay: %lf \n",i,cd->amps[i], cd->delays[i]); prnt("taps: %i lin. ampli. : %lf delay: %lf \n",i,cd->amps[i], cd->delays[i]);
...@@ -2281,7 +2316,7 @@ void init_channelmod(void) { ...@@ -2281,7 +2316,7 @@ void init_channelmod(void) {
} /* init_channelmod */ } /* init_channelmod */
int load_channellist(uint8_t nb_tx, uint8_t nb_rx, double sampling_rate, double channel_bandwidth) { int load_channellist(uint8_t nb_tx, uint8_t nb_rx, double sampling_rate, uint64_t center_freq, double channel_bandwidth) {
paramdef_t achannel_params[] = CHANNELMOD_MODEL_PARAMS_DESC; paramdef_t achannel_params[] = CHANNELMOD_MODEL_PARAMS_DESC;
paramlist_def_t channel_list; paramlist_def_t channel_list;
memset(&channel_list,0,sizeof(paramlist_def_t)); memset(&channel_list,0,sizeof(paramlist_def_t));
...@@ -2314,7 +2349,7 @@ int load_channellist(uint8_t nb_tx, uint8_t nb_rx, double sampling_rate, double ...@@ -2314,7 +2349,7 @@ int load_channellist(uint8_t nb_tx, uint8_t nb_rx, double sampling_rate, double
nb_rx, nb_rx,
modid, modid,
sampling_rate, sampling_rate,
0, center_freq,
channel_bandwidth, channel_bandwidth,
*(channel_list.paramarray[i][pindex_DT].dblptr), *(channel_list.paramarray[i][pindex_DT].dblptr),
0.0, 0.0,
......
...@@ -126,6 +126,18 @@ typedef struct { ...@@ -126,6 +126,18 @@ typedef struct {
char *model_name; char *model_name;
/// flags to properly trigger memory free /// flags to properly trigger memory free
unsigned int free_flags; unsigned int free_flags;
/// time stamp when the time varying channel emulation starts (when client connected)
uint64_t start_TS;
/// height of LEO satellite
float sat_height;
/// flag to enable dynamic delay simulation for LEO satellite
bool enable_dynamic_delay;
/// flag to enable dynamic Doppler simulation for LEO satellite
bool enable_dynamic_Doppler;
/// Doppler phase increment (might vary over time, e.g. for LEO satellite)
float Doppler_phase_inc;
/// current Doppler phase of each RX antenna (for continuous phase from one block to the next)
float *Doppler_phase_cur;
} channel_desc_t; } channel_desc_t;
typedef struct { typedef struct {
...@@ -218,6 +230,8 @@ typedef enum { ...@@ -218,6 +230,8 @@ typedef enum {
EPA_low, EPA_low,
EPA_medium, EPA_medium,
EPA_high, EPA_high,
SAT_LEO_TRANS,
SAT_LEO_REGEN,
} SCM_t; } SCM_t;
#define CHANNELMOD_MAP_INIT \ #define CHANNELMOD_MAP_INIT \
{"custom",custom},\ {"custom",custom},\
...@@ -253,6 +267,8 @@ typedef enum { ...@@ -253,6 +267,8 @@ typedef enum {
{"EPA_low",EPA_low},\ {"EPA_low",EPA_low},\
{"EPA_medium",EPA_medium},\ {"EPA_medium",EPA_medium},\
{"EPA_high",EPA_high},\ {"EPA_high",EPA_high},\
{"SAT_LEO_TRANS",SAT_LEO_TRANS},\
{"SAT_LEO_REGEN",SAT_LEO_REGEN},\
{NULL, -1} {NULL, -1}
#define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\n" #define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\n"
...@@ -543,7 +559,7 @@ int modelid_fromstrtype(char *modeltype); ...@@ -543,7 +559,7 @@ int modelid_fromstrtype(char *modeltype);
double channelmod_get_snr_dB(void); double channelmod_get_snr_dB(void);
double channelmod_get_sinr_dB(void); double channelmod_get_sinr_dB(void);
void init_channelmod(void) ; void init_channelmod(void) ;
int load_channellist(uint8_t nb_tx, uint8_t nb_rx, double sampling_rate, double channel_bandwidth) ; int load_channellist(uint8_t nb_tx, uint8_t nb_rx, double sampling_rate, uint64_t center_freq, double channel_bandwidth) ;
double N_RB2sampling_rate(uint16_t N_RB); double N_RB2sampling_rate(uint16_t N_RB);
double N_RB2channel_bandwidth(uint16_t N_RB); double N_RB2channel_bandwidth(uint16_t N_RB);
......
...@@ -120,9 +120,9 @@ typedef struct sl_bch_params { ...@@ -120,9 +120,9 @@ typedef struct sl_bch_params {
//configured from RRC //configured from RRC
//Parameters used to determine PSBCH slot //Parameters used to determine PSBCH slot
sl_ssb_timealloc_t ssb_time_alloc; sl_ssb_timealloc_t ssb_time_alloc;
uint8_t sl_mib[4] __attribute__((aligned(4)));
uint16_t slss_id; uint16_t slss_id;
bool status; bool status;
uint8_t sl_mib[4];
//Parameters incremented by MAC PSBCH scheduler //Parameters incremented by MAC PSBCH scheduler
//after every SSB txn/reception //after every SSB txn/reception
......
...@@ -88,7 +88,7 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac) ...@@ -88,7 +88,7 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac)
// Fake SIB19 reception for NTN // Fake SIB19 reception for NTN
// TODO: remove this and implement the actual SIB19 reception instead! // TODO: remove this and implement the actual SIB19 reception instead!
if (get_nrUE_params()->ntn_koffset || get_nrUE_params()->ntn_ta_common) { if (get_nrUE_params()->ntn_koffset || get_nrUE_params()->ntn_ta_common || get_nrUE_params()->ntn_ta_commondrift) {
NR_SIB19_r17_t *sib19_r17 = calloc(1, sizeof(*sib19_r17)); NR_SIB19_r17_t *sib19_r17 = calloc(1, sizeof(*sib19_r17));
sib19_r17->ntn_Config_r17 = calloc(1, sizeof(*sib19_r17->ntn_Config_r17)); sib19_r17->ntn_Config_r17 = calloc(1, sizeof(*sib19_r17->ntn_Config_r17));
...@@ -98,9 +98,11 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac) ...@@ -98,9 +98,11 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac)
} }
// NTN ta-Common-r17 // NTN ta-Common-r17
if (get_nrUE_params()->ntn_ta_common) { if (get_nrUE_params()->ntn_ta_common || get_nrUE_params()->ntn_ta_commondrift) {
sib19_r17->ntn_Config_r17->ta_Info_r17 = calloc(1, sizeof(*sib19_r17->ntn_Config_r17->ta_Info_r17)); sib19_r17->ntn_Config_r17->ta_Info_r17 = calloc(1, sizeof(*sib19_r17->ntn_Config_r17->ta_Info_r17));
sib19_r17->ntn_Config_r17->ta_Info_r17->ta_Common_r17 = get_nrUE_params()->ntn_ta_common / 4.072e-6; // ta-Common-r17 is in units of 4.072e-3 µs, ntn_ta_common is in ms sib19_r17->ntn_Config_r17->ta_Info_r17->ta_Common_r17 = get_nrUE_params()->ntn_ta_common / 4.072e-6; // ta-Common-r17 is in units of 4.072e-3 µs, ntn_ta_common is in ms
if (get_nrUE_params()->ntn_ta_commondrift)
asn1cCallocOne(sib19_r17->ntn_Config_r17->ta_Info_r17->ta_CommonDrift_r17, get_nrUE_params()->ntn_ta_commondrift / 0.2e-3); // is in units of 0.2e-3 µs/s, ntn_ta_commondrift is in µs/s
} }
nr_rrc_mac_config_req_sib19_r17(mac->ue_id, sib19_r17); nr_rrc_mac_config_req_sib19_r17(mac->ue_id, sib19_r17);
......
...@@ -188,7 +188,7 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc, ...@@ -188,7 +188,7 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc,
if (ie->nonCriticalExtension->dedicatedNAS_MessageList) { if (ie->nonCriticalExtension->dedicatedNAS_MessageList) {
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *tmp = ext->dedicatedNAS_MessageList; struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *tmp = ext->dedicatedNAS_MessageList;
for (int i = 0; i < tmp->list.count; i++) { for (int i = 0; i < tmp->list.count; i++) {
MessageDef *ittiMsg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_ESTABLI_CNF); MessageDef *ittiMsg = itti_alloc_new_message(TASK_RRC_NRUE, rrc->ue_id, NAS_CONN_ESTABLI_CNF);
NasConnEstabCnf *msg = &NAS_CONN_ESTABLI_CNF(ittiMsg); NasConnEstabCnf *msg = &NAS_CONN_ESTABLI_CNF(ittiMsg);
msg->errCode = AS_SUCCESS; msg->errCode = AS_SUCCESS;
msg->nasMsg.length = tmp->list.array[i]->size; msg->nasMsg.length = tmp->list.array[i]->size;
...@@ -700,8 +700,7 @@ static void nr_rrc_ue_prepare_RRCSetupRequest(NR_UE_RRC_INST_t *rrc) ...@@ -700,8 +700,7 @@ static void nr_rrc_ue_prepare_RRCSetupRequest(NR_UE_RRC_INST_t *rrc)
nr_rlc_srb_recv_sdu(rrc->ue_id, 0, buf, len); nr_rlc_srb_recv_sdu(rrc->ue_id, 0, buf, len);
} }
void nr_rrc_configure_default_SI(NR_UE_RRC_SI_INFO *SI_info, static void nr_rrc_configure_default_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SIB1_t *sib1)
NR_SIB1_t *sib1)
{ {
struct NR_SI_SchedulingInfo *si_SchedulingInfo = sib1->si_SchedulingInfo; struct NR_SI_SchedulingInfo *si_SchedulingInfo = sib1->si_SchedulingInfo;
if (!si_SchedulingInfo) if (!si_SchedulingInfo)
...@@ -751,11 +750,7 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc, ...@@ -751,11 +750,7 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc,
switch (bcch_message->message.choice.c1->present) { switch (bcch_message->message.choice.c1->present) {
case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1: case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1:
LOG_D(NR_RRC, "[UE %ld] Decoding SIB1\n", rrc->ue_id); LOG_D(NR_RRC, "[UE %ld] Decoding SIB1\n", rrc->ue_id);
asn1cFreeStruc(asn_DEF_NR_SIB1, SI_info->sib1); UPDATE_IE(SI_info->sib1, bcch_message->message.choice.c1->choice.systemInformationBlockType1, NR_SIB1_t);
NR_SIB1_t *sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1;
if(!SI_info->sib1)
SI_info->sib1 = calloc(1, sizeof(*SI_info->sib1));
memcpy(SI_info->sib1, sib1, sizeof(NR_SIB1_t));
if(g_log->log_component[NR_RRC].level >= OAILOG_DEBUG) if(g_log->log_component[NR_RRC].level >= OAILOG_DEBUG)
xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void *) SI_info->sib1); xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void *) SI_info->sib1);
LOG_A(NR_RRC, "SIB1 decoded\n"); LOG_A(NR_RRC, "SIB1 decoded\n");
...@@ -766,10 +761,10 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc, ...@@ -766,10 +761,10 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc,
nr_rrc_ue_prepare_RRCSetupRequest(rrc); nr_rrc_ue_prepare_RRCSetupRequest(rrc);
} }
// configure default SI // configure default SI
nr_rrc_configure_default_SI(SI_info, sib1); nr_rrc_configure_default_SI(SI_info, SI_info->sib1);
// configure timers and constant // configure timers and constant
nr_rrc_set_sib1_timers_and_constants(&rrc->timers_and_constants, sib1); nr_rrc_set_sib1_timers_and_constants(&rrc->timers_and_constants, SI_info->sib1);
nr_rrc_mac_config_req_sib1(rrc->ue_id, 0, sib1->si_SchedulingInfo, sib1->servingCellConfigCommon); nr_rrc_mac_config_req_sib1(rrc->ue_id, 0, SI_info->sib1->si_SchedulingInfo, SI_info->sib1->servingCellConfigCommon);
break; break;
case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation: case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation:
LOG_I(NR_RRC, "[UE %ld] Decoding SI\n", rrc->ue_id); LOG_I(NR_RRC, "[UE %ld] Decoding SI\n", rrc->ue_id);
...@@ -1663,7 +1658,7 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc, ...@@ -1663,7 +1658,7 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc,
NR_DedicatedNAS_Message_t *dedicatedNAS_Message = NR_DedicatedNAS_Message_t *dedicatedNAS_Message =
dlInformationTransfer->criticalExtensions.choice.dlInformationTransfer->dedicatedNAS_Message; dlInformationTransfer->criticalExtensions.choice.dlInformationTransfer->dedicatedNAS_Message;
MessageDef *ittiMsg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_DOWNLINK_DATA_IND); MessageDef *ittiMsg = itti_alloc_new_message(TASK_RRC_NRUE, rrc->ue_id, NAS_DOWNLINK_DATA_IND);
NasDlDataInd *msg = &NAS_DOWNLINK_DATA_IND(ittiMsg); NasDlDataInd *msg = &NAS_DOWNLINK_DATA_IND(ittiMsg);
msg->UEid = rrc->ue_id; msg->UEid = rrc->ue_id;
msg->nasMsg.length = dedicatedNAS_Message->size; msg->nasMsg.length = dedicatedNAS_Message->size;
...@@ -2315,7 +2310,7 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc, ...@@ -2315,7 +2310,7 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc,
rrc->rnti = 0; rrc->rnti = 0;
// Indicate the release of the RRC connection to upper layers // Indicate the release of the RRC connection to upper layers
MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_NAS_CONN_RELEASE_IND); MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_NRUE, rrc->ue_id, NR_NAS_CONN_RELEASE_IND);
NR_NAS_CONN_RELEASE_IND(msg_p).cause = release_cause; NR_NAS_CONN_RELEASE_IND(msg_p).cause = release_cause;
itti_send_msg_to_task(TASK_NAS_NRUE, rrc->ue_id, msg_p); itti_send_msg_to_task(TASK_NAS_NRUE, rrc->ue_id, msg_p);
} }
......
...@@ -25,23 +25,37 @@ ...@@ -25,23 +25,37 @@
#include <arpa/inet.h> // htonl, htons #include <arpa/inet.h> // htonl, htons
#define ENCODE_U8(buffer, value, size) \ #define ENCODE_U8(buffer, value, size) \
do { \
*(uint8_t*)(buffer) = value; \ *(uint8_t*)(buffer) = value; \
size += sizeof(uint8_t) size += sizeof(uint8_t); \
} while (0)
/* Safely encodes a 16-bit value into a buffer, handling
misalignment by memcpy 2 bytes to buffer in network
byte order (big-endian). */
#define ENCODE_U16(buffer, value, size) \ #define ENCODE_U16(buffer, value, size) \
*(uint16_t*)(buffer) = htons(value); \ do { \
size += sizeof(uint16_t) uint16_t _val = htons(value); \
memcpy((buffer), &_val, sizeof(uint16_t)); \
size += sizeof(uint16_t); \
} while (0)
/* Safely encodes a 24-bit value into a buffer, handling
misalignment by using htonl and memcpy to copy 3 bytes
in network byte order (big-endian). */
#define ENCODE_U24(buffer, value, size) \ #define ENCODE_U24(buffer, value, size) \
*(uint32_t*)(buffer) = htonl(value); \ do { \
size += sizeof(uint8_t) + sizeof(uint16_t) uint32_t _val = htonl(value); \
memcpy((buffer), ((uint8_t*)&_val) + 1, 3); \
size += sizeof(uint8_t) + sizeof(uint16_t); \
} while (0)
#define ENCODE_U32(buffer, value, size) \ #define ENCODE_U32(buffer, value, size) \
{ \ do { \
uint32_t tmp = htonl(value); \ uint32_t tmp = htonl(value); \
memcpy(buffer, &tmp, sizeof(tmp)); \ memcpy(buffer, &tmp, sizeof(tmp)); \
} \ size += sizeof(uint32_t); \
size += sizeof(uint32_t) } while (0)
#define IES_ENCODE_U8(buffer, encoded, value) \ #define IES_ENCODE_U8(buffer, encoded, value) \
ENCODE_U8(buffer + encoded, value, encoded) ENCODE_U8(buffer + encoded, value, encoded)
......
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
* 2023.01.27 Vladimir Dorovskikh 16 digits IMEISV * 2023.01.27 Vladimir Dorovskikh 16 digits IMEISV
*/ */
#include <string.h> // memset #include <string.h> // memset
#include <stdlib.h> // malloc, free #include <stdlib.h> // malloc, free
...@@ -52,8 +51,10 @@ ...@@ -52,8 +51,10 @@
#include "openair3/SECU/nas_stream_eia2.h" #include "openair3/SECU/nas_stream_eia2.h"
#include "openair3/UTILS/conversions.h" #include "openair3/UTILS/conversions.h"
#define MAX_NAS_UE 4
extern uint16_t NB_UE_INST; extern uint16_t NB_UE_INST;
static nr_ue_nas_t nr_ue_nas = {0}; static nr_ue_nas_t nr_ue_nas[MAX_NAS_UE] = {0};
static nr_nas_msg_snssai_t nas_allowed_nssai[8]; static nr_nas_msg_snssai_t nas_allowed_nssai[8];
typedef enum { typedef enum {
...@@ -129,10 +130,7 @@ security_state_t nas_security_rx_process(nr_ue_nas_t *nas, uint8_t *pdu_buffer, ...@@ -129,10 +130,7 @@ security_state_t nas_security_rx_process(nr_ue_nas_t *nas, uint8_t *pdu_buffer,
return NAS_SECURITY_INTEGRITY_PASSED; return NAS_SECURITY_INTEGRITY_PASSED;
} }
static int nas_protected_security_header_encode( static int nas_protected_security_header_encode(char *buffer, const fgs_nas_message_security_header_t *header, int length)
char *buffer,
const fgs_nas_message_security_header_t *header,
int length)
{ {
LOG_FUNC_IN; LOG_FUNC_IN;
...@@ -142,18 +140,18 @@ static int nas_protected_security_header_encode( ...@@ -142,18 +140,18 @@ static int nas_protected_security_header_encode(
ENCODE_U8(buffer, header->protocol_discriminator, size); ENCODE_U8(buffer, header->protocol_discriminator, size);
/* Encode the security header type */ /* Encode the security header type */
ENCODE_U8(buffer+size, (header->security_header_type & 0xf), size); ENCODE_U8(buffer + size, (header->security_header_type & 0xf), size);
/* Encode the message authentication code */ /* Encode the message authentication code */
ENCODE_U32(buffer+size, header->message_authentication_code, size); ENCODE_U32(buffer + size, header->message_authentication_code, size);
/* Encode the sequence number */ /* Encode the sequence number */
ENCODE_U8(buffer+size, header->sequence_number, size); ENCODE_U8(buffer + size, header->sequence_number, size);
LOG_FUNC_RETURN (size); LOG_FUNC_RETURN(size);
} }
static int _nas_mm_msg_encode_header(const mm_msg_header_t *header, static int _nas_mm_msg_encode_header(const mm_msg_header_t *header, uint8_t *buffer, uint32_t len)
uint8_t *buffer, uint32_t len) { {
int size = 0; int size = 0;
/* Check the buffer length */ /* Check the buffer length */
...@@ -163,8 +161,7 @@ static int _nas_mm_msg_encode_header(const mm_msg_header_t *header, ...@@ -163,8 +161,7 @@ static int _nas_mm_msg_encode_header(const mm_msg_header_t *header,
/* Check the protocol discriminator */ /* Check the protocol discriminator */
if (header->ex_protocol_discriminator != FGS_MOBILITY_MANAGEMENT_MESSAGE) { if (header->ex_protocol_discriminator != FGS_MOBILITY_MANAGEMENT_MESSAGE) {
LOG_TRACE(ERROR, "ESM-MSG - Unexpected extened protocol discriminator: 0x%x", LOG_TRACE(ERROR, "ESM-MSG - Unexpected extened protocol discriminator: 0x%x", header->ex_protocol_discriminator);
header->ex_protocol_discriminator);
return (TLV_ENCODE_PROTOCOL_NOT_SUPPORTED); return (TLV_ENCODE_PROTOCOL_NOT_SUPPORTED);
} }
...@@ -199,7 +196,7 @@ static int fill_guti(FGSMobileIdentity *mi, const Guti5GSMobileIdentity_t *guti) ...@@ -199,7 +196,7 @@ static int fill_guti(FGSMobileIdentity *mi, const Guti5GSMobileIdentity_t *guti)
static int fill_imeisv(FGSMobileIdentity *mi, const uicc_t *uicc) static int fill_imeisv(FGSMobileIdentity *mi, const uicc_t *uicc)
{ {
int i=0; int i = 0;
mi->imeisv.typeofidentity = FGS_MOBILE_IDENTITY_IMEISV; mi->imeisv.typeofidentity = FGS_MOBILE_IDENTITY_IMEISV;
mi->imeisv.digittac01 = getImeisvDigit(uicc, i++); mi->imeisv.digittac01 = getImeisvDigit(uicc, i++);
mi->imeisv.digittac02 = getImeisvDigit(uicc, i++); mi->imeisv.digittac02 = getImeisvDigit(uicc, i++);
...@@ -222,26 +219,28 @@ static int fill_imeisv(FGSMobileIdentity *mi, const uicc_t *uicc) ...@@ -222,26 +219,28 @@ static int fill_imeisv(FGSMobileIdentity *mi, const uicc_t *uicc)
return 19; return 19;
} }
int mm_msg_encode(MM_msg *mm_msg, uint8_t *buffer, uint32_t len) { int mm_msg_encode(MM_msg *mm_msg, uint8_t *buffer, uint32_t len)
{
LOG_FUNC_IN; LOG_FUNC_IN;
int header_result; int header_result;
int encode_result; int encode_result;
uint8_t msg_type = mm_msg->header.message_type; uint8_t msg_type = mm_msg->header.message_type;
/* First encode the EMM message header */ /* First encode the EMM message header */
header_result = _nas_mm_msg_encode_header(&mm_msg->header, buffer, len); header_result = _nas_mm_msg_encode_header(&mm_msg->header, buffer, len);
if (header_result < 0) { if (header_result < 0) {
LOG_TRACE(ERROR, "EMM-MSG - Failed to encode EMM message header " LOG_TRACE(ERROR,
"(%d)", header_result); "EMM-MSG - Failed to encode EMM message header "
"(%d)",
header_result);
LOG_FUNC_RETURN(header_result); LOG_FUNC_RETURN(header_result);
} }
buffer += header_result; buffer += header_result;
len -= header_result; len -= header_result;
switch(msg_type) { switch (msg_type) {
case REGISTRATION_REQUEST: case REGISTRATION_REQUEST:
encode_result = encode_registration_request(&mm_msg->registration_request, buffer, len); encode_result = encode_registration_request(&mm_msg->registration_request, buffer, len);
break; break;
...@@ -258,32 +257,36 @@ int mm_msg_encode(MM_msg *mm_msg, uint8_t *buffer, uint32_t len) { ...@@ -258,32 +257,36 @@ int mm_msg_encode(MM_msg *mm_msg, uint8_t *buffer, uint32_t len) {
encode_result = encode_fgs_uplink_nas_transport(&mm_msg->uplink_nas_transport, buffer, len); encode_result = encode_fgs_uplink_nas_transport(&mm_msg->uplink_nas_transport, buffer, len);
break; break;
case FGS_DEREGISTRATION_REQUEST_UE_ORIGINATING: case FGS_DEREGISTRATION_REQUEST_UE_ORIGINATING:
encode_result = encode_fgs_deregistration_request_ue_originating(&mm_msg->fgs_deregistration_request_ue_originating, buffer, len); encode_result =
encode_fgs_deregistration_request_ue_originating(&mm_msg->fgs_deregistration_request_ue_originating, buffer, len);
break; break;
default: default:
LOG_TRACE(ERROR, "EMM-MSG - Unexpected message type: 0x%x", LOG_TRACE(ERROR, "EMM-MSG - Unexpected message type: 0x%x", mm_msg->header.message_type);
mm_msg->header.message_type);
encode_result = TLV_ENCODE_WRONG_MESSAGE_TYPE; encode_result = TLV_ENCODE_WRONG_MESSAGE_TYPE;
break; break;
/* TODO: Handle not standard layer 3 messages: SERVICE_REQUEST */ /* TODO: Handle not standard layer 3 messages: SERVICE_REQUEST */
} }
if (encode_result < 0) { if (encode_result < 0) {
LOG_TRACE(ERROR, "EMM-MSG - Failed to encode L3 EMM message 0x%x " LOG_TRACE(ERROR,
"(%d)", mm_msg->header.message_type, encode_result); "EMM-MSG - Failed to encode L3 EMM message 0x%x "
"(%d)",
mm_msg->header.message_type,
encode_result);
} }
if (encode_result < 0) if (encode_result < 0)
LOG_FUNC_RETURN (encode_result); LOG_FUNC_RETURN(encode_result);
LOG_FUNC_RETURN (header_result + encode_result); LOG_FUNC_RETURN(header_result + encode_result);
} }
void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16], uint8_t *output, uicc_t* uicc) { void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16], uint8_t *output, uicc_t *uicc)
uint8_t S[100]={0}; {
uint8_t S[100] = {0};
S[0] = 0x6B; S[0] = 0x6B;
servingNetworkName (S+1, uicc->imsiStr, uicc->nmc_size); servingNetworkName(S + 1, uicc->imsiStr, uicc->nmc_size);
int netNamesize = strlen((char*)S+1); int netNamesize = strlen((char *)S + 1);
S[1 + netNamesize] = (netNamesize & 0xff00) >> 8; S[1 + netNamesize] = (netNamesize & 0xff00) >> 8;
S[2 + netNamesize] = (netNamesize & 0x00ff); S[2 + netNamesize] = (netNamesize & 0x00ff);
for (int i = 0; i < 16; i++) for (int i = 0; i < 16; i++)
...@@ -295,7 +298,7 @@ void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16 ...@@ -295,7 +298,7 @@ void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16
S[29 + netNamesize] = 0x00; S[29 + netNamesize] = 0x00;
S[30 + netNamesize] = 0x08; S[30 + netNamesize] = 0x08;
uint8_t plmn[3] = { 0x02, 0xf8, 0x39 }; uint8_t plmn[3] = {0x02, 0xf8, 0x39};
uint8_t oldS[100]; uint8_t oldS[100];
oldS[0] = 0x6B; oldS[0] = 0x6B;
memcpy(&oldS[1], plmn, 3); memcpy(&oldS[1], plmn, 3);
...@@ -310,10 +313,9 @@ void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16 ...@@ -310,10 +313,9 @@ void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16
oldS[32] = 0x00; oldS[32] = 0x00;
oldS[33] = 0x08; oldS[33] = 0x08;
uint8_t key[32] = {0}; uint8_t key[32] = {0};
memcpy(&key[0], ck, 16); memcpy(&key[0], ck, 16);
memcpy(&key[16], ik, 16); //KEY memcpy(&key[16], ik, 16); // KEY
uint8_t out[32] = {0}; uint8_t out[32] = {0};
byte_array_t data = {.buf = S, .len = 31 + netNamesize}; byte_array_t data = {.buf = S, .len = 31 + netNamesize};
...@@ -322,15 +324,16 @@ void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16 ...@@ -322,15 +324,16 @@ void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16
memcpy(output, out + 16, 16); memcpy(output, out + 16, 16);
} }
void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[32], uicc_t *uicc) { void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[32], uicc_t *uicc)
uint8_t S[100]={0}; {
uint8_t S[100] = {0};
uint8_t key[32] = {0}; uint8_t key[32] = {0};
memcpy(&key[0], ck, 16); memcpy(&key[0], ck, 16);
memcpy(&key[16], ik, 16); //KEY memcpy(&key[16], ik, 16); // KEY
S[0] = 0x6A; S[0] = 0x6A;
servingNetworkName (S+1, uicc->imsiStr, uicc->nmc_size); servingNetworkName(S + 1, uicc->imsiStr, uicc->nmc_size);
int netNamesize = strlen((char*)S+1); int netNamesize = strlen((char *)S + 1);
S[1 + netNamesize] = (uint8_t)((netNamesize & 0xff00) >> 8); S[1 + netNamesize] = (uint8_t)((netNamesize & 0xff00) >> 8);
S[2 + netNamesize] = (uint8_t)(netNamesize & 0x00ff); S[2 + netNamesize] = (uint8_t)(netNamesize & 0x00ff);
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
...@@ -343,23 +346,25 @@ void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[ ...@@ -343,23 +346,25 @@ void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[
kdf(key, data, 32, kausf); kdf(key, data, 32, kausf);
} }
void derive_kseaf(uint8_t kausf[32], uint8_t kseaf[32], uicc_t *uicc) { void derive_kseaf(uint8_t kausf[32], uint8_t kseaf[32], uicc_t *uicc)
uint8_t S[100]={0}; {
S[0] = 0x6C; //FC uint8_t S[100] = {0};
servingNetworkName (S+1, uicc->imsiStr, uicc->nmc_size); S[0] = 0x6C; // FC
int netNamesize = strlen((char*)S+1); servingNetworkName(S + 1, uicc->imsiStr, uicc->nmc_size);
int netNamesize = strlen((char *)S + 1);
S[1 + netNamesize] = (uint8_t)((netNamesize & 0xff00) >> 8); S[1 + netNamesize] = (uint8_t)((netNamesize & 0xff00) >> 8);
S[2 + netNamesize] = (uint8_t)(netNamesize & 0x00ff); S[2 + netNamesize] = (uint8_t)(netNamesize & 0x00ff);
byte_array_t data = {.buf = S , .len = 3 + netNamesize}; byte_array_t data = {.buf = S, .len = 3 + netNamesize};
kdf(kausf, data, 32, kseaf); kdf(kausf, data, 32, kseaf);
} }
void derive_kamf(uint8_t *kseaf, uint8_t *kamf, uint16_t abba, uicc_t* uicc) { void derive_kamf(uint8_t *kseaf, uint8_t *kamf, uint16_t abba, uicc_t *uicc)
{
int imsiLen = strlen(uicc->imsiStr); int imsiLen = strlen(uicc->imsiStr);
uint8_t S[100] = {0}; uint8_t S[100] = {0};
S[0] = 0x6D; //FC = 0x6D S[0] = 0x6D; // FC = 0x6D
memcpy(&S[1], uicc->imsiStr, imsiLen ); memcpy(&S[1], uicc->imsiStr, imsiLen);
S[1 + imsiLen] = (uint8_t)((imsiLen & 0xff00) >> 8); S[1 + imsiLen] = (uint8_t)((imsiLen & 0xff00) >> 8);
S[2 + imsiLen] = (uint8_t)(imsiLen & 0x00ff); S[2 + imsiLen] = (uint8_t)(imsiLen & 0x00ff);
S[3 + imsiLen] = abba & 0x00ff; S[3 + imsiLen] = abba & 0x00ff;
...@@ -375,8 +380,8 @@ void derive_kamf(uint8_t *kseaf, uint8_t *kamf, uint16_t abba, uicc_t* uicc) { ...@@ -375,8 +380,8 @@ void derive_kamf(uint8_t *kseaf, uint8_t *kamf, uint16_t abba, uicc_t* uicc) {
void derive_knas(algorithm_type_dist_t nas_alg_type, uint8_t nas_alg_id, uint8_t kamf[32], uint8_t *knas) void derive_knas(algorithm_type_dist_t nas_alg_type, uint8_t nas_alg_id, uint8_t kamf[32], uint8_t *knas)
{ {
uint8_t S[20] = {0}; uint8_t S[20] = {0};
uint8_t out[32] = { 0 }; uint8_t out[32] = {0};
S[0] = 0x69; //FC S[0] = 0x69; // FC
S[1] = (uint8_t)(nas_alg_type & 0xFF); S[1] = (uint8_t)(nas_alg_type & 0xFF);
S[2] = 0x00; S[2] = 0x00;
S[3] = 0x01; S[3] = 0x01;
...@@ -387,10 +392,11 @@ void derive_knas(algorithm_type_dist_t nas_alg_type, uint8_t nas_alg_id, uint8_t ...@@ -387,10 +392,11 @@ void derive_knas(algorithm_type_dist_t nas_alg_type, uint8_t nas_alg_id, uint8_t
byte_array_t data = {.buf = S, .len = 7}; byte_array_t data = {.buf = S, .len = 7};
kdf(kamf, data, 32, out); kdf(kamf, data, 32, out);
memcpy(knas, out+16, 16); memcpy(knas, out + 16, 16);
} }
void derive_kgnb(uint8_t kamf[32], uint32_t count, uint8_t *kgnb){ void derive_kgnb(uint8_t kamf[32], uint32_t count, uint8_t *kgnb)
{
/* Compute the KDF input parameter /* Compute the KDF input parameter
* S = FC(0x6E) || UL NAS Count || 0x00 0x04 || 0x01 || 0x00 0x01 * S = FC(0x6E) || UL NAS Count || 0x00 0x04 || 0x01 || 0x00 0x01
*/ */
...@@ -419,12 +425,13 @@ void derive_kgnb(uint8_t kamf[32], uint32_t count, uint8_t *kgnb){ ...@@ -419,12 +425,13 @@ void derive_kgnb(uint8_t kamf[32], uint32_t count, uint8_t *kgnb){
kdf(kamf, data, 32, kgnb); kdf(kamf, data, 32, kgnb);
printf("kgnb : "); printf("kgnb : ");
for(int pp=0;pp<32;pp++) for (int pp = 0; pp < 32; pp++)
printf("%02x ",kgnb[pp]); printf("%02x ", kgnb[pp]);
printf("\n"); printf("\n");
} }
void derive_ue_keys(uint8_t *buf, nr_ue_nas_t *nas) { void derive_ue_keys(uint8_t *buf, nr_ue_nas_t *nas)
{
uint8_t ak[6]; uint8_t ak[6];
uint8_t sqn[6]; uint8_t sqn[6];
...@@ -437,8 +444,8 @@ void derive_ue_keys(uint8_t *buf, nr_ue_nas_t *nas) { ...@@ -437,8 +444,8 @@ void derive_ue_keys(uint8_t *buf, nr_ue_nas_t *nas) {
uint8_t *kgnb = nas->security.kgnb; uint8_t *kgnb = nas->security.kgnb;
// get RAND for authentication request // get RAND for authentication request
for(int index = 0; index < 16;index++){ for (int index = 0; index < 16; index++) {
rand[index] = buf[8+index]; rand[index] = buf[8 + index];
} }
uint8_t resTemp[16]; uint8_t resTemp[16];
...@@ -447,30 +454,30 @@ void derive_ue_keys(uint8_t *buf, nr_ue_nas_t *nas) { ...@@ -447,30 +454,30 @@ void derive_ue_keys(uint8_t *buf, nr_ue_nas_t *nas) {
transferRES(ck, ik, resTemp, rand, output, nas->uicc); transferRES(ck, ik, resTemp, rand, output, nas->uicc);
for(int index = 0; index < 6; index++){ for (int index = 0; index < 6; index++) {
sqn[index] = buf[26+index]; sqn[index] = buf[26 + index];
} }
derive_kausf(ck, ik, sqn, kausf, nas->uicc); derive_kausf(ck, ik, sqn, kausf, nas->uicc);
derive_kseaf(kausf, kseaf, nas->uicc); derive_kseaf(kausf, kseaf, nas->uicc);
derive_kamf(kseaf, kamf, 0x0000, nas->uicc); derive_kamf(kseaf, kamf, 0x0000, nas->uicc);
derive_kgnb(kamf,0,kgnb); derive_kgnb(kamf, 0, kgnb);
printf("kausf:"); printf("kausf:");
for(int i = 0; i < 32; i++){ for (int i = 0; i < 32; i++) {
printf("%x ", kausf[i]); printf("%x ", kausf[i]);
} }
printf("\n"); printf("\n");
printf("kseaf:"); printf("kseaf:");
for(int i = 0; i < 32; i++){ for (int i = 0; i < 32; i++) {
printf("%x ", kseaf[i]); printf("%x ", kseaf[i]);
} }
printf("\n"); printf("\n");
printf("kamf:"); printf("kamf:");
for(int i = 0; i < 32; i++){ for (int i = 0; i < 32; i++) {
printf("%x ", kamf[i]); printf("%x ", kamf[i]);
} }
printf("\n"); printf("\n");
...@@ -478,16 +485,18 @@ void derive_ue_keys(uint8_t *buf, nr_ue_nas_t *nas) { ...@@ -478,16 +485,18 @@ void derive_ue_keys(uint8_t *buf, nr_ue_nas_t *nas) {
nr_ue_nas_t *get_ue_nas_info(module_id_t module_id) nr_ue_nas_t *get_ue_nas_info(module_id_t module_id)
{ {
DevAssert(module_id == 0); DevAssert(module_id < MAX_NAS_UE);
if (!nr_ue_nas.uicc) if (!nr_ue_nas[module_id].uicc) {
nr_ue_nas.uicc = checkUicc(0); nr_ue_nas[module_id].uicc = checkUicc(module_id);
return &nr_ue_nas; nr_ue_nas[module_id].UE_id = module_id;
}
return &nr_ue_nas[module_id];
} }
void generateRegistrationRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas) void generateRegistrationRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas)
{ {
int size = sizeof(mm_msg_header_t); int size = sizeof(mm_msg_header_t);
fgs_nas_message_t nas_msg={0}; fgs_nas_message_t nas_msg = {0};
MM_msg *mm_msg; MM_msg *mm_msg;
mm_msg = &nas_msg.plain.mm_msg; mm_msg = &nas_msg.plain.mm_msg;
...@@ -496,7 +505,6 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas) ...@@ -496,7 +505,6 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas)
mm_msg->header.security_header_type = PLAIN_5GS_MSG; mm_msg->header.security_header_type = PLAIN_5GS_MSG;
mm_msg->header.message_type = REGISTRATION_REQUEST; mm_msg->header.message_type = REGISTRATION_REQUEST;
// set registration request // set registration request
mm_msg->registration_request.protocoldiscriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE; mm_msg->registration_request.protocoldiscriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE;
size += 1; size += 1;
...@@ -507,7 +515,7 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas) ...@@ -507,7 +515,7 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas)
mm_msg->registration_request.fgsregistrationtype = INITIAL_REGISTRATION; mm_msg->registration_request.fgsregistrationtype = INITIAL_REGISTRATION;
mm_msg->registration_request.naskeysetidentifier.naskeysetidentifier = 1; mm_msg->registration_request.naskeysetidentifier.naskeysetidentifier = 1;
size += 1; size += 1;
if(nas->guti){ if (nas->guti) {
size += fill_guti(&mm_msg->registration_request.fgsmobileidentity, nas->guti); size += fill_guti(&mm_msg->registration_request.fgsmobileidentity, nas->guti);
} else { } else {
size += fill_suci(&mm_msg->registration_request.fgsmobileidentity, nas->uicc); size += fill_suci(&mm_msg->registration_request.fgsmobileidentity, nas->uicc);
...@@ -538,12 +546,12 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas) ...@@ -538,12 +546,12 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas)
initialNasMsg->data = malloc16_clear(size * sizeof(Byte_t)); initialNasMsg->data = malloc16_clear(size * sizeof(Byte_t));
nas->registration_request_buf = initialNasMsg->data; nas->registration_request_buf = initialNasMsg->data;
initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size); initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t *)(initialNasMsg->data), size);
nas->registration_request_len = initialNasMsg->length; nas->registration_request_len = initialNasMsg->length;
} }
void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype, uicc_t* uicc) { void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype, uicc_t *uicc)
{
int size = sizeof(mm_msg_header_t); int size = sizeof(mm_msg_header_t);
fgs_nas_message_t nas_msg; fgs_nas_message_t nas_msg;
memset(&nas_msg, 0, sizeof(fgs_nas_message_t)); memset(&nas_msg, 0, sizeof(fgs_nas_message_t));
...@@ -555,7 +563,6 @@ void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype ...@@ -555,7 +563,6 @@ void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype
mm_msg->header.security_header_type = PLAIN_5GS_MSG; mm_msg->header.security_header_type = PLAIN_5GS_MSG;
mm_msg->header.message_type = FGS_IDENTITY_RESPONSE; mm_msg->header.message_type = FGS_IDENTITY_RESPONSE;
// set identity response // set identity response
mm_msg->fgs_identity_response.protocoldiscriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE; mm_msg->fgs_identity_response.protocoldiscriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE;
size += 1; size += 1;
...@@ -563,15 +570,14 @@ void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype ...@@ -563,15 +570,14 @@ void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype
size += 1; size += 1;
mm_msg->fgs_identity_response.messagetype = FGS_IDENTITY_RESPONSE; mm_msg->fgs_identity_response.messagetype = FGS_IDENTITY_RESPONSE;
size += 1; size += 1;
if(identitytype == FGS_MOBILE_IDENTITY_SUCI){ if (identitytype == FGS_MOBILE_IDENTITY_SUCI) {
size += fill_suci(&mm_msg->fgs_identity_response.fgsmobileidentity, uicc); size += fill_suci(&mm_msg->fgs_identity_response.fgsmobileidentity, uicc);
} }
// encode the message // encode the message
initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t)); initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t));
initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size); initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t *)(initialNasMsg->data), size);
} }
static void generateAuthenticationResp(nr_ue_nas_t *nas, as_nas_info_t *initialNasMsg, uint8_t *buf) static void generateAuthenticationResp(nr_ue_nas_t *nas, as_nas_info_t *initialNasMsg, uint8_t *buf)
...@@ -579,7 +585,7 @@ static void generateAuthenticationResp(nr_ue_nas_t *nas, as_nas_info_t *initialN ...@@ -579,7 +585,7 @@ static void generateAuthenticationResp(nr_ue_nas_t *nas, as_nas_info_t *initialN
derive_ue_keys(buf, nas); derive_ue_keys(buf, nas);
OctetString res; OctetString res;
res.length = 16; res.length = 16;
res.value = calloc(1,16); res.value = calloc(1, 16);
memcpy(res.value, nas->security.res, 16); memcpy(res.value, nas->security.res, 16);
int size = sizeof(mm_msg_header_t); int size = sizeof(mm_msg_header_t);
...@@ -601,19 +607,19 @@ static void generateAuthenticationResp(nr_ue_nas_t *nas, as_nas_info_t *initialN ...@@ -601,19 +607,19 @@ static void generateAuthenticationResp(nr_ue_nas_t *nas, as_nas_info_t *initialN
mm_msg->fgs_identity_response.messagetype = FGS_AUTHENTICATION_RESPONSE; mm_msg->fgs_identity_response.messagetype = FGS_AUTHENTICATION_RESPONSE;
size += 1; size += 1;
//set response parameter // set response parameter
mm_msg->fgs_auth_response.authenticationresponseparameter.res = res; mm_msg->fgs_auth_response.authenticationresponseparameter.res = res;
size += 18; size += 18;
// encode the message // encode the message
initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t)); initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t));
initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size); initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t *)(initialNasMsg->data), size);
} }
int nas_itti_kgnb_refresh_req(instance_t instance, const uint8_t kgnb[32]) int nas_itti_kgnb_refresh_req(instance_t instance, const uint8_t kgnb[32])
{ {
MessageDef *message_p; MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_KENB_REFRESH_REQ); message_p = itti_alloc_new_message(TASK_NAS_NRUE, instance, NAS_KENB_REFRESH_REQ);
memcpy(NAS_KENB_REFRESH_REQ(message_p).kenb, kgnb, sizeof(NAS_KENB_REFRESH_REQ(message_p).kenb)); memcpy(NAS_KENB_REFRESH_REQ(message_p).kenb, kgnb, sizeof(NAS_KENB_REFRESH_REQ(message_p).kenb));
return itti_send_msg_to_task(TASK_RRC_NRUE, instance, message_p); return itti_send_msg_to_task(TASK_RRC_NRUE, instance, message_p);
} }
...@@ -657,9 +663,11 @@ static void generateSecurityModeComplete(nr_ue_nas_t *nas, as_nas_info_t *initia ...@@ -657,9 +663,11 @@ static void generateSecurityModeComplete(nr_ue_nas_t *nas, as_nas_info_t *initia
// encode the message // encode the message
initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t)); initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t));
int security_header_len = nas_protected_security_header_encode((char*)(initialNasMsg->data),&(nas_msg.header), size); int security_header_len = nas_protected_security_header_encode((char *)(initialNasMsg->data), &(nas_msg.header), size);
initialNasMsg->length = security_header_len + mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data+security_header_len), size-security_header_len); initialNasMsg->length =
security_header_len
+ mm_msg_encode(mm_msg, (uint8_t *)(initialNasMsg->data + security_header_len), size - security_header_len);
/* ciphering */ /* ciphering */
uint8_t buf[initialNasMsg->length - 7]; uint8_t buf[initialNasMsg->length - 7];
...@@ -686,12 +694,12 @@ static void generateSecurityModeComplete(nr_ue_nas_t *nas, as_nas_info_t *initia ...@@ -686,12 +694,12 @@ static void generateSecurityModeComplete(nr_ue_nas_t *nas, as_nas_info_t *initia
stream_compute_integrity(nas->security_container->integrity_algorithm, &stream_cipher, mac); stream_compute_integrity(nas->security_container->integrity_algorithm, &stream_cipher, mac);
printf("mac %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]); printf("mac %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]);
for(int i = 0; i < 4; i++){ for (int i = 0; i < 4; i++) {
initialNasMsg->data[2+i] = mac[i]; initialNasMsg->data[2 + i] = mac[i];
} }
} }
static void handle_security_mode_command(instance_t instance, nr_ue_nas_t *nas, as_nas_info_t *initialNasMsg, uint8_t *pdu, int pdu_length) static void handle_security_mode_command(nr_ue_nas_t *nas, as_nas_info_t *initialNasMsg, uint8_t *pdu, int pdu_length)
{ {
/* retrieve integrity and ciphering algorithms */ /* retrieve integrity and ciphering algorithms */
AssertFatal(pdu_length > 10, "nas: bad pdu\n"); AssertFatal(pdu_length > 10, "nas: bad pdu\n");
...@@ -707,13 +715,13 @@ static void handle_security_mode_command(instance_t instance, nr_ue_nas_t *nas, ...@@ -707,13 +715,13 @@ static void handle_security_mode_command(instance_t instance, nr_ue_nas_t *nas,
derive_knas(0x02, integrity_algorithm, kamf, knas_int); derive_knas(0x02, integrity_algorithm, kamf, knas_int);
printf("knas_int: "); printf("knas_int: ");
for(int i = 0; i < 16; i++){ for (int i = 0; i < 16; i++) {
printf("%x ", knas_int[i]); printf("%x ", knas_int[i]);
} }
printf("\n"); printf("\n");
printf("knas_enc: "); printf("knas_enc: ");
for(int i = 0; i < 16; i++){ for (int i = 0; i < 16; i++) {
printf("%x ", knas_enc[i]); printf("%x ", knas_enc[i]);
} }
printf("\n"); printf("\n");
...@@ -721,7 +729,7 @@ static void handle_security_mode_command(instance_t instance, nr_ue_nas_t *nas, ...@@ -721,7 +729,7 @@ static void handle_security_mode_command(instance_t instance, nr_ue_nas_t *nas,
/* todo: stream_security_container_delete() is not called anywhere, deal with that */ /* todo: stream_security_container_delete() is not called anywhere, deal with that */
nas->security_container = stream_security_container_init(ciphering_algorithm, integrity_algorithm, knas_enc, knas_int); nas->security_container = stream_security_container_init(ciphering_algorithm, integrity_algorithm, knas_enc, knas_int);
nas_itti_kgnb_refresh_req(instance, nas->security.kgnb); nas_itti_kgnb_refresh_req(nas->UE_id, nas->security.kgnb);
generateSecurityModeComplete(nas, initialNasMsg); generateSecurityModeComplete(nas, initialNasMsg);
} }
...@@ -749,7 +757,9 @@ static void decodeRegistrationAccept(const uint8_t *buf, int len, nr_ue_nas_t *n ...@@ -749,7 +757,9 @@ static void decodeRegistrationAccept(const uint8_t *buf, int len, nr_ue_nas_t *n
} }
} }
static void generateRegistrationComplete(nr_ue_nas_t *nas, as_nas_info_t *initialNasMsg, SORTransparentContainer *sortransparentcontainer) static void generateRegistrationComplete(nr_ue_nas_t *nas,
as_nas_info_t *initialNasMsg,
SORTransparentContainer *sortransparentcontainer)
{ {
int length = 0; int length = 0;
int size = 0; int size = 0;
...@@ -774,7 +784,7 @@ static void generateRegistrationComplete(nr_ue_nas_t *nas, as_nas_info_t *initia ...@@ -774,7 +784,7 @@ static void generateRegistrationComplete(nr_ue_nas_t *nas, as_nas_info_t *initia
sp_msg->plain.mm_msg.registration_complete.messagetype = REGISTRATION_COMPLETE; sp_msg->plain.mm_msg.registration_complete.messagetype = REGISTRATION_COMPLETE;
length += 1; length += 1;
if(sortransparentcontainer) { if (sortransparentcontainer) {
length += sortransparentcontainer->sortransparentcontainercontents.length; length += sortransparentcontainer->sortransparentcontainercontents.length;
} }
...@@ -794,7 +804,6 @@ static void generateRegistrationComplete(nr_ue_nas_t *nas, as_nas_info_t *initia ...@@ -794,7 +804,6 @@ static void generateRegistrationComplete(nr_ue_nas_t *nas, as_nas_info_t *initia
/* Encode the sequence number */ /* Encode the sequence number */
ENCODE_U8(initialNasMsg->data + size, sp_msg->header.sequence_number, size); ENCODE_U8(initialNasMsg->data + size, sp_msg->header.sequence_number, size);
/* Encode the extended protocol discriminator */ /* Encode the extended protocol discriminator */
ENCODE_U8(initialNasMsg->data + size, sp_msg->plain.mm_msg.registration_complete.protocoldiscriminator, size); ENCODE_U8(initialNasMsg->data + size, sp_msg->plain.mm_msg.registration_complete.protocoldiscriminator, size);
...@@ -804,7 +813,7 @@ static void generateRegistrationComplete(nr_ue_nas_t *nas, as_nas_info_t *initia ...@@ -804,7 +813,7 @@ static void generateRegistrationComplete(nr_ue_nas_t *nas, as_nas_info_t *initia
/* Encode the message type */ /* Encode the message type */
ENCODE_U8(initialNasMsg->data + size, sp_msg->plain.mm_msg.registration_complete.messagetype, size); ENCODE_U8(initialNasMsg->data + size, sp_msg->plain.mm_msg.registration_complete.messagetype, size);
if(sortransparentcontainer) { if (sortransparentcontainer) {
encode_registration_complete(&sp_msg->plain.mm_msg.registration_complete, initialNasMsg->data + size, length - size); encode_registration_complete(&sp_msg->plain.mm_msg.registration_complete, initialNasMsg->data + size, length - size);
} }
...@@ -832,14 +841,15 @@ static void generateRegistrationComplete(nr_ue_nas_t *nas, as_nas_info_t *initia ...@@ -832,14 +841,15 @@ static void generateRegistrationComplete(nr_ue_nas_t *nas, as_nas_info_t *initia
stream_compute_integrity(nas->security_container->integrity_algorithm, &stream_cipher, mac); stream_compute_integrity(nas->security_container->integrity_algorithm, &stream_cipher, mac);
printf("mac %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]); printf("mac %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]);
for(int i = 0; i < 4; i++){ for (int i = 0; i < 4; i++) {
initialNasMsg->data[2+i] = mac[i]; initialNasMsg->data[2 + i] = mac[i];
} }
} }
void decodeDownlinkNASTransport(as_nas_info_t *initialNasMsg, uint8_t * pdu_buffer){ void decodeDownlinkNASTransport(as_nas_info_t *initialNasMsg, uint8_t *pdu_buffer)
{
uint8_t msg_type = *(pdu_buffer + 16); uint8_t msg_type = *(pdu_buffer + 16);
if(msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC){ if (msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC) {
uint8_t *ip_p = pdu_buffer + 39; uint8_t *ip_p = pdu_buffer + 39;
char ip[20]; char ip[20];
sprintf(ip, "%d.%d.%d.%d", *(ip_p), *(ip_p + 1), *(ip_p + 2), *(ip_p + 3)); sprintf(ip, "%d.%d.%d.%d", *(ip_p), *(ip_p + 1), *(ip_p + 2), *(ip_p + 3));
...@@ -880,7 +890,9 @@ static void generateDeregistrationRequest(nr_ue_nas_t *nas, as_nas_info_t *initi ...@@ -880,7 +890,9 @@ static void generateDeregistrationRequest(nr_ue_nas_t *nas, as_nas_info_t *initi
initialNasMsg->data = calloc(size, sizeof(Byte_t)); initialNasMsg->data = calloc(size, sizeof(Byte_t));
int security_header_len = nas_protected_security_header_encode((char *)(initialNasMsg->data), &nas_msg.header, size); int security_header_len = nas_protected_security_header_encode((char *)(initialNasMsg->data), &nas_msg.header, size);
initialNasMsg->length = security_header_len + mm_msg_encode(&sp_msg->plain.mm_msg, (uint8_t *)(initialNasMsg->data + security_header_len), size - security_header_len); initialNasMsg->length =
security_header_len
+ mm_msg_encode(&sp_msg->plain.mm_msg, (uint8_t *)(initialNasMsg->data + security_header_len), size - security_header_len);
nas_stream_cipher_t stream_cipher; nas_stream_cipher_t stream_cipher;
...@@ -909,15 +921,15 @@ static void generateDeregistrationRequest(nr_ue_nas_t *nas, as_nas_info_t *initi ...@@ -909,15 +921,15 @@ static void generateDeregistrationRequest(nr_ue_nas_t *nas, as_nas_info_t *initi
stream_compute_integrity(nas->security_container->integrity_algorithm, &stream_cipher, mac); stream_compute_integrity(nas->security_container->integrity_algorithm, &stream_cipher, mac);
printf("mac %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]); printf("mac %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]);
for(int i = 0; i < 4; i++){ for (int i = 0; i < 4; i++) {
initialNasMsg->data[2+i] = mac[i]; initialNasMsg->data[2 + i] = mac[i];
} }
} }
static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t *initialNasMsg, nas_pdu_session_req_t *pdu_req) static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t *initialNasMsg, nas_pdu_session_req_t *pdu_req)
{ {
int size = 0; int size = 0;
fgs_nas_message_t nas_msg={0}; fgs_nas_message_t nas_msg = {0};
// setup pdu session establishment request // setup pdu session establishment request
uint16_t req_length = 7; uint16_t req_length = 7;
...@@ -931,8 +943,6 @@ static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t * ...@@ -931,8 +943,6 @@ static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t *
pdu_session_establish.pdusessiontype = pdu_req->pdusession_type; pdu_session_establish.pdusessiontype = pdu_req->pdusession_type;
encode_pdu_session_establishment_request(&pdu_session_establish, req_buffer); encode_pdu_session_establishment_request(&pdu_session_establish, req_buffer);
MM_msg *mm_msg; MM_msg *mm_msg;
nas_stream_cipher_t stream_cipher; nas_stream_cipher_t stream_cipher;
uint8_t mac[4]; uint8_t mac[4];
...@@ -962,14 +972,14 @@ static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t * ...@@ -962,14 +972,14 @@ static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t *
size += 1; size += 1;
mm_msg->uplink_nas_transport.fgspayloadcontainer.payloadcontainercontents.length = req_length; mm_msg->uplink_nas_transport.fgspayloadcontainer.payloadcontainercontents.length = req_length;
mm_msg->uplink_nas_transport.fgspayloadcontainer.payloadcontainercontents.value = req_buffer; mm_msg->uplink_nas_transport.fgspayloadcontainer.payloadcontainercontents.value = req_buffer;
size += (2+req_length); size += (2 + req_length);
mm_msg->uplink_nas_transport.pdusessionid = pdu_req->pdusession_id; mm_msg->uplink_nas_transport.pdusessionid = pdu_req->pdusession_id;
mm_msg->uplink_nas_transport.requesttype = 1; mm_msg->uplink_nas_transport.requesttype = 1;
size += 3; size += 3;
const bool has_nssai_sd = pdu_req->sd != 0xffffff; // 0xffffff means "no SD", TS 23.003 const bool has_nssai_sd = pdu_req->sd != 0xffffff; // 0xffffff means "no SD", TS 23.003
const size_t nssai_len = has_nssai_sd ? 4 : 1; const size_t nssai_len = has_nssai_sd ? 4 : 1;
mm_msg->uplink_nas_transport.snssai.length = nssai_len; mm_msg->uplink_nas_transport.snssai.length = nssai_len;
//Fixme: it seems there are a lot of memory errors in this: this value was on the stack, // Fixme: it seems there are a lot of memory errors in this: this value was on the stack,
// but pushed in a itti message to another thread // but pushed in a itti message to another thread
// this kind of error seems in many places in 5G NAS // this kind of error seems in many places in 5G NAS
mm_msg->uplink_nas_transport.snssai.value = calloc(1, nssai_len); mm_msg->uplink_nas_transport.snssai.value = calloc(1, nssai_len);
...@@ -977,18 +987,20 @@ static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t * ...@@ -977,18 +987,20 @@ static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t *
if (has_nssai_sd) if (has_nssai_sd)
INT24_TO_BUFFER(pdu_req->sd, &mm_msg->uplink_nas_transport.snssai.value[1]); INT24_TO_BUFFER(pdu_req->sd, &mm_msg->uplink_nas_transport.snssai.value[1]);
size += 1 + 1 + nssai_len; size += 1 + 1 + nssai_len;
int dnnSize=strlen(nas->uicc->dnnStr); int dnnSize = strlen(nas->uicc->dnnStr);
mm_msg->uplink_nas_transport.dnn.value=calloc(1,dnnSize+1); mm_msg->uplink_nas_transport.dnn.value = calloc(1, dnnSize + 1);
mm_msg->uplink_nas_transport.dnn.length = dnnSize + 1; mm_msg->uplink_nas_transport.dnn.length = dnnSize + 1;
mm_msg->uplink_nas_transport.dnn.value[0] = dnnSize; mm_msg->uplink_nas_transport.dnn.value[0] = dnnSize;
memcpy(mm_msg->uplink_nas_transport.dnn.value + 1, nas->uicc->dnnStr, dnnSize); memcpy(mm_msg->uplink_nas_transport.dnn.value + 1, nas->uicc->dnnStr, dnnSize);
size += (1+1+dnnSize+1); size += (1 + 1 + dnnSize + 1);
// encode the message // encode the message
initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t)); initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t));
int security_header_len = nas_protected_security_header_encode((char*)(initialNasMsg->data),&(nas_msg.header), size); int security_header_len = nas_protected_security_header_encode((char *)(initialNasMsg->data), &(nas_msg.header), size);
initialNasMsg->length = security_header_len + mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data+security_header_len), size-security_header_len); initialNasMsg->length =
security_header_len
+ mm_msg_encode(mm_msg, (uint8_t *)(initialNasMsg->data + security_header_len), size - security_header_len);
/* ciphering */ /* ciphering */
uint8_t buf[initialNasMsg->length - 7]; uint8_t buf[initialNasMsg->length - 7];
...@@ -1014,12 +1026,11 @@ static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t * ...@@ -1014,12 +1026,11 @@ static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t *
stream_compute_integrity(nas->security_container->integrity_algorithm, &stream_cipher, mac); stream_compute_integrity(nas->security_container->integrity_algorithm, &stream_cipher, mac);
printf("mac %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]); printf("mac %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]);
for(int i = 0; i < 4; i++){ for (int i = 0; i < 4; i++) {
initialNasMsg->data[2+i] = mac[i]; initialNasMsg->data[2 + i] = mac[i];
} }
} }
static uint8_t get_msg_type(uint8_t *pdu_buffer, uint32_t length) static uint8_t get_msg_type(uint8_t *pdu_buffer, uint32_t length)
{ {
if (pdu_buffer == NULL) if (pdu_buffer == NULL)
...@@ -1057,22 +1068,22 @@ error: ...@@ -1057,22 +1068,22 @@ error:
return 0; return 0;
} }
static void send_nas_uplink_data_req(instance_t instance, const as_nas_info_t *initial_nas_msg) static void send_nas_uplink_data_req(nr_ue_nas_t *nas, const as_nas_info_t *initial_nas_msg)
{ {
MessageDef *msg = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_UPLINK_DATA_REQ); MessageDef *msg = itti_alloc_new_message(TASK_NAS_NRUE, nas->UE_id, NAS_UPLINK_DATA_REQ);
ul_info_transfer_req_t *req = &NAS_UPLINK_DATA_REQ(msg); ul_info_transfer_req_t *req = &NAS_UPLINK_DATA_REQ(msg);
req->UEid = instance; req->UEid = nas->UE_id;
req->nasMsg.data = (uint8_t *) initial_nas_msg->data; req->nasMsg.data = (uint8_t *)initial_nas_msg->data;
req->nasMsg.length = initial_nas_msg->length; req->nasMsg.length = initial_nas_msg->length;
itti_send_msg_to_task(TASK_RRC_NRUE, instance, msg); itti_send_msg_to_task(TASK_RRC_NRUE, nas->UE_id, msg);
} }
static void send_nas_detach_req(instance_t instance, bool wait_release) static void send_nas_detach_req(nr_ue_nas_t *nas, bool wait_release)
{ {
MessageDef *msg = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_DETACH_REQ); MessageDef *msg = itti_alloc_new_message(TASK_NAS_NRUE, nas->UE_id, NAS_DETACH_REQ);
nas_detach_req_t *req = &NAS_DETACH_REQ(msg); nas_detach_req_t *req = &NAS_DETACH_REQ(msg);
req->wait_release = wait_release; req->wait_release = wait_release;
itti_send_msg_to_task(TASK_RRC_NRUE, instance, msg); itti_send_msg_to_task(TASK_RRC_NRUE, nas->UE_id, msg);
} }
static void parse_allowed_nssai(nr_nas_msg_snssai_t nssaiList[8], const uint8_t *buf, const uint32_t len) static void parse_allowed_nssai(nr_nas_msg_snssai_t nssaiList[8], const uint8_t *buf, const uint32_t len)
...@@ -1171,14 +1182,14 @@ static void get_allowed_nssai(nr_nas_msg_snssai_t nssai[8], const uint8_t *pdu_b ...@@ -1171,14 +1182,14 @@ static void get_allowed_nssai(nr_nas_msg_snssai_t nssai[8], const uint8_t *pdu_b
} }
} }
static void request_default_pdusession(int instance, int nssai_idx) static void request_default_pdusession(nr_ue_nas_t *nas, int nssai_idx)
{ {
MessageDef *message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_PDU_SESSION_REQ); MessageDef *message_p = itti_alloc_new_message(TASK_NAS_NRUE, nas->UE_id, NAS_PDU_SESSION_REQ);
NAS_PDU_SESSION_REQ(message_p).pdusession_id = 10; /* first or default pdu session */ NAS_PDU_SESSION_REQ(message_p).pdusession_id = 10; /* first or default pdu session */
NAS_PDU_SESSION_REQ(message_p).pdusession_type = 0x91; // 0x91 = IPv4, 0x92 = IPv6, 0x93 = IPv4v6 NAS_PDU_SESSION_REQ(message_p).pdusession_type = 0x91; // 0x91 = IPv4, 0x92 = IPv6, 0x93 = IPv4v6
NAS_PDU_SESSION_REQ(message_p).sst = nas_allowed_nssai[nssai_idx].sst; NAS_PDU_SESSION_REQ(message_p).sst = nas_allowed_nssai[nssai_idx].sst;
NAS_PDU_SESSION_REQ(message_p).sd = nas_allowed_nssai[nssai_idx].sd; NAS_PDU_SESSION_REQ(message_p).sd = nas_allowed_nssai[nssai_idx].sd;
itti_send_msg_to_task(TASK_NAS_NRUE, instance, message_p); itti_send_msg_to_task(TASK_NAS_NRUE, nas->UE_id, message_p);
} }
static int get_user_nssai_idx(const nr_nas_msg_snssai_t allowed_nssai[8], const nr_ue_nas_t *nas) static int get_user_nssai_idx(const nr_nas_msg_snssai_t allowed_nssai[8], const nr_ue_nas_t *nas)
...@@ -1193,16 +1204,17 @@ static int get_user_nssai_idx(const nr_nas_msg_snssai_t allowed_nssai[8], const ...@@ -1193,16 +1204,17 @@ static int get_user_nssai_idx(const nr_nas_msg_snssai_t allowed_nssai[8], const
void *nas_nrue_task(void *args_p) void *nas_nrue_task(void *args_p)
{ {
nr_ue_nas.uicc = checkUicc(0); for (int UE_id = 0; UE_id < NB_UE_INST; UE_id++) {
// This sets UE uicc from command line. Needs to be called 2 seconds into nr-ue runtime, otherwise the unused command line
// arguments will be reported as unused and the modem asserts.
(void)get_ue_nas_info(UE_id);
}
while (1) { while (1) {
nas_nrue(NULL); nas_nrue(NULL);
} }
} }
static void handle_registration_accept(instance_t instance, static void handle_registration_accept(nr_ue_nas_t *nas, const uint8_t *pdu_buffer, uint32_t msg_length)
nr_ue_nas_t *nas,
const uint8_t *pdu_buffer,
uint32_t msg_length)
{ {
LOG_I(NAS, "[UE] Received REGISTRATION ACCEPT message\n"); LOG_I(NAS, "[UE] Received REGISTRATION ACCEPT message\n");
decodeRegistrationAccept(pdu_buffer, msg_length, nas); decodeRegistrationAccept(pdu_buffer, msg_length, nas);
...@@ -1211,27 +1223,25 @@ static void handle_registration_accept(instance_t instance, ...@@ -1211,27 +1223,25 @@ static void handle_registration_accept(instance_t instance,
as_nas_info_t initialNasMsg = {0}; as_nas_info_t initialNasMsg = {0};
generateRegistrationComplete(nas, &initialNasMsg, NULL); generateRegistrationComplete(nas, &initialNasMsg, NULL);
if (initialNasMsg.length > 0) { if (initialNasMsg.length > 0) {
send_nas_uplink_data_req(instance, &initialNasMsg); send_nas_uplink_data_req(nas, &initialNasMsg);
LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n"); LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n");
} }
const int nssai_idx = get_user_nssai_idx(nas_allowed_nssai, nas); const int nssai_idx = get_user_nssai_idx(nas_allowed_nssai, nas);
if (nssai_idx < 0) { if (nssai_idx < 0) {
LOG_E(NAS, "NSSAI parameters not match with allowed NSSAI. Couldn't request PDU session.\n"); LOG_E(NAS, "NSSAI parameters not match with allowed NSSAI. Couldn't request PDU session.\n");
} else { } else {
request_default_pdusession(instance, nssai_idx); request_default_pdusession(nas, nssai_idx);
} }
} }
void *nas_nrue(void *args_p) void *nas_nrue(void *args_p)
{ {
// Wait for a message or an event // Wait for a message or an event
nr_ue_nas.uicc = checkUicc(0);
MessageDef *msg_p; MessageDef *msg_p;
itti_receive_msg(TASK_NAS_NRUE, &msg_p); itti_receive_msg(TASK_NAS_NRUE, &msg_p);
if (msg_p != NULL) { if (msg_p != NULL) {
instance_t instance = msg_p->ittiMsgHeader.originInstance; nr_ue_nas_t *nas = get_ue_nas_info(msg_p->ittiMsgHeader.destinationInstance);
AssertFatal(instance == 0, "cannot handle more than one UE!\n");
switch (ITTI_MSG_ID(msg_p)) { switch (ITTI_MSG_ID(msg_p)) {
case INITIALIZE_MESSAGE: case INITIALIZE_MESSAGE:
...@@ -1248,7 +1258,7 @@ void *nas_nrue(void *args_p) ...@@ -1248,7 +1258,7 @@ void *nas_nrue(void *args_p)
case NAS_CELL_SELECTION_CNF: case NAS_CELL_SELECTION_CNF:
LOG_I(NAS, LOG_I(NAS,
"[UE %ld] Received %s: errCode %u, cellID %u, tac %u\n", "[UE %ld] Received %s: errCode %u, cellID %u, tac %u\n",
instance, nas->UE_id,
ITTI_MSG_NAME(msg_p), ITTI_MSG_NAME(msg_p),
NAS_CELL_SELECTION_CNF(msg_p).errCode, NAS_CELL_SELECTION_CNF(msg_p).errCode,
NAS_CELL_SELECTION_CNF(msg_p).cellID, NAS_CELL_SELECTION_CNF(msg_p).cellID,
...@@ -1263,7 +1273,7 @@ void *nas_nrue(void *args_p) ...@@ -1263,7 +1273,7 @@ void *nas_nrue(void *args_p)
case NAS_CELL_SELECTION_IND: case NAS_CELL_SELECTION_IND:
LOG_I(NAS, LOG_I(NAS,
"[UE %ld] Received %s: cellID %u, tac %u\n", "[UE %ld] Received %s: cellID %u, tac %u\n",
instance, nas->UE_id,
ITTI_MSG_NAME(msg_p), ITTI_MSG_NAME(msg_p),
NAS_CELL_SELECTION_IND(msg_p).cellID, NAS_CELL_SELECTION_IND(msg_p).cellID,
NAS_CELL_SELECTION_IND(msg_p).tac); NAS_CELL_SELECTION_IND(msg_p).tac);
...@@ -1272,7 +1282,7 @@ void *nas_nrue(void *args_p) ...@@ -1272,7 +1282,7 @@ void *nas_nrue(void *args_p)
break; break;
case NAS_PAGING_IND: case NAS_PAGING_IND:
LOG_I(NAS, "[UE %ld] Received %s: cause %u\n", instance, ITTI_MSG_NAME(msg_p), NAS_PAGING_IND(msg_p).cause); LOG_I(NAS, "[UE %ld] Received %s: cause %u\n", nas->UE_id, ITTI_MSG_NAME(msg_p), NAS_PAGING_IND(msg_p).cause);
/* TODO not processed by NAS currently */ /* TODO not processed by NAS currently */
break; break;
...@@ -1280,10 +1290,9 @@ void *nas_nrue(void *args_p) ...@@ -1280,10 +1290,9 @@ void *nas_nrue(void *args_p)
case NAS_PDU_SESSION_REQ: { case NAS_PDU_SESSION_REQ: {
as_nas_info_t pduEstablishMsg = {0}; as_nas_info_t pduEstablishMsg = {0};
nas_pdu_session_req_t *pduReq = &NAS_PDU_SESSION_REQ(msg_p); nas_pdu_session_req_t *pduReq = &NAS_PDU_SESSION_REQ(msg_p);
nr_ue_nas_t *nas = get_ue_nas_info(0);
generatePduSessionEstablishRequest(nas, &pduEstablishMsg, pduReq); generatePduSessionEstablishRequest(nas, &pduEstablishMsg, pduReq);
if (pduEstablishMsg.length > 0) { if (pduEstablishMsg.length > 0) {
send_nas_uplink_data_req(instance, &pduEstablishMsg); send_nas_uplink_data_req(nas, &pduEstablishMsg);
LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n"); LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n");
} }
break; break;
...@@ -1292,7 +1301,7 @@ void *nas_nrue(void *args_p) ...@@ -1292,7 +1301,7 @@ void *nas_nrue(void *args_p)
case NAS_CONN_ESTABLI_CNF: { case NAS_CONN_ESTABLI_CNF: {
LOG_I(NAS, LOG_I(NAS,
"[UE %ld] Received %s: errCode %u, length %u\n", "[UE %ld] Received %s: errCode %u, length %u\n",
instance, nas->UE_id,
ITTI_MSG_NAME(msg_p), ITTI_MSG_NAME(msg_p),
NAS_CONN_ESTABLI_CNF(msg_p).errCode, NAS_CONN_ESTABLI_CNF(msg_p).errCode,
NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length); NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length);
...@@ -1300,11 +1309,8 @@ void *nas_nrue(void *args_p) ...@@ -1300,11 +1309,8 @@ void *nas_nrue(void *args_p)
uint8_t *pdu_buffer = NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.data; uint8_t *pdu_buffer = NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.data;
int pdu_length = NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length; int pdu_length = NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length;
nr_ue_nas_t *nas = get_ue_nas_info(0);
security_state_t security_state = nas_security_rx_process(nas, pdu_buffer, pdu_length); security_state_t security_state = nas_security_rx_process(nas, pdu_buffer, pdu_length);
if (security_state != NAS_SECURITY_INTEGRITY_PASSED if (security_state != NAS_SECURITY_INTEGRITY_PASSED && security_state != NAS_SECURITY_NO_SECURITY_CONTEXT) {
&& security_state != NAS_SECURITY_NO_SECURITY_CONTEXT) {
LOG_E(NAS, "NAS integrity failed, discard incoming message\n"); LOG_E(NAS, "NAS integrity failed, discard incoming message\n");
break; break;
} }
...@@ -1312,7 +1318,7 @@ void *nas_nrue(void *args_p) ...@@ -1312,7 +1318,7 @@ void *nas_nrue(void *args_p)
int msg_type = get_msg_type(pdu_buffer, pdu_length); int msg_type = get_msg_type(pdu_buffer, pdu_length);
if (msg_type == REGISTRATION_ACCEPT) { if (msg_type == REGISTRATION_ACCEPT) {
handle_registration_accept(instance, nas, pdu_buffer, pdu_length); handle_registration_accept(nas, pdu_buffer, pdu_length);
} else if (msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC) { } else if (msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC) {
capture_pdu_session_establishment_accept_msg(pdu_buffer, pdu_length); capture_pdu_session_establishment_accept_msg(pdu_buffer, pdu_length);
} }
...@@ -1321,9 +1327,7 @@ void *nas_nrue(void *args_p) ...@@ -1321,9 +1327,7 @@ void *nas_nrue(void *args_p)
} }
case NR_NAS_CONN_RELEASE_IND: case NR_NAS_CONN_RELEASE_IND:
LOG_I(NAS, "[UE %ld] Received %s: cause %u\n", LOG_I(NAS, "[UE %ld] Received %s: cause %u\n", nas->UE_id, ITTI_MSG_NAME(msg_p), NR_NAS_CONN_RELEASE_IND(msg_p).cause);
instance, ITTI_MSG_NAME (msg_p), NR_NAS_CONN_RELEASE_IND (msg_p).cause);
nr_ue_nas_t *nas = get_ue_nas_info(0);
// TODO handle connection release // TODO handle connection release
if (nas->termination_procedure) { if (nas->termination_procedure) {
/* the following is not clean, but probably necessary: we need to give /* the following is not clean, but probably necessary: we need to give
...@@ -1338,7 +1342,7 @@ void *nas_nrue(void *args_p) ...@@ -1338,7 +1342,7 @@ void *nas_nrue(void *args_p)
case NAS_UPLINK_DATA_CNF: case NAS_UPLINK_DATA_CNF:
LOG_I(NAS, LOG_I(NAS,
"[UE %ld] Received %s: UEid %u, errCode %u\n", "[UE %ld] Received %s: UEid %u, errCode %u\n",
instance, nas->UE_id,
ITTI_MSG_NAME(msg_p), ITTI_MSG_NAME(msg_p),
NAS_UPLINK_DATA_CNF(msg_p).UEid, NAS_UPLINK_DATA_CNF(msg_p).UEid,
NAS_UPLINK_DATA_CNF(msg_p).errCode); NAS_UPLINK_DATA_CNF(msg_p).errCode);
...@@ -1346,33 +1350,31 @@ void *nas_nrue(void *args_p) ...@@ -1346,33 +1350,31 @@ void *nas_nrue(void *args_p)
break; break;
case NAS_DEREGISTRATION_REQ: { case NAS_DEREGISTRATION_REQ: {
LOG_I(NAS, "[UE %ld] Received %s\n", instance, ITTI_MSG_NAME(msg_p)); LOG_I(NAS, "[UE %ld] Received %s\n", nas->UE_id, ITTI_MSG_NAME(msg_p));
nr_ue_nas_t *nas = get_ue_nas_info(0);
nas_deregistration_req_t *req = &NAS_DEREGISTRATION_REQ(msg_p); nas_deregistration_req_t *req = &NAS_DEREGISTRATION_REQ(msg_p);
if (nas->guti) { if (nas->guti) {
if (req->cause == AS_DETACH) { if (req->cause == AS_DETACH) {
nas->termination_procedure = true; nas->termination_procedure = true;
send_nas_detach_req(instance, true); send_nas_detach_req(nas, true);
} }
as_nas_info_t initialNasMsg = {0}; as_nas_info_t initialNasMsg = {0};
generateDeregistrationRequest(nas, &initialNasMsg, req); generateDeregistrationRequest(nas, &initialNasMsg, req);
send_nas_uplink_data_req(instance, &initialNasMsg); send_nas_uplink_data_req(nas, &initialNasMsg);
} else { } else {
LOG_W(NAS, "No GUTI, cannot trigger deregistration request.\n"); LOG_W(NAS, "No GUTI, cannot trigger deregistration request.\n");
if (req->cause == AS_DETACH) if (req->cause == AS_DETACH)
send_nas_detach_req(instance, false); send_nas_detach_req(nas, false);
} }
} break; } break;
case NAS_DOWNLINK_DATA_IND: { case NAS_DOWNLINK_DATA_IND: {
LOG_I(NAS, LOG_I(NAS,
"[UE %ld] Received %s: length %u , buffer %p\n", "[UE %ld] Received %s: length %u , buffer %p\n",
instance, nas->UE_id,
ITTI_MSG_NAME(msg_p), ITTI_MSG_NAME(msg_p),
NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length, NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length,
NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data); NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data);
as_nas_info_t initialNasMsg = {0}; as_nas_info_t initialNasMsg = {0};
nr_ue_nas_t *nas = get_ue_nas_info(0);
uint8_t *pdu_buffer = NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data; uint8_t *pdu_buffer = NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data;
int pdu_length = NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length; int pdu_length = NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length;
...@@ -1386,8 +1388,7 @@ void *nas_nrue(void *args_p) ...@@ -1386,8 +1388,7 @@ void *nas_nrue(void *args_p)
security_state = NAS_SECURITY_INTEGRITY_PASSED; security_state = NAS_SECURITY_INTEGRITY_PASSED;
} }
if (security_state != NAS_SECURITY_INTEGRITY_PASSED if (security_state != NAS_SECURITY_INTEGRITY_PASSED && security_state != NAS_SECURITY_NO_SECURITY_CONTEXT) {
&& security_state != NAS_SECURITY_NO_SECURITY_CONTEXT) {
LOG_E(NAS, "NAS integrity failed, discard incoming message\n"); LOG_E(NAS, "NAS integrity failed, discard incoming message\n");
break; break;
} }
...@@ -1402,13 +1403,13 @@ void *nas_nrue(void *args_p) ...@@ -1402,13 +1403,13 @@ void *nas_nrue(void *args_p)
generateAuthenticationResp(nas, &initialNasMsg, pdu_buffer); generateAuthenticationResp(nas, &initialNasMsg, pdu_buffer);
break; break;
case FGS_SECURITY_MODE_COMMAND: case FGS_SECURITY_MODE_COMMAND:
handle_security_mode_command(instance, nas, &initialNasMsg, pdu_buffer, pdu_length); handle_security_mode_command(nas, &initialNasMsg, pdu_buffer, pdu_length);
break; break;
case FGS_DOWNLINK_NAS_TRANSPORT: case FGS_DOWNLINK_NAS_TRANSPORT:
decodeDownlinkNASTransport(&initialNasMsg, pdu_buffer); decodeDownlinkNASTransport(&initialNasMsg, pdu_buffer);
break; break;
case REGISTRATION_ACCEPT: case REGISTRATION_ACCEPT:
handle_registration_accept(instance, nas, pdu_buffer, pdu_length); handle_registration_accept(nas, pdu_buffer, pdu_length);
break; break;
case FGS_DEREGISTRATION_ACCEPT: case FGS_DEREGISTRATION_ACCEPT:
LOG_I(NAS, "received deregistration accept\n"); LOG_I(NAS, "received deregistration accept\n");
...@@ -1448,11 +1449,11 @@ void *nas_nrue(void *args_p) ...@@ -1448,11 +1449,11 @@ void *nas_nrue(void *args_p)
} }
if (initialNasMsg.length > 0) if (initialNasMsg.length > 0)
send_nas_uplink_data_req(instance, &initialNasMsg); send_nas_uplink_data_req(nas, &initialNasMsg);
} break; } break;
default: default:
LOG_E(NAS, "[UE %ld] Received unexpected message %s\n", instance, ITTI_MSG_NAME(msg_p)); LOG_E(NAS, "[UE %ld] Received unexpected message %s\n", nas->UE_id, ITTI_MSG_NAME(msg_p));
break; break;
} }
......
...@@ -105,6 +105,7 @@ typedef struct { ...@@ -105,6 +105,7 @@ typedef struct {
bool termination_procedure; bool termination_procedure;
uint8_t *registration_request_buf; uint8_t *registration_request_buf;
uint32_t registration_request_len; uint32_t registration_request_len;
instance_t UE_id;
} nr_ue_nas_t; } nr_ue_nas_t;
typedef enum fgs_protocol_discriminator_e { typedef enum fgs_protocol_discriminator_e {
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#include <unistd.h> #include <unistd.h>
#include <stdbool.h> #include <stdbool.h>
#include <errno.h> #include <errno.h>
#include <complex.h>
#include <common/utils/assertions.h> #include <common/utils/assertions.h>
#include <common/utils/LOG/log.h> #include <common/utils/LOG/log.h>
...@@ -52,14 +52,85 @@ ...@@ -52,14 +52,85 @@
either we regenerate the channel (call again random_channel(desc,0)), or we keep it over subframes either we regenerate the channel (call again random_channel(desc,0)), or we keep it over subframes
legacy: we regenerate each sub frame in UL, and each frame only in DL legacy: we regenerate each sub frame in UL, and each frame only in DL
*/ */
void rxAddInput( const c16_t *input_sig, void rxAddInput(const c16_t *input_sig,
c16_t *after_channel_sig, c16_t *after_channel_sig,
int rxAnt, int rxAnt,
channel_desc_t *channelDesc, channel_desc_t *channelDesc,
int nbSamples, int nbSamples,
uint64_t TS, uint64_t TS,
uint32_t CirSize uint32_t CirSize)
) { {
if ((channelDesc->sat_height > 0) && (channelDesc->enable_dynamic_delay || channelDesc->enable_dynamic_Doppler)) { // model for transparent satellite on circular orbit
/* assumptions:
- The Earth is spherical, the ground station is static, and that the Earth does not rotate.
- An access or link is possible from the satellite to the ground station at all times.
- The ground station is located at the North Pole (positive Zaxis), and the satellite starts from the initial elevation angle 0° in the second quadrant of the YZplane.
- Satellite moves in the clockwise direction in its circular orbit.
*/
const double radius_earth = 6371e3; // m
const double radius_sat = radius_earth + channelDesc->sat_height;
const double GM_earth = 3.986e14; // m^3/s^2
const double w_sat = sqrt(GM_earth / (radius_sat * radius_sat * radius_sat)); // rad/s
// start_time and end_time are when the pos_sat_z == pos_gnb_z (elevation angle == 0 and 180 degree)
const double start_phase = -acos(radius_earth / radius_sat); // SAT is just rising above the horizon
const double end_phase = -start_phase; // SAT is just falling behind the horizon
const double start_time = start_phase / w_sat; // in seconds
const double end_time = end_phase / w_sat; // in seconds
const uint64_t duration_samples = (end_time - start_time) * channelDesc->sampling_rate;
const double t = start_time + ((TS - channelDesc->start_TS) % duration_samples) / channelDesc->sampling_rate;
const double pos_sat_x = 0;
const double pos_sat_y = radius_sat * sin(w_sat * t);
const double pos_sat_z = radius_sat * cos(w_sat * t);
const double vel_sat_x = 0;
const double vel_sat_y = w_sat * radius_sat * cos(w_sat * t);
const double vel_sat_z = -w_sat * radius_sat * sin(w_sat * t);
const double pos_ue_x = 0;
const double pos_ue_y = 0;
const double pos_ue_z = radius_earth;
const double dir_sat_ue_x = pos_ue_x - pos_sat_x;
const double dir_sat_ue_y = pos_ue_y - pos_sat_y;
const double dir_sat_ue_z = pos_ue_z - pos_sat_z;
const double dist_sat_ue = sqrt(dir_sat_ue_x * dir_sat_ue_x + dir_sat_ue_y * dir_sat_ue_y + dir_sat_ue_z * dir_sat_ue_z);
const double vel_sat_ue = (vel_sat_x * dir_sat_ue_x + vel_sat_y * dir_sat_ue_y + vel_sat_z * dir_sat_ue_z) / dist_sat_ue;
double dist_gnb_sat = 0;
double vel_gnb_sat = 0;
if (channelDesc->modelid == SAT_LEO_TRANS) {
const double pos_gnb_x = 0;
const double pos_gnb_y = 0;
const double pos_gnb_z = radius_earth;
const double dir_gnb_sat_x = pos_sat_x - pos_gnb_x;
const double dir_gnb_sat_y = pos_sat_y - pos_gnb_y;
const double dir_gnb_sat_z = pos_sat_z - pos_gnb_z;
dist_gnb_sat = sqrt(dir_gnb_sat_x * dir_gnb_sat_x + dir_gnb_sat_y * dir_gnb_sat_y + dir_gnb_sat_z * dir_gnb_sat_z);
vel_gnb_sat = (vel_sat_x * dir_gnb_sat_x + vel_sat_y * dir_gnb_sat_y + vel_sat_z * dir_gnb_sat_z) / dist_gnb_sat;
}
const double c = 299792458; // m/s
const double prop_delay = (dist_gnb_sat + dist_sat_ue) / c;
if (channelDesc->enable_dynamic_delay)
channelDesc->channel_offset = prop_delay * channelDesc->sampling_rate;
const double f_Doppler_shift_sat_ue = (vel_sat_ue / (c - vel_sat_ue)) * channelDesc->center_freq;
const double f_Doppler_shift_gnb_sat = (-vel_gnb_sat / c) * channelDesc->center_freq;
if (channelDesc->enable_dynamic_Doppler)
channelDesc->Doppler_phase_inc = 2 * M_PI * (f_Doppler_shift_gnb_sat + f_Doppler_shift_sat_ue) / channelDesc->sampling_rate;
static uint64_t last_TS = 0;
if(TS - last_TS >= channelDesc->sampling_rate) {
last_TS = TS;
LOG_I(HW, "Satellite orbit: time %f s, Doppler: gNB->SAT %f kHz, SAT->UE %f kHz, Delay %f ms\n", t, f_Doppler_shift_gnb_sat / 1000, f_Doppler_shift_sat_ue / 1000, prop_delay * 1000);
}
}
// channelDesc->path_loss_dB should contain the total path gain // channelDesc->path_loss_dB should contain the total path gain
// so, in actual RF: tx gain + path loss + rx gain (+antenna gain, ...) // so, in actual RF: tx gain + path loss + rx gain (+antenna gain, ...)
// UE and NB gain control to be added // UE and NB gain control to be added
...@@ -94,9 +165,20 @@ void rxAddInput( const c16_t *input_sig, ...@@ -94,9 +165,20 @@ void rxAddInput( const c16_t *input_sig,
} //l } //l
} }
// Fixme: lround(), rount(), ... is detected by valgrind as error, not found why if (channelDesc->Doppler_phase_inc != 0.0) {
out_ptr->r += lround(rx_tmp.r*pathLossLinear + noise_per_sample*gaussZiggurat(0.0,1.0)); #ifdef CMPLX
out_ptr->i += lround(rx_tmp.i*pathLossLinear + noise_per_sample*gaussZiggurat(0.0,1.0)); double complex in = CMPLX(rx_tmp.r, rx_tmp.i);
#else
double complex in = rx_tmp.r + rx_tmp.i * I;
#endif
double complex out = in * cexp(channelDesc->Doppler_phase_cur[rxAnt] * I);
rx_tmp.r = creal(out);
rx_tmp.i = cimag(out);
channelDesc->Doppler_phase_cur[rxAnt] += channelDesc->Doppler_phase_inc;
}
out_ptr->r = lround(rx_tmp.r*pathLossLinear + noise_per_sample*gaussZiggurat(0.0,1.0));
out_ptr->i = lround(rx_tmp.i*pathLossLinear + noise_per_sample*gaussZiggurat(0.0,1.0));
out_ptr++; out_ptr++;
} }
......
...@@ -167,6 +167,7 @@ typedef struct { ...@@ -167,6 +167,7 @@ typedef struct {
int rx_num_channels; int rx_num_channels;
int tx_num_channels; int tx_num_channels;
double sample_rate; double sample_rate;
double rx_freq;
double tx_bw; double tx_bw;
int channelmod; int channelmod;
double chan_pathloss; double chan_pathloss;
...@@ -342,7 +343,7 @@ static void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) { ...@@ -342,7 +343,7 @@ static void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) {
break; break;
} else if (strcmp(rfsimu_params[p].strlistptr[i],"chanmod") == 0) { } else if (strcmp(rfsimu_params[p].strlistptr[i],"chanmod") == 0) {
init_channelmod(); init_channelmod();
load_channellist(rfsimulator->tx_num_channels, rfsimulator->rx_num_channels, rfsimulator->sample_rate, rfsimulator->tx_bw); load_channellist(rfsimulator->tx_num_channels, rfsimulator->rx_num_channels, rfsimulator->sample_rate, rfsimulator->rx_freq, rfsimulator->tx_bw);
rfsimulator->channelmod=true; rfsimulator->channelmod=true;
} else { } else {
fprintf(stderr, "unknown rfsimulator option: %s\n", rfsimu_params[p].strlistptr[i]); fprintf(stderr, "unknown rfsimulator option: %s\n", rfsimu_params[p].strlistptr[i]);
...@@ -400,7 +401,7 @@ static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, ...@@ -400,7 +401,7 @@ static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt,
t->rx_num_channels, t->rx_num_channels,
channelmod, channelmod,
t->sample_rate, t->sample_rate,
0, t->rx_freq,
t->tx_bw, t->tx_bw,
30e-9, // TDL delay-spread parameter 30e-9, // TDL delay-spread parameter
0.0, 0.0,
...@@ -708,6 +709,10 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi ...@@ -708,6 +709,10 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
samplesVoid[i]=(void *)&v; samplesVoid[i]=(void *)&v;
rfsimulator_write_internal(t, t->lastWroteTS > 1 ? t->lastWroteTS - 1 : 0, samplesVoid, 1, t->tx_num_channels, 1, false); rfsimulator_write_internal(t, t->lastWroteTS > 1 ? t->lastWroteTS - 1 : 0, samplesVoid, 1, t->tx_num_channels, 1, false);
buffer_t *b = &t->buf[conn_sock];
if (b->channel_model)
b->channel_model->start_TS = t->lastWroteTS;
} else { } else {
if ( events[nbEv].events & (EPOLLHUP | EPOLLERR | EPOLLRDHUP) ) { if ( events[nbEv].events & (EPOLLHUP | EPOLLERR | EPOLLRDHUP) ) {
socketError(t,fd); socketError(t,fd);
...@@ -760,6 +765,8 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi ...@@ -760,6 +765,8 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
nsamps_for_initial; nsamps_for_initial;
LOG_D(HW, "UE got first timestamp: starting at %lu\n", t->nextRxTstamp); LOG_D(HW, "UE got first timestamp: starting at %lu\n", t->nextRxTstamp);
b->trashingPacket=true; b->trashingPacket=true;
if (b->channel_model)
b->channel_model->start_TS = t->nextRxTstamp;
} else if (b->lastReceivedTS < b->th.timestamp) { } else if (b->lastReceivedTS < b->th.timestamp) {
int nbAnt= b->th.nbAnt; int nbAnt= b->th.nbAnt;
...@@ -963,6 +970,8 @@ static int rfsimulator_stop(openair0_device *device) { ...@@ -963,6 +970,8 @@ static int rfsimulator_stop(openair0_device *device) {
return 0; return 0;
} }
static int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cfg) { static int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cfg) {
rfsimulator_state_t* s = device->priv;
s->rx_freq = openair0_cfg->rx_freq[0];
return 0; return 0;
} }
static int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) { static int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) {
...@@ -980,6 +989,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { ...@@ -980,6 +989,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
rfsimulator->tx_num_channels=openair0_cfg->tx_num_channels; rfsimulator->tx_num_channels=openair0_cfg->tx_num_channels;
rfsimulator->rx_num_channels=openair0_cfg->rx_num_channels; rfsimulator->rx_num_channels=openair0_cfg->rx_num_channels;
rfsimulator->sample_rate=openair0_cfg->sample_rate; rfsimulator->sample_rate=openair0_cfg->sample_rate;
rfsimulator->rx_freq=openair0_cfg->rx_freq[0];
rfsimulator->tx_bw=openair0_cfg->tx_bw; rfsimulator->tx_bw=openair0_cfg->tx_bw;
rfsimulator_readconfig(rfsimulator); rfsimulator_readconfig(rfsimulator);
if (rfsimulator->prop_delay_ms > 0.0) if (rfsimulator->prop_delay_ms > 0.0)
......
channelmod = {
max_chan=10;
modellist="modellist_rfsimu_1";
modellist_rfsimu_1 = (
{
model_name = "rfsimu_channel_enB0"
type = "SAT_LEO_TRANS";
noise_power_dB = -100;
},
{
model_name = "rfsimu_channel_ue0"
type = "SAT_LEO_TRANS";
noise_power_dB = -100;
}
);
};
...@@ -165,7 +165,8 @@ gNBs = ...@@ -165,7 +165,8 @@ gNBs =
#ext2 #ext2
#ntn_Config_r17 #ntn_Config_r17
# cellSpecificKoffset_r17 = 478; # cellSpecificKoffset_r17 = 478; # GEO satellite
# cellSpecificKoffset_r17 = 40; # LEO satellite
} }
); );
...@@ -255,7 +256,6 @@ rfsimulator : ...@@ -255,7 +256,6 @@ rfsimulator :
serveraddr = "server"; serveraddr = "server";
serverport = 4043; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
}; };
...@@ -289,3 +289,4 @@ log_config : ...@@ -289,3 +289,4 @@ log_config :
f1ap_log_level ="debug"; f1ap_log_level ="debug";
}; };
@include "channelmod_rfsimu_LEO_satellite.conf"
...@@ -165,7 +165,8 @@ gNBs = ...@@ -165,7 +165,8 @@ gNBs =
#ext2 #ext2
#ntn_Config_r17 #ntn_Config_r17
# cellSpecificKoffset_r17 = 478; # cellSpecificKoffset_r17 = 478; # GEO satellite
# cellSpecificKoffset_r17 = 40; # LEO satellite
} }
); );
...@@ -255,7 +256,6 @@ rfsimulator : ...@@ -255,7 +256,6 @@ rfsimulator :
serveraddr = "server"; serveraddr = "server";
serverport = 4043; serverport = 4043;
options = (); #("saviq"); or/and "chanmod" options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"; IQfile = "/tmp/rfsimulator.iqs";
}; };
...@@ -289,3 +289,4 @@ log_config : ...@@ -289,3 +289,4 @@ log_config :
f1ap_log_level ="debug"; f1ap_log_level ="debug";
}; };
@include "channelmod_rfsimu_LEO_satellite.conf"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment