Compare commits

..

1 Commits

Author SHA1 Message Date
Guido Casati
708352fbf6 Initialize nr_prach_info_t structure to zero before use
This commit ensures that the 'info' structure is properly initialized
with zero values before assigning values to its members.

This prevents the use of uninitialized memory which could contain
contain garbage values.

e.g. in FR2 case we have: `info.N_RA_sfn += count_bits64(info.s_map);`
2025-04-04 15:49:00 +02:00
364 changed files with 9858 additions and 15166 deletions

View File

@@ -288,15 +288,14 @@ add_definitions(-DHAVE_NETINET_IN_H)
set(E2_AGENT "OFF" CACHE STRING "O-RAN-compliant E2 Agent")
set_property(CACHE E2_AGENT PROPERTY STRINGS "ON" "OFF")
if (E2_AGENT STREQUAL "ON")
set(E2AP_VERSION "E2AP_V2" CACHE STRING "E2AP version")
set_property(CACHE E2AP_VERSION PROPERTY STRINGS "E2AP_V1" "E2AP_V2" "E2AP_V3")
message(STATUS "Selected E2AP version: ${E2AP_VERSION}")
set(E2AP_VERSION "E2AP_V2" CACHE STRING "E2AP version")
set_property(CACHE E2AP_VERSION PROPERTY STRINGS "E2AP_V1" "E2AP_V2" "E2AP_V3")
message(STATUS "Selected E2AP_VERSION: ${E2AP_VERSION}")
set(KPM_VERSION "KPM_V2_03" CACHE STRING "The KPM SM version to use")
set_property(CACHE KPM_VERSION PROPERTY STRINGS "KPM_V2_03" "KPM_V3_00")
message(STATUS "Selected KPM Version: ${KPM_VERSION}")
set(KPM_VERSION "KPM_V2_03" CACHE STRING "The KPM SM version to use")
set_property(CACHE KPM_VERSION PROPERTY STRINGS "KPM_V2_03" "KPM_V3_00")
message(STATUS "Selected KPM version: ${KPM_VERSION}")
endif()
add_boolean_option(ENABLE_IMSCOPE OFF "Enable phy scope based on imgui" OFF)
add_boolean_option(ENABLE_IMSCOPE_RECORD OFF "Enable recording IQ data for imscope" OFF)
@@ -454,9 +453,6 @@ target_include_directories(f1ap PUBLIC F1AP_DIR)
target_link_libraries(f1ap PUBLIC asn1_f1ap GTPV1U)
target_link_libraries(f1ap PRIVATE ngap nr_rrc HASHTABLE f1ap_lib)
target_include_directories(f1ap PRIVATE ${F1AP_DIR}/lib)
if(E2_AGENT)
target_compile_definitions(f1ap PRIVATE E2_AGENT)
endif()
# LPP
##############
@@ -813,14 +809,17 @@ set(PHY_SRC_COMMON
${OPENAIR1_DIR}/PHY/CODING/viterbi_lte.c
${OPENAIR1_DIR}/PHY/INIT/init_top.c
${OPENAIR1_DIR}/PHY/INIT/lte_parms.c
${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c
${OPENAIR1_DIR}/PHY/TOOLS/dfts_load.c
${OPENAIR1_DIR}/PHY/TOOLS/log2_approx.c
${OPENAIR1_DIR}/PHY/TOOLS/cmult_sv.c
${OPENAIR1_DIR}/PHY/TOOLS/cmult_vv.c
${OPENAIR1_DIR}/PHY/TOOLS/cdot_prod.c
${OPENAIR1_DIR}/PHY/TOOLS/signal_energy.c
${OPENAIR1_DIR}/PHY/TOOLS/dB_routines.c
${OPENAIR1_DIR}/PHY/TOOLS/sqrt.c
${OPENAIR1_DIR}/PHY/TOOLS/get_sin_cos.c
${OPENAIR1_DIR}/PHY/TOOLS/oai_arith_operations.c
${OPENAIR1_DIR}/PHY/TOOLS/lut.c
${OPENAIR1_DIR}/PHY/TOOLS/simde_operations.c
)
set(PHY_SRC
@@ -945,12 +944,16 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_freq_equalization.c
${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_measurements_gNB.c
${OPENAIR1_DIR}/PHY/TOOLS/file_output.c
${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c
${OPENAIR1_DIR}/PHY/TOOLS/log2_approx.c
${OPENAIR1_DIR}/PHY/TOOLS/cmult_sv.c
${OPENAIR1_DIR}/PHY/TOOLS/cmult_vv.c
${OPENAIR1_DIR}/PHY/TOOLS/cdot_prod.c
${OPENAIR1_DIR}/PHY/TOOLS/signal_energy.c
${OPENAIR1_DIR}/PHY/TOOLS/dB_routines.c
${OPENAIR1_DIR}/PHY/TOOLS/sqrt.c
${OPENAIR1_DIR}/PHY/TOOLS/oai_arith_operations.c
${OPENAIR1_DIR}/PHY/TOOLS/lut.c
${OPENAIR1_DIR}/PHY/TOOLS/simde_operations.c
${PHY_POLARSRC}
${PHY_SMALLBLOCKSRC}
${PHY_NRLDPC_CODINGIF}
@@ -994,12 +997,16 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_adjust_gain.c
${OPENAIR1_DIR}/PHY/TOOLS/file_output.c
${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c
${OPENAIR1_DIR}/PHY/TOOLS/log2_approx.c
${OPENAIR1_DIR}/PHY/TOOLS/cmult_sv.c
${OPENAIR1_DIR}/PHY/TOOLS/cmult_vv.c
${OPENAIR1_DIR}/PHY/TOOLS/cdot_prod.c
${OPENAIR1_DIR}/PHY/TOOLS/signal_energy.c
${OPENAIR1_DIR}/PHY/TOOLS/dB_routines.c
${OPENAIR1_DIR}/PHY/TOOLS/sqrt.c
${OPENAIR1_DIR}/PHY/TOOLS/oai_arith_operations.c
${OPENAIR1_DIR}/PHY/TOOLS/lut.c
${OPENAIR1_DIR}/PHY/TOOLS/simde_operations.c
${OPENAIR1_DIR}/PHY/INIT/nr_init_ue.c
${PHY_POLARSRC}
${PHY_SMALLBLOCKSRC}
@@ -1824,7 +1831,6 @@ target_link_libraries(nr-softmodem PRIVATE
ITTI ${NAS_UE_LIB} lte_rrc nr_rrc
ngap s1ap L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB SIMU
x2ap f1ap m2ap m3ap e1ap shlib_loader
time_management
-Wl,--end-group z dl)
target_link_libraries(nr-softmodem PRIVATE pthread m CONFIG_LIB rt sctp)
@@ -1857,7 +1863,6 @@ add_executable(nr-cuup
target_link_libraries(nr-cuup PRIVATE
CONFIG_LIB ITTI SCTP_CLIENT
GTPV1U e1ap f1ap
time_management
z sctp dl pthread shlib_loader ${T_LIB})
target_link_libraries(nr-cuup PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
if(E2_AGENT)
@@ -1889,7 +1894,6 @@ target_link_libraries(nr-uesoftmodem PRIVATE
nr_rrc SECURITY UTIL HASHTABLE SCHED_RU_LIB SCHED_NR_UE_LIB
PHY_COMMON PHY_NR_COMMON PHY_NR_UE NR_L2_UE MAC_NR_COMMON NFAPI_LIB
ITTI SIMU shlib_loader
time_management
-Wl,--end-group z dl)
target_link_libraries(nr-uesoftmodem PRIVATE pthread m CONFIG_LIB rt nr_ue_phy_meas)

View File

@@ -77,8 +77,8 @@ oc-cn5g-20897:
Undeploy: "! scripts/oc-cn5g-undeploy.sh /opt/oai-cn5g-fed-develop-2025-jan oaicicd-core-for-fhi72"
LogCollect: "! scripts/oc-cn5g-logcollect.sh /opt/oai-cn5g-fed-develop-2025-jan oaicicd-core-for-fhi72 %%log_dir%%"
oc-cn5g-20897-aerial:
Host: gracehopper1-oai
oc-cn5g-20897-aerial2:
Host: aerial2
NetworkScript: echo "inet 172.21.6.105"
RunIperf3Server: False
Deploy: "! scripts/oc-cn5g-deploy.sh /opt/oai-cn5g-fed-develop-2025-jan oaicicd-core-for-nvidia-aerial"

View File

@@ -410,7 +410,6 @@ class Containerize():
result = re.search('native_arm', self.imageKind)
if result is not None:
imageNames.append(('oai-gnb', 'gNB', 'oai-gnb', ''))
imageNames.append(('ran-build-fhi72', 'build.fhi72.native_arm', 'ran-build-fhi72', ''))
imageNames.append(('oai-nr-cuup', 'nr-cuup', 'oai-nr-cuup', ''))
imageNames.append(('oai-nr-ue', 'nrUE', 'oai-nr-ue', ''))
imageNames.append(('oai-gnb-aerial', 'gNB.aerial', 'oai-gnb-aerial', ''))
@@ -890,10 +889,7 @@ class Containerize():
if deployed:
break
elif (attempt < num_attempts - 1):
warning_msg = f'Restart services {services}'
logging.warning(warning_msg)
imagesInfo.append(warning_msg)
HTML.CreateHtmlTestRowQueue('N/A', 'NOK', ['\n'.join(imagesInfo)])
logging.warning(f'Failed to deploy on attempt {attempt}, restart services {services}')
for svc in services.split():
CopyinServiceLog(ssh, lSourcePath, yaml_dir, svc, wd_yaml, f'{svc}-{HTML.testCase_id}-attempt{attempt}.log')
ssh.run(f'docker compose -f {wd_yaml} down -- {services}')

View File

@@ -49,7 +49,7 @@ class CoreNetwork:
self._host = c.get('Host').strip()
if self._host == "%%current_host%%":
if node is None:
raise Exception(f"core network {cn_name} requires node, but none provided (cannot replace %%current_host%%)")
raise Exception(f"core network {self} requires node, but none provided (cannot replace %%current_host%%)")
self._host = node
if d is not None:
raise Exception("directory handling not implemented")
@@ -66,7 +66,7 @@ class CoreNetwork:
logging.info(f'initialized core {self} from {filename}')
def __str__(self):
return f"{self._cn_name}@{self._host}"
return f"{self._cn_name}@{self._host} [IP: {self.getIP()}]"
def __repr__(self):
return self.__str__()
@@ -162,9 +162,6 @@ class CoreNetwork:
def getCmdPrefix(self):
return self._cmd_prefix or ""
def getName(self):
return self._cn_name
def getHost(self):
return self._host

View File

@@ -210,7 +210,7 @@ def Iperf_analyzeV2UDP(server_filename, iperf_bitrate_threshold, iperf_packetlos
jit_msg = f'Jitter : {jitter}'
pal_msg = f'Packet Loss : {packetloss}'
if float(packetloss) > float(iperf_packetloss_threshold):
pal_msg += f' (too high! >{iperf_packetloss_threshold}%)'
pal_msg += f' (too high! >{self.iperf_packetloss_threshold}%)'
return (result, f'{req_msg}\n{bir_msg}\n{brl_msg}\n{jit_msg}\n{pal_msg}')
def Custom_Command(HTML, node, command, command_fail):
@@ -464,7 +464,7 @@ class OaiCiTest():
return (False, f"UE {ue.getName()} has no IP address")
svrIP = cn.getIP()
if not svrIP:
return (False, f"Iperf server {cn.getName()} has no IP address")
return (False, f"Iperf server {ue.getName()} has no IP address")
iperf_opt = self.iperf_args
jsonReport = "--json"
@@ -862,7 +862,7 @@ class OaiCiTest():
success, output = cn.deploy()
logging.info(f"deployment core network {core_name} success {success}, output:\n{output}")
if success:
msg = f"Started {cn} [{cn.getIP()}]"
msg = f"Started {cn}"
HTML.CreateHtmlTestRowQueue(core_name, 'OK', [msg])
else:
msg = f"deployment of core network {core_name} FAILED"

View File

@@ -189,11 +189,11 @@ RUs = (
nb_rx = 1
# The higher att for TX than RX is because we use a circulator (as for TDD),
# while we should use a duplexer in the FDD case. However, it uses the same setup.
att_tx = 16
att_tx = 18
att_rx = 0;
bands = [1];
max_pdschReferenceSignalPower = -27;
max_rxgain = 110;
max_rxgain = 108;
eNB_instances = [0];
clock_src = "internal";
}

View File

@@ -194,11 +194,11 @@ RUs = (
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 4;
att_rx = 4;
att_tx = 10;
att_rx = 10;
bands = [78];
max_pdschReferenceSignalPower = -27;
max_rxgain = 106;
max_rxgain = 114;
eNB_instances = [0];
clock_src = "internal";
}

View File

@@ -186,7 +186,7 @@ MACRLCs = (
remote_s_portd = 50010; // pnf p7 port [!]
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 300;
pusch_TargetSNRx10 = 250;
pucch_TargetSNRx10 = 250;
pusch_FailureThres = 100;
ul_max_mcs = 28;

View File

@@ -186,8 +186,8 @@ gNBs =
NETWORK_INTERFACES :
{
GNB_IPV4_ADDRESS_FOR_NG_AMF = "172.21.16.202";
GNB_IPV4_ADDRESS_FOR_NGU = "172.21.16.202";
GNB_IPV4_ADDRESS_FOR_NG_AMF = "172.21.16.131";
GNB_IPV4_ADDRESS_FOR_NGU = "172.21.16.131";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};

View File

@@ -20,8 +20,6 @@ gNBs =
min_rxtxtime = 6;
num_dlharq = 32;
num_ulharq = 32;
cu_sibs = [2];
du_sibs = [19];
servingCellConfigCommon = (
{
@@ -51,7 +49,7 @@ gNBs =
initialDLBWPsubcarrierSpacing = 0;
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 2;
initialDLBWPsearchSpaceZero = 2;
initialDLBWPsearchSpaceZero = 0;
#uplinkConfigCommon
#frequencyInfoUL
@@ -151,7 +149,7 @@ gNBs =
#ext2
#ntn_Config_r17
cellSpecificKoffset_r17 = 40;
ta-Common-r17 = 4627000; # 18.84 ms
ta-Common-r17 = 4634000; # 18.87 ms
ta-CommonDrift-r17 = -230000; # -46 µs/s
positionX-r17 = 0;
positionY-r17 = -2166908; # -2816980.4 m
@@ -237,6 +235,15 @@ RUs = (
}
);
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";
@@ -289,4 +296,6 @@ log_config :
rlc_log_level ="info";
pdcp_log_level ="info";
rrc_log_level ="info";
ngap_log_level ="debug";
f1ap_log_level ="debug";
};

View File

@@ -19,8 +19,6 @@ gNBs =
sib1_tda = 5;
min_rxtxtime = 6;
disable_harq = 1;
cu_sibs = [2];
du_sibs = [19];
servingCellConfigCommon = (
{
@@ -50,7 +48,7 @@ gNBs =
initialDLBWPsubcarrierSpacing = 0;
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 2;
initialDLBWPsearchSpaceZero = 2;
initialDLBWPsearchSpaceZero = 0;
#uplinkConfigCommon
#frequencyInfoUL
@@ -235,6 +233,15 @@ RUs = (
}
);
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";
@@ -270,4 +277,6 @@ log_config :
rlc_log_level ="info";
pdcp_log_level ="info";
rrc_log_level ="info";
ngap_log_level ="debug";
f1ap_log_level ="debug";
};

View File

@@ -18,12 +18,11 @@ gNBs =
////////// Physical parameters:
pdsch_AntennaPorts_XP = 2;
pdsch_AntennaPorts_N1 = 2;
pdsch_AntennaPorts_N1 = 1;
maxMIMO_layers = 2;
pusch_AntennaPorts = 4;
do_CSIRS = 1;
do_SRS = 0;
force_UL256qam_off = 1;
servingCellConfigCommon = (
{
@@ -31,12 +30,12 @@ gNBs =
physCellId = 0;
# downlinkConfigCommon
#frequencyInfoDL
# center frequency = 4049.76 MHz
# selected SSB frequency = 4049.76 MHz
absoluteFrequencySSB = 669984;
# center frequency = 3999.36 MHz
# selected SSB frequency = 3999.36 MHz
absoluteFrequencySSB = 666624;
dl_frequencyBand = 77;
# frequency point A = 4000.62 MHz
dl_absoluteFrequencyPointA = 666708;
# frequency point A = 3950.22 MHz
dl_absoluteFrequencyPointA = 663348;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
@@ -178,8 +177,10 @@ MACRLCs = (
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 250;
pusch_TargetSNRx10 = 180;
pucch_TargetSNRx10 = 230;
ul_bler_target_upper = .35;
ul_bler_target_lower = .15;
pusch_FailureThres = 100;
}
);
@@ -211,7 +212,7 @@ RUs = (
sf_extension = 0;
eNB_instances = [0];
ru_thread_core = 5;
sl_ahead = 10;
sl_ahead = 5;
tr_preference = "raw_if4p5"; # important: activate FHI7.2
do_precoding = 0; # needs to match O-RU configuration
}
@@ -249,11 +250,10 @@ log_config :
fhi_72 = {
dpdk_devices = ("0000:c3:11.0", "0000:c3:11.1");
dpdk_iova_mode = "VA";
system_core = 0;
io_core = 1;
worker_cores = (2);
ru_addr = ("98:ae:71:04:83:e3", "98:ae:71:04:83:e3");
ru_addr = ("98:ae:71:01:c5:eb", "98:ae:71:01:c5:eb");
mtu = 9600;
fh_config = ({
T1a_cp_dl = (285, 470);

View File

@@ -83,7 +83,7 @@ gNBs =
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 = 2;
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
#one (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14;
#ra_ContentionResolutionTimer
@@ -192,9 +192,8 @@ L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
prach_dtx_threshold = 150;
prach_dtx_threshold = 120;
pucch0_dtx_threshold = 30;
max_ldpc_iterations = 15;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
@@ -204,11 +203,11 @@ RUs = (
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 6;
att_rx = 6;
att_tx = 10;
att_rx = 10;
bands = [78];
max_pdschReferenceSignalPower = -27;
max_rxgain = 110;
max_rxgain = 114;
eNB_instances = [0];
clock_src = "internal";
}

View File

@@ -1,35 +0,0 @@
uicc0 = {
imsi = "208990100001100";
key = "fec86ba6eb707ed08905757b1bb44b8f";
opc= "C42449363BBAD02B66D16BC975D77CC1";
dnn= "oai";
nssai_sst=1;
}
position0 = {
x = 0.0;
y = 0.0;
z = 6377900.0;
}
thread-pool = "-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1"
#/* configuration for channel modelisation */
#/* To be included in main config file when */
#/* channel modelisation is used (rfsimulator with chanmod options enabled) */
channelmod = {
max_chan = 10;
modellist = "modellist_rfsimu_1";
modellist_rfsimu_1 = (
{ # DL, modify on UE side
model_name = "rfsimu_channel_enB0"
type = "SAT_LEO_TRANS";
noise_power_dB = -100;
},
{ # UL, modify on gNB side
model_name = "rfsimu_channel_ue0"
type = "SAT_LEO_TRANS";
noise_power_dB = -100;
}
);
};

View File

@@ -46,15 +46,9 @@
020022
040024
000024
000030
040025
000031
030021
040027
040025
000031
020022
040026
100021
222222
</TestCaseRequestedList>
@@ -228,22 +222,6 @@
<command_fail>yes</command_fail>
</testCase>
<testCase id="040026">
<class>Custom_Command</class>
<desc>UE (1) connected to DU-PCI 0?</desc>
<node>cacofonix</node>
<command>echo ci fetch_du_by_ue_id 1 | nc 192.168.71.150 9090 | grep "3584"</command>
<command_fail>yes</command_fail>
</testCase>
<testCase id="040027">
<class>Custom_Command</class>
<desc>UE (1) connected to DU-PCI 1?</desc>
<node>cacofonix</node>
<command>echo ci fetch_du_by_ue_id 1 | nc 192.168.71.150 9090 | grep "3585"</command>
<command_fail>yes</command_fail>
</testCase>
<testCase id="100021">
<class>Undeploy_Object</class>
<always_exec>true</always_exec>

View File

@@ -32,6 +32,7 @@
000001
000002
000003
002001
010000
000004
333333
@@ -39,6 +40,7 @@
010002
010003
020005
010013
002006
444444
100002
@@ -48,6 +50,12 @@
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="002001">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>10</idle_sleep_time_in_sec>
</testCase>
<testCase id="111110">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
@@ -165,39 +173,43 @@
</testCase>
<testCase id="010000">
<class>Deploy_Object</class>
<class>Custom_Command</class>
<desc>RC monitoring</desc>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_flexric</yaml_path>
<services>xapp-rc-moni</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<node>localhost</node>
<command_fail>yes</command_fail>
<command>docker exec oai-flexric bash -c "stdbuf -o0 /usr/local/flexric/xApp/c/monitor/xapp_rc_moni" > ../cmake_targets/log/5g_rfsimulator_flexric/rc-moni-010000.log</command>
</testCase>
<testCase id="010001">
<class>Deploy_Object</class>
<class>Custom_Command</class>
<desc>KPM monitoring</desc>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_flexric</yaml_path>
<services>xapp-kpm-moni</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<node>localhost</node>
<command_fail>yes</command_fail>
<command>docker exec oai-flexric bash -c "stdbuf -o0 /usr/local/flexric/xApp/c/monitor/xapp_kpm_moni" > ../cmake_targets/log/5g_rfsimulator_flexric/kpm-moni-010001.log</command>
</testCase>
<testCase id="010002">
<class>Deploy_Object</class>
<class>Custom_Command</class>
<desc>KPM monitoring and RC control</desc>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_flexric</yaml_path>
<services>xapp-kpm-rc</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<node>localhost</node>
<command_fail>yes</command_fail>
<command>docker exec oai-flexric bash -c "stdbuf -o0 /usr/local/flexric/xApp/c/kpm_rc/xapp_kpm_rc" > ../cmake_targets/log/5g_rfsimulator_flexric/kpm_rc-010002.log</command>
</testCase>
<testCase id="010003">
<class>Deploy_Object</class>
<class>Custom_Command</class>
<desc>Custom SMs monitoring</desc>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_flexric</yaml_path>
<services>xapp-custom-moni</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<node>localhost</node>
<command_fail>yes</command_fail>
<command>docker exec oai-flexric bash -c "stdbuf -o0 /usr/local/flexric/xApp/c/monitor/xapp_gtp_mac_rlc_pdcp_moni" > ../cmake_targets/log/5g_rfsimulator_flexric/sms-moni-010003.log</command>
</testCase>
<testCase id="010013">
<class>Custom_Command</class>
<desc>Custom SMs monitoring</desc>
<node>localhost</node>
<command_fail>yes</command_fail>
<command>docker exec oai-flexric bash -c "stdbuf -o0 /usr/local/flexric/xApp/c/monitor/xapp_gtp_mac_rlc_pdcp_moni" > ../cmake_targets/log/5g_rfsimulator_flexric/sms-moni-010013.log</command>
</testCase>
</testCaseList>

View File

@@ -1,118 +0,0 @@
<!--
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-Leo</htmlTabRef>
<htmlTabName>Monolithic SA NTN LEO gNB</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
111111
100001
800813
000001
000002
000003
020001
020002
100001
222222
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="111111">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<svr_id>0</svr_id>
<images>oai-gnb-asan oai-nr-ue-asan</images>
</testCase>
<testCase id="800813">
<class>Create_Workspace</class>
<desc>Create new Workspace</desc>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000001">
<class>Deploy_Object</class>
<desc>Deploy OAI 5G CoreNetwork</desc>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_ntn_leo</yaml_path>
<services>mysql oai-amf oai-smf oai-upf oai-ext-dn</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000002">
<class>Deploy_Object</class>
<desc>Deploy OAI 5G gNB+nrUE RF sim SA</desc>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_ntn_leo</yaml_path>
<services>oai-gnb oai-nr-ue</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000003">
<class>Attach_UE</class>
<desc>Attach OAI UE (Wait for IP)</desc>
<id>rfsim5g_ue</id>
<nodes>cacofonix</nodes>
</testCase>
<testCase id="020001">
<class>Ping</class>
<desc>Ping ext-dn from NR-UE</desc>
<id>rfsim5g_ue</id>
<nodes>cacofonix</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>cacofonix</svr_node>
<ping_args>-c 20 -i 0.25</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>
<nodes>cacofonix</nodes>
<svr_id>rfsim5g_ue</svr_id>
<svr_node>cacofonix</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="100001">
<class>Undeploy_Object</class>
<always_exec>true</always_exec>
<desc>Undeploy all OAI 5G stack</desc>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_ntn_leo</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="222222">
<class>Clean_Test_Server_Images</class>
<always_exec>true</always_exec>
<desc>Clean Test Images on Test Server</desc>
<svr_id>0</svr_id>
<images>oai-gnb-asan oai-nr-ue-asan</images>
</testCase>
</testCaseList>

View File

@@ -44,7 +44,7 @@
<testCase id="555000">
<class>DeployCoreNetwork</class>
<desc>Initialize 5G Core</desc>
<cn_id>oc-cn5g-20897-aerial</cn_id>
<cn_id>oc-cn5g-20897-aerial2</cn_id>
</testCase>
<testCase id="111111">
@@ -52,7 +52,6 @@
<desc>Pull Images from Local Registry</desc>
<svr_id>0</svr_id>
<images>oai-gnb-aerial</images>
<tag_prefix>arm_</tag_prefix>
</testCase>
<testCase id="800813">
@@ -90,16 +89,16 @@
<class>Ping</class>
<desc>Ping: 100pings in 20sec</desc>
<id>up2-aerial</id>
<svr_id>oc-cn5g-20897-aerial</svr_id>
<svr_id>oc-cn5g-20897-aerial2</svr_id>
<ping_args>-c 100 -i 0.2</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="000022">
<class>Iperf</class>
<desc>iperf (DL/UDP/500M)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 500M -t 30 -R</iperf_args>
<svr_id>oc-cn5g-20897-aerial</svr_id>
<desc>iperf (DL/UDP/600M)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 600M -t 30 -R</iperf_args>
<svr_id>oc-cn5g-20897-aerial2</svr_id>
<id>up2-aerial</id>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
@@ -107,9 +106,9 @@
<testCase id="000033">
<class>Iperf</class>
<desc>iperf (UL/UDP/40M)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 40M -t 30</iperf_args>
<svr_id>oc-cn5g-20897-aerial</svr_id>
<desc>iperf (UL/UDP/50M)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 50M -t 30</iperf_args>
<svr_id>oc-cn5g-20897-aerial2</svr_id>
<id>up2-aerial</id>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
@@ -145,7 +144,7 @@
<class>UndeployCoreNetwork</class>
<always_exec>true</always_exec>
<desc>Terminate 5G Core</desc>
<cn_id>oc-cn5g-20897-aerial</cn_id>
<cn_id>oc-cn5g-20897-aerial2</cn_id>
</testCase>
</testCaseList>

View File

@@ -120,12 +120,9 @@
</testCase>
<testCase id="000002">
<class>Ping</class>
<desc>Ping: 20pings</desc>
<id>idefix</id>
<svr_id>sabox-nepes</svr_id>
<ping_args>-c 20 -i0.5 -w25</ping_args>
<ping_packetloss_threshold>80</ping_packetloss_threshold>
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>10</idle_sleep_time_in_sec>
</testCase>

View File

@@ -199,12 +199,9 @@
</testCase>
<testCase id="100002">
<class>Ping</class>
<desc>Ping: 20pings</desc>
<id>idefix</id>
<svr_id>sabox-nepes</svr_id>
<ping_args>-c 20 -i0.5 -w25</ping_args>
<ping_packetloss_threshold>80</ping_packetloss_threshold>
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>10</idle_sleep_time_in_sec>
</testCase>
<testCase id="330201">

View File

@@ -134,12 +134,9 @@
</testCase>
<testCase id="100002">
<class>Ping</class>
<desc>Ping: 20pings</desc>
<id>idefix</id>
<svr_id>sabox-nepes</svr_id>
<ping_args>-c 20 -i0.5 -w25</ping_args>
<ping_packetloss_threshold>80</ping_packetloss_threshold>
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>10</idle_sleep_time_in_sec>
</testCase>
<testCase id="150000">

View File

@@ -53,10 +53,11 @@
</testCase>
<testCase id="110000">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<svr_id>0</svr_id>
<class>Pull_Cluster_Image</class>
<desc>Pull Images from Cluster</desc>
<oc_project>oaicicd-ran</oc_project>
<images>oai-gnb-fhi72</images>
<node>cacofonix</node>
</testCase>
<testCase id="800813">
<class>Create_Workspace</class>
@@ -90,8 +91,8 @@
<testCase id="100010">
<class>Iperf</class>
<desc>iperf (DL/600Mbps/UDP)(30 sec)(multi-ue profile)</desc>
<iperf_args>-u -b 600M -t 30 -R</iperf_args>
<desc>iperf (DL/300Mbps/UDP)(30 sec)(multi-ue profile)</desc>
<iperf_args>-u -b 300M -t 30 -R</iperf_args>
<id>up2-fhi72</id>
<iperf_packetloss_threshold>20</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
@@ -110,8 +111,8 @@
<testCase id="100020">
<class>Iperf</class>
<desc>iperf (UL/80Mbps/UDP)(30 sec)(multi-ue profile)</desc>
<iperf_args>-u -b 80M -t 30</iperf_args>
<desc>iperf (UL/70Mbps/UDP)(30 sec)(multi-ue profile)</desc>
<iperf_args>-u -b 70M -t 30</iperf_args>
<id>up2-fhi72</id>
<iperf_packetloss_threshold>20</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
@@ -124,7 +125,7 @@
<desc>iperf (UL/TCP)(30 sec)(multi-ue profile)</desc>
<iperf_args>-t 30</iperf_args>
<id>up2-fhi72</id>
<iperf_tcp_rate_target>10</iperf_tcp_rate_target>
<iperf_tcp_rate_target>40</iperf_tcp_rate_target>
<svr_id>oc-cn5g-20897</svr_id>
</testCase>

View File

@@ -0,0 +1,49 @@
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>TEST-GH-AERIAL-SA</htmlTabRef>
<htmlTabName>Gracehopper AERIAL 100 MHz TDD SA</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<TestCaseRequestedList>
111111
333333
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="111111">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<svr_id>0</svr_id>
<images>oai-gnb-aerial</images>
<tag_prefix>arm_</tag_prefix>
</testCase>
<testCase id="333333">
<class>Clean_Test_Server_Images</class>
<always_exec>true</always_exec>
<desc>Clean Test Images on Test Server</desc>
<svr_id>0</svr_id>
<images>oai-gnb-aerial</images>
</testCase>
</testCaseList>

View File

@@ -116,8 +116,8 @@
<testCase id="071000">
<class>Iperf</class>
<desc>iperf (DL/450Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 450M -t 30 -R</iperf_args>
<desc>iperf (DL/480Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 480M -t 30 -R</iperf_args>
<svr_id>matix-cn5g</svr_id>
<id>up2</id>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>

View File

@@ -114,12 +114,9 @@
</testCase>
<testCase id="200002">
<class>Ping</class>
<desc>Ping: 20pings</desc>
<id>idefix</id>
<svr_id>sabox-nepes</svr_id>
<ping_args>-c 20 -i0.5 -w25</ping_args>
<ping_packetloss_threshold>80</ping_packetloss_threshold>
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>10</idle_sleep_time_in_sec>
</testCase>

View File

@@ -21,7 +21,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.1.9
image: oaisoftwarealliance/oai-amf:v2.0.0
environment:
- TZ=Europe/paris
volumes:
@@ -33,7 +33,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.1.9
image: oaisoftwarealliance/oai-smf:v2.0.0
environment:
- TZ=Europe/Paris
volumes:
@@ -45,7 +45,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.1.9
image: oaisoftwarealliance/oai-upf:v2.0.0
environment:
- TZ=Europe/Paris
volumes:

View File

@@ -21,7 +21,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.1.9
image: oaisoftwarealliance/oai-amf:v2.0.0
environment:
- TZ=Europe/paris
volumes:
@@ -33,7 +33,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.1.9
image: oaisoftwarealliance/oai-smf:v2.0.0
environment:
- TZ=Europe/Paris
volumes:
@@ -45,7 +45,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.1.9
image: oaisoftwarealliance/oai-upf:v2.0.0
environment:
- TZ=Europe/Paris
volumes:

View File

@@ -37,9 +37,9 @@ Now pull images.
```bash
$ docker pull mysql:8.0
$ docker pull oaisoftwarealliance/oai-amf:v2.1.9
$ docker pull oaisoftwarealliance/oai-smf:v2.1.9
$ docker pull oaisoftwarealliance/oai-upf:v2.1.9
$ docker pull oaisoftwarealliance/oai-amf:v2.0.0
$ docker pull oaisoftwarealliance/oai-smf:v2.0.0
$ docker pull oaisoftwarealliance/oai-upf:v2.0.0
$ docker pull oaisoftwarealliance/trf-gen-cn5g:focal
$ docker pull oaisoftwarealliance/oai-gnb:develop
@@ -52,7 +52,7 @@ $ docker logout
**CAUTION: 2023/01/27 with the release `v1.5.0` of the `CN5G`, the previous version was not compatible any-more.**
**This new version is working only with the `v2.1.9` of the `CN5G`.**
**This new version is working only with the `v2.0.0` of the `CN5G`.**
# 2. Deploy containers #

View File

@@ -21,7 +21,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.1.9
image: oaisoftwarealliance/oai-amf:v2.0.0
environment:
- TZ=Europe/paris
volumes:
@@ -33,7 +33,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.1.9
image: oaisoftwarealliance/oai-smf:v2.0.0
environment:
- TZ=Europe/Paris
volumes:
@@ -45,7 +45,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.1.9
image: oaisoftwarealliance/oai-upf:v2.0.0
environment:
- TZ=Europe/Paris
volumes:

View File

@@ -21,7 +21,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.1.9
image: oaisoftwarealliance/oai-amf:v2.0.0
environment:
- TZ=Europe/paris
volumes:
@@ -33,7 +33,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.1.9
image: oaisoftwarealliance/oai-smf:v2.0.0
environment:
- TZ=Europe/Paris
volumes:
@@ -45,7 +45,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.1.9
image: oaisoftwarealliance/oai-upf:v2.0.0
environment:
- TZ=Europe/Paris
volumes:

View File

@@ -21,7 +21,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.1.9
image: oaisoftwarealliance/oai-amf:v2.0.0
environment:
- TZ=Europe/paris
volumes:
@@ -33,7 +33,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.1.9
image: oaisoftwarealliance/oai-smf:v2.0.0
environment:
- TZ=Europe/Paris
volumes:
@@ -45,7 +45,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.1.9
image: oaisoftwarealliance/oai-upf:v2.0.0
environment:
- TZ=Europe/Paris
volumes:

View File

@@ -21,7 +21,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.1.9
image: oaisoftwarealliance/oai-amf:v2.0.0
environment:
- TZ=Europe/paris
volumes:
@@ -33,7 +33,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.1.9
image: oaisoftwarealliance/oai-smf:v2.0.0
environment:
- TZ=Europe/Paris
volumes:
@@ -45,7 +45,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.1.9
image: oaisoftwarealliance/oai-upf:v2.0.0
environment:
- TZ=Europe/Paris
volumes:

View File

@@ -1,5 +1,5 @@
[NEAR-RIC]
NEAR_RIC_IP = 192.168.70.150
[XAPP]
DB_DIR = /tmp/
DB_PATH = /flexric/db/
DB_NAME = xapp_rnis_db

View File

@@ -13,82 +13,6 @@ services:
interval: 10s
timeout: 5s
xapp-rc-moni:
image: ${REGISTRY:-oaisoftwarealliance}/oai-flexric:${FLEXRIC_TAG:-develop}
command: "stdbuf -o0 /usr/local/flexric/xApp/c/monitor/xapp_rc_moni"
container_name: xapp-rc-moni
environment:
- XAPP_DURATION=20 # 20s is a default value
depends_on:
- oai-flexric
- oai-gnb
networks:
public_net:
ipv4_address: 192.168.70.154
volumes:
- ./conf/flexric.conf:/usr/local/etc/flexric/flexric.conf
healthcheck:
test: /bin/bash -c "pgrep xapp_rc_moni"
interval: 10s
timeout: 5s
xapp-kpm-moni:
image: ${REGISTRY:-oaisoftwarealliance}/oai-flexric:${FLEXRIC_TAG:-develop}
command: "stdbuf -o0 /usr/local/flexric/xApp/c/monitor/xapp_kpm_moni"
container_name: xapp-kpm-moni
environment:
- XAPP_DURATION=20 # 20s is a default value
depends_on:
- oai-flexric
- oai-gnb
networks:
public_net:
ipv4_address: 192.168.70.155
volumes:
- ./conf/flexric.conf:/usr/local/etc/flexric/flexric.conf
healthcheck:
test: /bin/bash -c "pgrep xapp_kpm_moni"
interval: 10s
timeout: 5s
xapp-kpm-rc:
image: ${REGISTRY:-oaisoftwarealliance}/oai-flexric:${FLEXRIC_TAG:-develop}
command: "stdbuf -o0 /usr/local/flexric/xApp/c/kpm_rc/xapp_kpm_rc"
container_name: xapp-kpm-rc
environment:
- XAPP_DURATION=20 # 20s is a default value
depends_on:
- oai-flexric
- oai-gnb
networks:
public_net:
ipv4_address: 192.168.70.156
volumes:
- ./conf/flexric.conf:/usr/local/etc/flexric/flexric.conf
healthcheck:
test: /bin/bash -c "pgrep xapp_kpm_rc"
interval: 10s
timeout: 5s
xapp-custom-moni:
image: ${REGISTRY:-oaisoftwarealliance}/oai-flexric:${FLEXRIC_TAG:-develop}
command: "stdbuf -o0 /usr/local/flexric/xApp/c/monitor/xapp_gtp_mac_rlc_pdcp_moni"
container_name: xapp-custom-moni
environment:
- XAPP_DURATION=20 # 20s is a default value
depends_on:
- oai-flexric
- oai-gnb
networks:
public_net:
ipv4_address: 192.168.70.157
volumes:
- ./conf/flexric.conf:/usr/local/etc/flexric/flexric.conf
healthcheck:
test: /bin/bash -c "pgrep xapp_gtp_mac_rlc_pdcp_moni"
interval: 10s
timeout: 5s
oai-gnb:
image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop}
privileged: true

View File

@@ -21,7 +21,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.1.9
image: oaisoftwarealliance/oai-amf:v2.0.0
environment:
- TZ=Europe/paris
volumes:
@@ -33,7 +33,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.1.9
image: oaisoftwarealliance/oai-smf:v2.0.0
environment:
- TZ=Europe/Paris
volumes:
@@ -45,7 +45,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.1.9
image: oaisoftwarealliance/oai-upf:v2.0.0
environment:
- TZ=Europe/Paris
volumes:

View File

@@ -21,7 +21,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.1.9
image: oaisoftwarealliance/oai-amf:v2.0.0
environment:
- TZ=Europe/paris
volumes:
@@ -33,7 +33,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.1.9
image: oaisoftwarealliance/oai-smf:v2.0.0
environment:
- TZ=Europe/Paris
volumes:
@@ -45,7 +45,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.1.9
image: oaisoftwarealliance/oai-upf:v2.0.0
environment:
- TZ=Europe/Paris
volumes:
@@ -110,7 +110,7 @@ services:
- NET_ADMIN # for interface bringup
- NET_RAW # for ping
environment:
USE_ADDITIONAL_OPTIONS: --band 254 -C 2488400000 --CO -873500000 -r 25 --numerology 0 --ssb 60 --rfsim --rfsimulator.prop_delay 238.74 --rfsimulator.serveraddr 192.168.71.140 --num-ul-actors 1 --log_config.global_log_options level,nocolor,time
USE_ADDITIONAL_OPTIONS: --band 254 -C 2488400000 --CO -873500000 -r 25 --numerology 0 --ssb 60 --rfsim --rfsimulator.prop_delay 238.74 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
depends_on:
- oai-gnb
networks:

View File

@@ -1,152 +0,0 @@
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.1.9
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.1.9
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.1.9
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: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop}
container_name: rfsim5g-oai-gnb
cap_drop:
- ALL
environment:
USE_ADDITIONAL_OPTIONS: --rfsim --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.band254.u0.25prb.rfsim.ntn-leo.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: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-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 254 -C 2488400000 --CO -873500000 -r 25 --numerology 0 --ssb 60
--rfsim --rfsimulator.prop_delay 20 --rfsimulator.options chanmod
--rfsimulator.serveraddr 192.168.71.140
--time-sync-I 0.1 --ntn-initial-time-drift -46
--autonomous-ta --initial-fo 57340 --cont-fo-comp 2
--log_config.global_log_options level,nocolor,time
--num-ul-actors 1
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.ntn-leo.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"

View File

@@ -21,7 +21,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.1.9
image: oaisoftwarealliance/oai-amf:v2.0.0
environment:
- TZ=Europe/paris
volumes:
@@ -33,7 +33,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.1.9
image: oaisoftwarealliance/oai-smf:v2.0.0
environment:
- TZ=Europe/Paris
volumes:
@@ -45,7 +45,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.1.9
image: oaisoftwarealliance/oai-upf:v2.0.0
environment:
- TZ=Europe/Paris
volumes:

View File

@@ -16,7 +16,7 @@ services:
- ../../conf_files/gnb-vnf.sa.band77.162prb.nfapi.4x4.conf:/opt/oai-gnb/etc/gnb.conf
healthcheck:
test: /bin/bash -c "pgrep nr-softmodem"
interval: 15s
interval: 10s
timeout: 5s
retries: 5
oai-pnf:
@@ -36,6 +36,6 @@ services:
- ../../conf_files/gnb-pnf.band77.usrpn310.4x4.conf:/opt/oai-gnb/etc/gnb.conf
healthcheck:
test: /bin/bash -c "pgrep nr-softmodem"
interval: 15s
interval: 10s
timeout: 5s
retries: 5

View File

@@ -9,7 +9,7 @@ services:
environment:
USE_ADDITIONAL_OPTIONS: --telnetsrv --telnetsrv.listenport 9090 --telnetsrv.shrmod ci
--log_config.global_log_options level,nocolor,time,line_num,function
--security.drb_integrity no
--security.drb_integrity yes
volumes:
- ../../conf_files/gnb-cucp.sa.f1.quectel.conf:/opt/oai-gnb/etc/gnb.conf
# for performance reasons, we use host mode: in bridge mode, we have

View File

@@ -2,6 +2,7 @@ services:
oai-gnb:
image: ${REGISTRY:-oaisoftwarealliance}/oai-gnb-fhi72:${TAG:-develop}
cap_add:
- SYS_ADMIN
- IPC_LOCK
- SYS_NICE
cap_drop:
@@ -9,14 +10,14 @@ services:
container_name: oai-gnb
environment:
TZ: Europe/Paris
USE_ADDITIONAL_OPTIONS: --thread-pool 7,8,9,10,11,12
USE_ADDITIONAL_OPTIONS: --thread-pool 6,7,8,9
devices:
- /dev/vfio:/dev/vfio/
volumes:
- ../../conf_files/gnb.sa.band77.273prb.fhi72.4x4-vvdn.conf:/opt/oai-gnb/etc/gnb.conf
- /dev/hugepages:/dev/hugepages
# Please change these values based on your system
cpuset: "0,1,2,3,4,5,6,7,8,9,10,11,12"
cpuset: "0,1,2,3,4,5,6,7,8,9"
networks:
oai-net:
ipv4_address: 172.21.18.20

View File

@@ -24,7 +24,7 @@ sudo -E echo start_server -uid 0 | sudo -E nvidia-cuda-mps-control
# Check if an argument is provided
if [ $# -eq 0 ]; then
# No argument provided, use default value
argument="P5G_FXN_GH"
argument="P5G_FXN"
else
# Argument provided, use it
argument="$1"

View File

@@ -23,7 +23,7 @@ services:
- ../../../cmake_targets/share:/opt/cuBB/share
userns_mode: host
ipc: "shareable"
image: cubb-build:24-3
image: cubb-build:24-1
environment:
- cuBB_SDK=/opt/nvidia/cuBB
command: bash -c "sudo rm -rf /tmp/phy.log && sudo chmod +x /opt/nvidia/cuBB/aerial_l1_entrypoint.sh && /opt/nvidia/cuBB/aerial_l1_entrypoint.sh"

View File

@@ -107,18 +107,3 @@ or directly with
")
endif()
endfunction()
function(run_asn1c ASN1C_GRAMMAR ASN1C_PREFIX)
set(options "")
set(oneValueArgs COMMENT)
set(multiValueArgs OUTPUT OPTIONS)
cmake_parse_arguments(ASN1C "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
get_filename_component(GRAMMAR_FILE ${ASN1C_GRAMMAR} NAME)
set(LOGFILE "${CMAKE_CURRENT_BINARY_DIR}/${GRAMMAR_FILE}.log")
add_custom_command(OUTPUT ${ASN1C_OUTPUT}
COMMAND ASN1C_PREFIX=${ASN1C_PREFIX} ${ASN1C_EXEC} ${ASN1C_OPTIONS} -D ${CMAKE_CURRENT_BINARY_DIR} ${ASN1C_GRAMMAR} > ${LOGFILE} 2>&1 || cat ${LOGFILE}
DEPENDS ${ASN1C_GRAMMAR}
COMMENT "Generating ${ASN1C_COMMENT} from ${GRAMMAR_FILE}"
)
endfunction()

View File

@@ -1,123 +0,0 @@
#
# 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
#
# FindArmral
# -------
#
# Finds the armral library.
# the version is currently hardcoded to 25.01
#
# Optional options
# ^^^^^^^^^^^^^^^^
#
# ``armral_LOCATION``
# The location of the library.
#
# Imported Targets
# ^^^^^^^^^^^^^^^^
#
# This module provides the following imported targets, if found:
#
# ``armral``
# The armral library
#
# Result Variables
# ^^^^^^^^^^^^^^^^
#
# This will define the following variables:
#
# ``armral_FOUND``
# True if the system has the armral library.
# ``armral_VERSION``
# The version of the armral library which was found.
# ``armral_INCLUDE_DIRS``
# Include directories needed to use armral.
# ``armral_LIBRARIES``
# Libraries needed to link to armral.
#
# Cache Variables
# ^^^^^^^^^^^^^^^
#
# The following cache variables may also be set:
#
# ``armral_INCLUDE_DIR``
# The directory containing ``armral.h``.
# ``armral_LIBRARY``
# The path to the armral library.
option(armral_LOCATION "directory of ArmRAL library" "")
if (NOT armral_LOCATION)
set(armral_LOCATION "/usr/local")
endif()
if (NOT EXISTS ${armral_LOCATION})
message(FATAL_ERROR "no such directory: ${armral_LOCATION}")
endif()
find_path(armral_INCLUDE_DIR
NAMES
armral.h
HINTS ${armral_LOCATION}
PATH_SUFFIXES include
NO_DEFAULT_PATH
)
if (NOT armral_INCLUDE_DIR)
message(FATAL_ERROR "could not detect armral header at ${armral_LOCATION}/include")
endif()
find_library(armral_LIBRARY
NAMES armral
HINTS ${armral_LOCATION}
PATH_SUFFIXES lib build
NO_DEFAULT_PATH
)
if (NOT armral_LIBRARY)
message(FATAL_ERROR "could not detect armral build artifacts at neither ${armral_LOCATION}/lib nor ${armral_LOCATION}/build")
endif()
# No way to retrieve the version from header or library
set(armral_VERSION 25.01)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(armral
FOUND_VAR armral_FOUND
REQUIRED_VARS
armral_LIBRARY
armral_INCLUDE_DIR
VERSION_VAR armral_VERSION
)
if(armral_FOUND)
set(armral_LIBRARIES ${armral_LIBRARY})
set(armral_INCLUDE_DIRS ${armral_INCLUDE_DIR})
endif()
if(armral_FOUND AND NOT TARGET armral)
add_library(armral UNKNOWN IMPORTED)
set_target_properties(armral PROPERTIES
IMPORTED_LOCATION "${armral_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${armral_INCLUDE_DIRS}"
)
endif()
mark_as_advanced(
armral_INCLUDE_DIR
armral_LIBRARY
)

View File

@@ -24,12 +24,6 @@
#include <stdint.h>
typedef struct plmn_id_s {
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
} plmn_id_t;
typedef struct nssai_s {
uint8_t sst;
uint32_t sd;

View File

@@ -167,20 +167,4 @@ typedef struct paramlist_def {
int numelt ;
} paramlist_def_t;
/* Macros to get parameters with the config module API */
#define GET_PARAMS(param_def, param_desc, prefix) \
printf("Reading '%s' section from the config file\n", #param_def); \
paramdef_t param_def[] = param_desc; \
config_get(config_get_if(), param_def, sizeofArray(param_def), prefix);
/* Macros to get params lists with the config module API */
#define GET_PARAMS_LIST(param_list, param_def, param_desc, list_name, prefix, ...) \
paramdef_t param_def[] = param_desc; \
paramlist_def_t param_list = {list_name, NULL, 0}; \
__VA_OPT__(checkedparam_t config_check_##param_def[] = __VA_ARGS__; \
static_assert(sizeofArray(config_check_##param_def) == sizeofArray(param_def), \
"param_def_t array and corresponding checkedparam_t array should have the same size"); \
for (int i = 0; i < sizeofArray(param_def); ++i) param_def[i].chkPptr = &(config_check_##param_def[i]);) \
config_getlist(config_get_if(), &param_list, param_def, sizeofArray(param_def), prefix);
#endif /* INCLUDE_CONFIG_PARAMDESC_H */

View File

@@ -80,8 +80,6 @@
#define NB_RAB_MAX 11 /* from LTE_maxDRB in LTE_asn_constant.h */
#define RAB_OFFSET 0x000F
#define MAX_NUM_SLICES 1024
// RLC Entity
#define RLC_TX_MAXSIZE 10000000
#define RLC_RX_MAXSIZE 10000000
@@ -95,6 +93,5 @@
#define RETURNerror (-1)
#define DEFAULT_NAS_PATH "PWD"
#define UNUSED_VARIABLE(vARIABLE) (void)(vARIABLE)
#define NUM_PRACH_RX_FOR_NOISE_ESTIMATE 100
#endif /* __PLATFORM_CONSTANTS_H__ */

View File

@@ -13,7 +13,6 @@ add_subdirectory(T)
add_subdirectory(nr)
add_subdirectory(LOG)
add_subdirectory(threadPool)
add_subdirectory(time_manager)
add_library(utils utils.c system.c time_meas.c time_stat.c tun_if.c)
target_include_directories(utils PUBLIC .)
target_link_libraries(utils PRIVATE ${T_LIB})

View File

@@ -157,19 +157,14 @@ int write_file_matlab(const char *fname, const char *vname, void *data, int leng
//printf("Writing %d elements of type %d to %s\n",length,format,fname);
const int fname_len = strlen(fname);
char write_file_name[fname_len + 10];
const char *fn_format = (format & MATLAB_RAW) ? "%s.bin" : "%s";
snprintf(write_file_name, sizeof(write_file_name), fn_format, fname);
if (format == 10 || format ==11 || format == 12 || format == 13 || format == 14 || multiVec) {
fp = fopen(write_file_name, "a+");
fp = fopen(fname,"a+");
} else if (format != 10 && format !=11 && format != 12 && format != 13 && format != 14) {
fp = fopen(write_file_name, "w+");
fp = fopen(fname,"w+");
}
if (fp== NULL) {
printf("[OPENAIR][FILE OUTPUT] Cannot open file %s\n", write_file_name);
printf("[OPENAIR][FILE OUTPUT] Cannot open file %s\n",fname);
return(-1);
}

View File

@@ -36,7 +36,6 @@
#include "common/utils/LOG/log.h"
#include "nr_common.h"
#include <limits.h>
#include <math.h>
#define C_SRS_NUMBER (64)
#define B_SRS_NUMBER (4)
@@ -1428,15 +1427,3 @@ frequency_range_t get_freq_range_from_band(uint16_t band)
{
return band <= 256 ? FR1 : FR2;
}
float get_beta_dmrs_pusch(int num_cdm_groups_no_data, pusch_dmrs_type_t dmrs_type)
{
float beta_dmrs_pusch = 1.0;
if (num_cdm_groups_no_data == 2) {
beta_dmrs_pusch = powf(10.0, 3.0 / 20.0);
} else if (num_cdm_groups_no_data == 3) {
if (dmrs_type == pusch_dmrs_type2)
beta_dmrs_pusch = powf(10.0, 4.77 / 20.0);
}
return beta_dmrs_pusch;
}

View File

@@ -38,7 +38,6 @@
#include "assertions.h"
#include "common/utils/utils.h"
#define MAX_SI_GROUPS 3
#define NR_MAX_PDSCH_TBS 3824
#define MAX_NUM_BEAM_PERIODS 4
#define MAX_BWP_SIZE 275
@@ -85,7 +84,6 @@ static inline const char *rnti_types(nr_rnti_type_t rr)
#define MU_SCS(m) (15 << m)
#define MAX_GSCN_BAND 620 // n78 has the highest GSCN range of 619
#define NR_NUMBER_OF_SYMBOLS_PER_SLOT 14
#define NR_NUMBER_OF_SYMBOLS_PER_SLOT_EXTENDED_CP 12
#define NR_MAX_NB_LAYERS 4 // 8
// Since the IQ samples are represented by SQ15 R+I (see https://en.wikipedia.org/wiki/Q_(number_format)) we need to compensate when
@@ -94,12 +92,6 @@ static inline const char *rnti_types(nr_rnti_type_t rr)
// the total shift is 2 * 15, in dB scale thats 10log10(2^(15*2))
#define SQ15_SQUARED_NORM_FACTOR_DB 90.3089986992
typedef struct {
uint8_t *SIB_buffer;
int SIB_size;
int SIB_type;
} nr_SIBs_t;
typedef struct nr_bandentry_s {
int16_t band;
uint64_t ul_min;
@@ -130,11 +122,6 @@ typedef enum frequency_range_e {
FR2
} frequency_range_t;
typedef enum {
pusch_dmrs_type1 = 0,
pusch_dmrs_type2 = 1
} pusch_dmrs_type_t;
#define MAX_NUM_SLOTS_ALLOWED 80 // up to numerology 3 (120 KHz SCS) is supported
enum slot_type { TDD_NR_DOWNLINK_SLOT, TDD_NR_UPLINK_SLOT, TDD_NR_MIXED_SLOT };
@@ -307,17 +294,6 @@ frequency_range_t get_freq_range_from_freq(uint64_t freq);
frequency_range_t get_freq_range_from_arfcn(uint32_t arfcn);
frequency_range_t get_freq_range_from_band(uint16_t band);
/**
* @brief Calculates the scaling factor for the ratio of PUSCH EPRE to DMRS EPRE.
*
* @param num_cdm_groups_no_data The number of CDM groups without data.
* @param dmrs_type The DMRS type.
* @return The calculated beta scaling factor for the ratio of PUSCH EPRE to DMRS EPRE.
*
* @note The values are derived from TS 38.214 Table 6.2.2-1.
*/
float get_beta_dmrs_pusch(int num_cdm_groups_no_data, pusch_dmrs_type_t dmrs_type);
#define CEILIDIV(a,b) ((a+b-1)/b)
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))

View File

@@ -228,9 +228,5 @@ static inline uint64_t BIT_STRING_to_uint64(const BIT_STRING_t *asn) {
free(STRUCT); \
STRUCT = NULL; \
} while (0)
#define asn1cFreeSeq(ASN_DEF, LIST) \
do { \
ASN_STRUCT_FREE(ASN_DEF, LIST.array[--LIST.count]); \
} while (LIST.count > 0) \
#endif

View File

@@ -141,29 +141,6 @@ int trigger_reestab(char *buf, int debug, telnet_printfunc_t prnt)
return 0;
}
extern nr_rrc_du_container_t *get_du_for_ue(gNB_RRC_INST *rrc, uint32_t ue_id);
/** @brief Get connected DU by the UE ID */
int fetch_du_by_ue_id(char *buf, int debug, telnet_printfunc_t prnt)
{
if (!RC.nrrrc)
ERROR_MSG_RET("no RRC present, cannot list counts\n");
ue_id_t ue_id = 1;
if (buf) {
ue_id = strtol(buf, NULL, 10);
}
nr_rrc_du_container_t *du = get_du_for_ue(RC.nrrrc[0], ue_id);
if (du) {
prnt("gNB_DU_id %d is connected to ue_id %ld\n", du->setup_req->gNB_DU_id, ue_id);
return 0;
} else {
ERROR_MSG_RET("No DU connected\n");
return -1;
}
}
extern void nr_HO_F1_trigger_telnet(gNB_RRC_INST *rrc, uint32_t rrc_ue_id);
/**
* @brief Trigger F1 handover for UE
@@ -222,7 +199,6 @@ static telnetshell_cmddef_t cicmds[] = {
{"force_ue_release", "[rnti(hex,opt)]", force_ue_release},
{"force_ul_failure", "[rnti(hex,opt)]", force_ul_failure},
{"trigger_f1_ho", "[rrc_ue_id(int,opt)]", rrc_gNB_trigger_f1_ho},
{"fetch_du_by_ue_id", "[rrc_ue_id(int,opt)]", fetch_du_by_ue_id},
{"", "", NULL},
};

View File

@@ -1,14 +0,0 @@
add_library(time_management STATIC
time_manager.c)
add_library(time_management_core OBJECT
time_source.c
time_server.c
time_client.c)
target_link_libraries(time_management PUBLIC time_management_core)
target_link_libraries(time_management_core PRIVATE ${T_LIB})
if(ENABLE_TESTS)
add_subdirectory(tests)
endif()

View File

@@ -1,11 +0,0 @@
add_executable(test_time_manager_manual test_manual.c)
target_link_libraries(test_time_manager_manual time_management_core)
target_link_libraries(test_time_manager_manual LOG CONFIG_LIB)
add_executable(test_time_manager_auto test_auto.c)
target_link_libraries(test_time_manager_auto time_management)
target_link_libraries(test_time_manager_auto LOG CONFIG_LIB)
add_dependencies(tests test_time_manager_auto)
add_test(NAME time_management_tests
COMMAND ./test_time_manager_auto)

View File

@@ -1,297 +0,0 @@
/*
* 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
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include "common/utils/time_manager/time_manager.h"
#include "common/utils/LOG/log.h"
#include "common/config/config_userapi.h"
configmodule_interface_t *uniqCfg = NULL;
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
{
if (s != NULL) {
printf("%s:%d %s() Exiting OAI softmodem: %s\n", file, line, function, s);
}
if (assert)
abort();
else
exit(1);
}
static int rlc_tick_count = 0;
static int pdcp_tick_count = 0;
static int x2ap_tick_count = 0;
void nr_rlc_ms_tick(void)
{
rlc_tick_count++;
}
void nr_pdcp_ms_tick(void)
{
pdcp_tick_count++;
}
void x2ap_ms_tick(void)
{
x2ap_tick_count++;
}
/* return 1 if ok, 0 if error */
static int standalone_realtime(void)
{
time_manager_tick_function_t tick_functions[] = {
nr_pdcp_ms_tick,
nr_rlc_ms_tick,
x2ap_ms_tick
};
int tick_functions_count = sizeofArray(tick_functions);
time_manager_start(tick_functions, tick_functions_count, TIME_SOURCE_REALTIME);
sleep(1);
time_manager_finish();
LOG_I(UTIL,
"standalone realtime: rlc ticks: %d pdcp ticks: %d x2ap ticks: %d\n",
rlc_tick_count,
pdcp_tick_count,
x2ap_tick_count);
/* let's accept 1% deviation from the 1000 counts we expect */
return abs(rlc_tick_count-1000) < 10
&& abs(pdcp_tick_count - 1000) < 10
&& abs(x2ap_tick_count - 1000) < 10;
}
/* return 1 if ok, 0 if error */
static int standalone_iq_samples(void)
{
time_manager_tick_function_t tick_functions[] = {
nr_pdcp_ms_tick,
nr_rlc_ms_tick,
x2ap_ms_tick
};
int tick_functions_count = sizeofArray(tick_functions);
time_manager_start(tick_functions, tick_functions_count, TIME_SOURCE_IQ_SAMPLES);
/* let's pretend we have 2000 samples per second */
for (int i = 0; i < 1000; i++) {
time_manager_iq_samples(1, 2000);
usleep(10);
time_manager_iq_samples(1, 2000);
usleep(10);
}
time_manager_finish();
LOG_I(UTIL,
"standalone iq-samples: rlc ticks: %d pdcp ticks: %d x2ap ticks: %d\n",
rlc_tick_count,
pdcp_tick_count,
x2ap_tick_count);
/* exact count is required */
return rlc_tick_count == 1000
&& pdcp_tick_count == 1000
&& x2ap_tick_count == 1000;
}
/* return 1 if ok, 0 if error */
static int client_server(char *program_name, bool iq_samples_time_source)
{
LOG_I(UTIL, "client/server %s: launch sub-processes\n", iq_samples_time_source ? "iq-samples" : "realtime");
pid_t server;
pid_t client;
/* start server */
server = fork();
DevAssert(server >= 0);
if (server == 0) {
/* run as server */
if (iq_samples_time_source)
execl(program_name, program_name, "--time_management.mode", "server", "--time_management.time_source", "iq_samples", NULL);
else
execl(program_name, program_name, "--time_management.mode", "server", NULL);
exit(1);
}
/* wait a little bit so that server is ready to accept clients
* (this is hackish)
*/
usleep(100);
/* start client */
client = fork();
DevAssert(client >= 0);
if (client == 0) {
/* run as client */
execl(program_name, program_name, "--time_management.mode", "client", NULL);
exit(1);
}
/* wait for completion */
int ret = 1;
int status;
pid_t r = waitpid(server, &status, 0);
DevAssert(r == server);
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
ret = 0;
r = waitpid(client, &status, 0);
DevAssert(r == client);
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
ret = 0;
return ret;
}
/* return 1 if ok, 0 if error */
static int run_sub_client_server(bool iq_samples_time_source)
{
time_manager_tick_function_t tick_functions[] = {
nr_pdcp_ms_tick,
nr_rlc_ms_tick,
x2ap_ms_tick
};
int tick_functions_count = sizeofArray(tick_functions);
/* last argument doesn't matter, overwritten by args of execl in client_server() */
time_manager_start(tick_functions, tick_functions_count, TIME_SOURCE_REALTIME);
if (iq_samples_time_source) {
/* 'iq_samples_time_source' is true only for server
* wait a bit for client to be there otherwise server
* may finish too early
*/
usleep(100);
/* let's pretend we have 2000 samples per second */
for (int i = 0; i < 1000; i++) {
time_manager_iq_samples(1, 2000);
usleep(10);
time_manager_iq_samples(1, 2000);
usleep(10);
}
} else {
sleep(1);
}
time_manager_finish();
LOG_I(UTIL, "client/server: rlc ticks: %d pdcp ticks: %d x2ap ticks: %d\n", rlc_tick_count, pdcp_tick_count, x2ap_tick_count);
if (iq_samples_time_source)
return rlc_tick_count == 1000
&& pdcp_tick_count == 1000
&& x2ap_tick_count == 1000;
else
/* let's accept 1% deviation from the 1000 counts we expect */
return abs(rlc_tick_count-1000) < 10
&& abs(pdcp_tick_count - 1000) < 10
&& abs(x2ap_tick_count - 1000) < 10;
}
int main(int argc, char **argv)
{
if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == NULL) {
exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
}
logInit();
/* for client/server tests, we use sub-processes with command line parameters */
if (argc > 1) {
/* if there are command line parameters then it's a sub-process */
rlc_tick_count = 0;
pdcp_tick_count = 0;
x2ap_tick_count = 0;
/* return value to the main test program
* let's do as for the shell: 0 means success and 1 means error
*/
/* we know we are in iq-samples time source mode if the last argument is "iq_samples" */
int success = run_sub_client_server(!strcmp(argv[argc - 1], "iq_samples")) == 1;
return 1 - success;
}
int err = 0;
/* test standalone realtime */
rlc_tick_count = 0;
pdcp_tick_count = 0;
x2ap_tick_count = 0;
int ret = standalone_realtime();
if (ret == 1)
LOG_I(UTIL, "standalone realtime: OK\n");
else {
LOG_E(UTIL, "standalone realtime: ERROR\n");
err = 1;
}
/* test standalone iq-samples */
rlc_tick_count = 0;
pdcp_tick_count = 0;
x2ap_tick_count = 0;
ret = standalone_iq_samples();
if (ret == 1)
LOG_I(UTIL, "standalone iq-samples: OK\n");
else {
LOG_E(UTIL, "standalone iq-samples: ERROR\n");
err = 1;
}
/* client/server tests are not written in a robust way
* they may fail depending on realtime on the machine
* de-activate if needed (if CI fails)
*/
/* test client/server realtime */
rlc_tick_count = 0;
pdcp_tick_count = 0;
x2ap_tick_count = 0;
ret = client_server(argv[0], false);
if (ret == 1)
LOG_I(UTIL, "client-server realtime: OK\n");
else {
LOG_E(UTIL, "client-server realtime: ERROR\n");
err = 1;
}
/* test client/server iq-samples */
rlc_tick_count = 0;
pdcp_tick_count = 0;
x2ap_tick_count = 0;
ret = client_server(argv[0], true);
if (ret == 1)
LOG_I(UTIL, "client-server iq-samples: OK\n");
else {
LOG_E(UTIL, "client-server iq-samples: ERROR\n");
err = 1;
}
logTerm();
return err;
}

View File

@@ -1,175 +0,0 @@
/*
* 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
*/
#include "../time_source.h"
#include "../time_server.h"
#include "../time_client.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <stdbool.h>
#include <signal.h>
#include "common/utils/system.h"
#include "common/utils/LOG/log.h"
#include "common/config/config_userapi.h"
configmodule_interface_t *uniqCfg = NULL;
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
{
printf("%s:%d:%s: %s\n", file, line, function, s);
fflush(stdout);
exit(1);
}
_Atomic bool test_exit;
static void *iq_generate_thread(void *ts)
{
time_source_t *time_source = ts;
while (!test_exit) {
printf("iq_generate_thread calls time_source_iq_add(time_source, 100, 10000)\n");
time_source_iq_add(time_source, 100, 10000);
sleep(1);
}
return NULL;
}
#define STANDALONE 0
#define SERVER 1
#define CLIENT 2
static void usage(void)
{
printf("options:\n");
printf(" -client\n");
printf(" run as client (default is standalone)\n");
printf(" -server\n");
printf(" run as server (default is standalone)\n");
printf(" -ip <ip address (default 127.0.0.1)>\n");
printf(" use this ip address for server\n");
printf(" -port <port (default 7473)\n");
printf(" use this port for server\n");
printf(" -realtime\n");
printf(" run with realtime clock (default is simulated iq samples)\n");
exit(0);
}
static void server_callback(void *callback_data)
{
printf("server_callback called (callback_data %p)\n", callback_data);
DevAssert(callback_data == (void *)1);
}
static void client_callback(void *callback_data)
{
printf("client_callback called (callback_data %p)\n", callback_data);
DevAssert(callback_data == (void *)2);
}
/* dummy sig handler to quit immediately when pressing enter
* (we send a signal to iq_generate_thread to interrupt sleep())
*/
static void sig_handle(int n)
{
/* nothing */
}
int main(int n, char **v)
{
time_source_t *ts = NULL;
time_server_t *server = NULL;
time_client_t *client = NULL;
int mode = STANDALONE;
char *server_ip = "127.0.0.1";
int server_port = 7473;
time_source_type_t time_source_type = TIME_SOURCE_IQ_SAMPLES;
pthread_t iq_thread;
for (int i = 1; i < n; i++) {
if (!strcmp(v[i], "-client")) { mode = CLIENT; continue; }
if (!strcmp(v[i], "-server")) { mode = SERVER; continue; }
if (!strcmp(v[i], "-ip")) { if (i>n-2) usage(); server_ip = v[++i]; continue; }
if (!strcmp(v[i], "-port")) { if (i>n-2) usage(); server_port = atoi(v[++i]); continue; }
if (!strcmp(v[i], "-realtime")) { time_source_type = TIME_SOURCE_REALTIME; continue; }
usage();
}
logInit();
/* hack: set log to info (logInit doesn't do it because we don't call load_configmodule()) */
for (int i = 0; i < MAX_LOG_COMPONENTS; i++)
g_log->log_component[i].level = OAILOG_INFO;
if (mode != CLIENT) {
ts = new_time_source(time_source_type);
if (time_source_type == TIME_SOURCE_IQ_SAMPLES) {
void *ret = signal(SIGHUP, sig_handle);
DevAssert(ret != SIG_ERR);
threadCreate(&iq_thread, iq_generate_thread, ts, "iq samples generator", -1, SCHED_OAI);
}
}
if (mode == SERVER) {
/* (void*)1 to check if callback data is passed correctly */
server = new_time_server(server_ip, server_port, server_callback, (void *)1);
time_server_attach_time_source(server, ts);
}
if (mode == CLIENT) {
/* (void*)2 to check if callback data is passed correctly */
client = new_time_client(server_ip, server_port, client_callback, (void *)2);
}
printf("main: press enter to quit\n");
getchar();
test_exit = true;
if (mode != CLIENT)
if (time_source_type == TIME_SOURCE_IQ_SAMPLES) {
(void)pthread_kill(iq_thread, SIGHUP);
int ret = pthread_join(iq_thread, NULL);
DevAssert(ret == 0);
}
if (mode != CLIENT) {
free_time_source(ts);
}
if (mode == SERVER) {
free_time_server(server);
}
if (mode == CLIENT) {
free_time_client(client);
}
logTerm();
return 0;
}

View File

@@ -1,232 +0,0 @@
/*
* 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
*/
#include "time_client.h"
#include <string.h>
#include <errno.h>
#include <stdbool.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <poll.h>
#include <sys/eventfd.h>
#include <unistd.h>
#include "common/utils/assertions.h"
#include "common/utils/LOG/log.h"
#include "common/utils/system.h"
typedef struct {
pthread_t thread_id;
int exit_fd;
struct sockaddr_in server_ip;
int server_port;
void (*callback)(void *);
void *callback_data;
} time_client_private_t;
static int connect_to_server(time_client_private_t *time_client)
{
int sock = -1;
int opts;
int r;
struct pollfd fds[2];
/* try forever (or exit requested) until we succeed */
while (1) {
sock = socket(AF_INET, SOCK_STREAM, 0);
AssertFatal(sock != -1, "socket() failed: %s\n", strerror(errno));
int v = 1;
r = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v));
AssertFatal(r == 0, "setsockopt() failed: %s\n", strerror(errno));
/* unblock socket */
opts = fcntl(sock, F_GETFL);
AssertFatal(opts >= 0, "fcntl() failed: %s\n", strerror(errno));
opts |= O_NONBLOCK;
r = fcntl(sock, F_SETFL, opts);
AssertFatal(r == 0, "fctnl() failed: %s\n", strerror(errno));
if (connect(sock, (struct sockaddr *)&time_client->server_ip, sizeof(time_client->server_ip)) == 0)
break;
if (errno == EINPROGRESS) {
/* connection not completed yet, we need to wait */
fds[0].fd = sock;
fds[0].events = POLLOUT;
fds[1].fd = time_client->exit_fd;
fds[1].events = POLLIN;
r = poll(fds, 2, -1);
AssertFatal(r >= 0, "poll() failed: %s\n", strerror(errno));
/* do we need to exit? */
if (fds[1].revents) {
shutdown(sock, SHUT_RDWR);
close(sock);
sock = -1;
break;
}
/* check if connection is successful */
if (fds[0].revents & POLLOUT) {
int so_error;
socklen_t so_error_len = sizeof(so_error);
r = getsockopt(sock, SOL_SOCKET, SO_ERROR, &so_error, &so_error_len);
AssertFatal(r == 0 && so_error_len == sizeof(so_error),
"getsockopt() failed (r = %d) or so_error_len (= %d) is not %ld\n",
r, so_error_len, sizeof(so_error));
if (so_error == 0)
/* success */
break;
}
}
/* connection failed, try again in 1s (or stop if exit requested) */
close(sock);
sock = -1;
char server_address[256];
const char *ret = inet_ntop(AF_INET, &time_client->server_ip.sin_addr, server_address, sizeof(server_address));
AssertFatal(ret != NULL, "inet_ntop() failed: %s\n", strerror(errno));
LOG_W(UTIL, "time client: connection to %s:%d failed, try again in 1s\n", server_address, time_client->server_port);
/* sleep 1s (or exit requested) */
fds[0].fd = time_client->exit_fd;
fds[0].events = POLLIN;
r = poll(fds, 1, 1000);
AssertFatal(r >= 0, "poll() failed: %s\n", strerror(errno));
/* exit requested? */
if (fds[0].revents) {
shutdown(sock, SHUT_RDWR);
close(sock);
sock = -1;
break;
}
}
if (sock != -1) {
/* reblock socket */
opts &= ~O_NONBLOCK;
r = fcntl(sock, F_SETFL, opts);
AssertFatal(r == 0, "fcntl() failed: %s\n", strerror(errno));
}
return sock;
}
static void *time_client_thread(void *tc)
{
time_client_private_t *time_client = tc;
int ret;
int socket = connect_to_server(time_client);
/* if socket is -1 at this point, it means that exit was requested */
if (socket == -1)
return NULL;
while (1) {
struct pollfd polls[2];
/* polls[0] is for the socket */
polls[0].fd = socket;
polls[0].events = POLLIN;
/* polls[1] is for exit_fd */
polls[1].fd = time_client->exit_fd;
polls[1].events = POLLIN;
ret = poll(polls, 2, -1);
AssertFatal(ret >= 0, "poll() failed: %s\n", strerror(errno));
/* whatever is in revents for exit_fd means exit */
if (polls[1].revents)
break;
/* is socket fine? */
if (polls[0].revents & (POLLERR | POLLHUP)) {
reconnect:
/* socket not fine, reconnect */
shutdown(socket, SHUT_RDWR);
close(socket);
socket = connect_to_server(time_client);
/* connect only fails if exit requested, we can safely 'continue' */
continue;
}
/* here we only accept POLLIN */
AssertFatal(polls[0].revents == POLLIN, "poll() did not return expected POLLIN\n");
/* get the ticks from server */
uint8_t tick_count;
ret = read(socket, &tick_count, 1);
/* any error => reconnect */
if (ret == -1) {
LOG_E(UTIL, "time client: error %s, reconnect\n", strerror(errno));
goto reconnect;
}
/* if 0 is returned, it means socket has been closed by other end */
if (ret == 0) {
LOG_E(UTIL, "time client: socket closed by other end, reconnect\n");
goto reconnect;
}
DevAssert(ret == 1);
/* call callback once for each tick */
for (int i = 0; i < tick_count; i++)
time_client->callback(time_client->callback_data);
}
shutdown(socket, SHUT_RDWR);
close(socket);
return NULL;
}
time_client_t *new_time_client(const char *server_ip,
int server_port,
void (*callback)(void *),
void *callback_data)
{
time_client_private_t *tc;
int ret;
tc = calloc_or_fail(1, sizeof(*tc));
tc->exit_fd = eventfd(0, 0);
AssertFatal(tc->exit_fd != -1, "eventfd() failed: %s\n", strerror(errno));
ret = inet_aton(server_ip, &tc->server_ip.sin_addr);
AssertFatal(ret != 0, "inet_aton() failed: %s\n", strerror(errno));
tc->server_ip.sin_family = AF_INET;
tc->server_ip.sin_port = htons(server_port);
tc->server_port = server_port;
tc->callback = callback;
tc->callback_data = callback_data;
threadCreate(&tc->thread_id, time_client_thread, tc, "time client", -1, SCHED_OAI);
return tc;
}
void free_time_client(time_client_t *tc)
{
time_client_private_t *time_client = tc;
uint64_t v = 1;
int ret = write(time_client->exit_fd, &v, 8);
DevAssert(ret == 8);
ret = pthread_join(time_client->thread_id, NULL);
DevAssert(ret == 0);
close(time_client->exit_fd);
free(time_client);
}

View File

@@ -1,205 +0,0 @@
/*
* 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
*/
#include "time_manager.h"
#include "time_source.h"
#include "time_server.h"
#include "time_client.h"
#include "common/config/config_userapi.h"
#include "common/utils/assertions.h"
#include "common/utils/LOG/log.h"
/* global variables (some may be ununsed, depends on configuration) */
static time_source_t *time_source = NULL;
static time_server_t *time_server = NULL;
static time_client_t *time_client = NULL;
/* tick functions registered at initialization of the time manager */
static time_manager_tick_function_t *tick_functions;
static int tick_functions_count;
/* tick callback, called by time_source every 'millisecond' (can be
* actual millisecond or simulated millisecond)
*/
static void tick(void *unused)
{
for (int i = 0; i < tick_functions_count; i++)
tick_functions[i]();
}
#define TIME_SOURCE "time_source"
#define MODE "mode"
#define SERVER_IP "server_ip"
#define SERVER_PORT "server_port"
static paramdef_t config_parameters[] = {
{TIME_SOURCE, "time source", 0, .strptr = NULL, .defstrval = NULL, TYPE_STRING, 0},
{MODE, "time mode", 0, .strptr = NULL, .defstrval = NULL, TYPE_STRING, 0},
{SERVER_IP, "server ip", 0, .strptr = NULL, .defstrval = NULL, TYPE_STRING, 0},
{SERVER_PORT, "server port", 0, .iptr = NULL, .defintval = -1, TYPE_INT, 0},
};
static char *get_param_str(char *name)
{
int idx = config_paramidx_fromname(config_parameters, sizeofArray(config_parameters), name);
char *param;
if (config_parameters[idx].strptr != NULL)
param = *config_parameters[idx].strptr;
else
param = NULL;
return param;
}
static int get_param_int(char *name)
{
int idx = config_paramidx_fromname(config_parameters, sizeofArray(config_parameters), name);
return *config_parameters[idx].iptr;
}
void time_manager_start(time_manager_tick_function_t *_tick_functions,
int _tick_functions_count,
time_source_type_t time_source_type)
{
bool has_time_server = false;
bool has_time_client = false;
char *default_server_ip = "127.0.0.1";
int default_server_port = 7374;
char *server_ip = NULL;
int server_port = -1;
tick_functions_count = _tick_functions_count;
tick_functions = calloc_or_fail(tick_functions_count, sizeof(*tick_functions));
memcpy(tick_functions, _tick_functions, tick_functions_count * sizeof(*tick_functions));
/* retrieve configuration */
int ret = config_get(config_get_if(), config_parameters, sizeofArray(config_parameters), "time_management");
if (ret >= 0) {
char *param;
/* time source */
param = get_param_str(TIME_SOURCE);
if (param != NULL) {
if (!strcmp(param, "realtime")) {
time_source_type = TIME_SOURCE_REALTIME;
} else if (!strcmp(param, "iq_samples")) {
time_source_type = TIME_SOURCE_IQ_SAMPLES;
} else {
AssertFatal(0, "bad parameter 'time_source' in section 'time_management', unknown value \"%s\". Valid values are \"realtime\" and \"iq_samples\"\n", param);
}
}
/* mode */
param = get_param_str(MODE);
if (param != NULL) {
if (!strcmp(param, "standalone")) {
has_time_server = false;
has_time_client = false;
} else if (!strcmp(param, "server")) {
has_time_server = true;
has_time_client = false;
} else if (!strcmp(param, "client")) {
has_time_server = false;
has_time_client = true;
} else {
AssertFatal(0, "bad parameter 'mode' in section 'time_management', unknown value \"%s\". Valid values are \"standalone\", \"server\" and \"client\"\n", param);
}
}
/* server ip */
param = get_param_str(SERVER_IP);
if (param != NULL) {
server_ip = param;
}
/* server port */
int port = get_param_int(SERVER_PORT);
if (port != -1) {
server_port = port;
}
}
if (server_ip == NULL)
server_ip = default_server_ip;
if (server_port == -1)
server_port = default_server_port;
/* create entities, according to selected configuration */
if (!has_time_client) {
time_source = new_time_source(time_source_type);
time_source_set_callback(time_source, tick, NULL);
}
if (has_time_server) {
time_server = new_time_server(server_ip, server_port, tick, NULL);
time_server_attach_time_source(time_server, time_source);
}
if (has_time_client) {
time_client = new_time_client(server_ip, server_port, tick, NULL);
/* for the log below, there is no time source, we want to print 'server' as time source */
time_source_type = 2;
}
LOG_I(UTIL,
"time manager configuration: [time source: %s] [mode: %s] [server IP: %s} [server port: %d]%s\n",
(char *[]){"reatime", "iq_samples", "server"}[time_source_type],
has_time_server ? "server"
: has_time_client ? "client"
: "standalone",
server_ip,
server_port,
has_time_server || has_time_client ? "" : " (server IP/port not used)");
}
void time_manager_iq_samples(uint64_t iq_samples_count,
uint64_t iq_samples_per_second)
{
time_source_iq_add(time_source, iq_samples_count, iq_samples_per_second);
}
void time_manager_finish(void)
{
/* time source has to be shutdown first */
if (time_source != NULL) {
free_time_source(time_source);
time_source = NULL;
}
if (time_server != NULL) {
free_time_server(time_server);
time_server = NULL;
}
if (time_client != NULL) {
free_time_client(time_client);
time_client = NULL;
}
free(tick_functions);
tick_functions = NULL;
tick_functions_count = 0;
}

View File

@@ -1,249 +0,0 @@
/*
* 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
*/
#include "time_server.h"
#include <stdbool.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <poll.h>
#include <errno.h>
#include <sys/eventfd.h>
#include <unistd.h>
#include <string.h>
#include "common/utils/system.h"
#include "common/utils/LOG/log.h"
typedef struct {
pthread_t thread_id;
_Atomic bool exit;
int server_socket;
int tick_fd;
void (*callback)(void *);
void *callback_data;
} time_server_private_t;
static void *time_server_thread(void *ts)
{
time_server_private_t *time_server = ts;
struct pollfd *polls = NULL;
int *socket_fds = NULL;
int client_count = 0;
polls = calloc_or_fail(2, sizeof(struct pollfd));
while (!time_server->exit) {
/* polls[0] is to receive ticks */
polls[0].fd = time_server->tick_fd;
polls[0].events = POLLIN;
/* polls[1] is to accept connections from clients */
polls[1].fd = time_server->server_socket;
polls[1].events = POLLIN;
/* add clients */
for (int i = 0; i < client_count; i++) {
polls[i + 2].fd = socket_fds[i];
polls[i + 2].events = POLLIN;
}
int ret = poll(polls, client_count + 2, -1);
AssertFatal(ret >= 1 || (ret == -1 && errno == EINTR), "poll() failed\n");
if (time_server->exit)
break;
/* check tick */
if (polls[0].revents) {
/* do not accept errors */
AssertFatal(polls[0].revents == POLLIN, "poll() failed\n");
uint64_t ticks;
int ret = read(time_server->tick_fd, &ticks, 8);
DevAssert(ret == 8);
/* call the callback ticks time */
for (int i = 0; i < ticks; i++)
time_server->callback(time_server->callback_data);
/* send ticks by blocks of 255 max (what fits in a uint8_t) */
while (ticks) {
/* get min(ticks, 255) */
uint8_t count = ticks < 255 ? ticks : 255;
/* send to all clients */
for (int i = 0; i < client_count; i++) {
if (write(socket_fds[i], &count, 1) == 1)
continue;
/* error writing - remove client */
LOG_W(UTIL, "time server: client disconnects\n");
shutdown(socket_fds[i], SHUT_RDWR);
close(socket_fds[i]);
client_count--;
i--;
if (client_count == 0) {
free(socket_fds);
socket_fds = NULL;
} else {
memmove(&socket_fds[i + 1], &socket_fds[i + 2], sizeof(int) * (client_count - i - 1));
socket_fds = realloc(socket_fds, sizeof(int) * client_count);
}
polls = realloc(polls, sizeof(struct pollfd) * (client_count + 2));
AssertFatal(polls != NULL, "realloc() failed\n");
}
ticks -= count;
}
}
/* check new client */
if (polls[1].revents) {
/* do not accept errors */
AssertFatal(polls[1].revents == POLLIN, "poll() failed\n");
int new_socket = accept(time_server->server_socket, NULL, NULL);
AssertFatal(new_socket != -1, "accept() failed: %s\n", strerror(errno));
/* add client */
client_count++;
socket_fds = realloc(socket_fds, sizeof(int) * client_count);
AssertFatal(socket_fds != NULL, "realloc() failed\n");
socket_fds[client_count - 1] = new_socket;
polls = realloc(polls, sizeof(struct pollfd) * (client_count + 2));
AssertFatal(polls != NULL, "realloc() failed\n");
continue;
}
/* any event on a client socket is to be considered as an error */
for (int i = 0; i < client_count; i++) {
if (polls[i + 2].revents == 0)
continue;
LOG_W(UTIL,
"time server: error on client's socket, removing client (revents is %d, fd is %d i is %d)\n",
polls[i + 2].revents,
polls[i + 2].fd,
i);
shutdown(socket_fds[i], SHUT_RDWR);
close(socket_fds[i]);
client_count--;
i--;
if (client_count == 0) {
free(socket_fds);
socket_fds = NULL;
} else {
memmove(&socket_fds[i + 1], &socket_fds[i + 2], sizeof(int) * (client_count - i - 1));
socket_fds = realloc(socket_fds, sizeof(int) * client_count);
AssertFatal(socket_fds != NULL, "realloco() failed\n");
}
if (client_count)
memmove(&polls[i + 2 + 1], &polls[i + 2 + 2], sizeof(struct pollfd) * (client_count - i - 1));
polls = realloc(polls, sizeof(struct pollfd) * (client_count + 2));
AssertFatal(polls != NULL, "realloc() failed\n");
}
}
/* close all clients' sockets */
for (int i = 0; i < client_count; i++) {
shutdown(socket_fds[i], SHUT_RDWR);
close(socket_fds[i]);
}
free(polls);
free(socket_fds);
return NULL;
}
time_server_t *new_time_server(const char *ip,
int port,
void (*callback)(void *),
void *callback_data)
{
time_server_private_t *ts;
int ret;
ts = calloc_or_fail(1, sizeof(*ts));
ts->server_socket = socket(AF_INET, SOCK_STREAM, 0);
AssertFatal(ts->server_socket != -1, "socket() failed: %s\n", strerror(errno));
int v = 1;
ret = setsockopt(ts->server_socket, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(v));
AssertFatal(ret == 0, "setsockopt() failed: %s\n", strerror(errno));
v = 1;
ret = setsockopt(ts->server_socket, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v));
AssertFatal(ret == 0, "setsockopt() failed: %s\n", strerror(errno));
ts->tick_fd = eventfd(0, 0);
AssertFatal(ts->tick_fd != -1, "eventfd() failed: %s\n", strerror(errno));
struct sockaddr_in ip_addr;
ip_addr.sin_family = AF_INET;
ip_addr.sin_port = htons(port);
ret = inet_aton(ip, &ip_addr.sin_addr);
AssertFatal(ret != 0, "inet_aton() failed: %s\n", strerror(errno));
ret = bind(ts->server_socket, (struct sockaddr *)&ip_addr, sizeof(ip_addr));
AssertFatal(ret == 0, "bind() failed: %s\n", strerror(errno));
ret = listen(ts->server_socket, 10); /* 10: arbitrary value */
AssertFatal(ret == 0, "listen() failed: %s\n", strerror(errno));
ts->callback = callback;
ts->callback_data = callback_data;
threadCreate(&ts->thread_id, time_server_thread, ts, "time server", -1, SCHED_OAI);
return ts;
}
void free_time_server(time_server_t *ts)
{
time_server_private_t *time_server = ts;
/* flag exit */
time_server->exit = true;
/* send a fake tick to wake up the server thread */
uint64_t v = 1;
int ret = write(time_server->tick_fd, &v, 8);
DevAssert(ret == 8);
/* wait for thread termination */
void *retval;
ret = pthread_join(time_server->thread_id, &retval);
/* free memory */
shutdown(time_server->server_socket, SHUT_RDWR);
close(time_server->server_socket);
close(time_server->tick_fd);
free(time_server);
}
static void time_server_tick_callback(void *ts)
{
time_server_private_t *time_server = ts;
uint64_t v = 1;
int ret = write(time_server->tick_fd, &v, 8);
DevAssert(ret == 8);
}
void time_server_attach_time_source(time_server_t *time_server,
time_source_t *time_source)
{
time_source_set_callback(time_source, time_server_tick_callback, time_server);
}

View File

@@ -1,40 +0,0 @@
/*
* 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
*/
#ifndef COMMON_UTIL_TIME_MANAGER_TIME_SERVER
#define COMMON_UTIL_TIME_MANAGER_TIME_SERVER
#include "time_source.h"
/* opaque data type */
typedef void time_server_t;
time_server_t *new_time_server(const char *ip,
int port,
void (*callback)(void *),
void *callback_data);
void free_time_server(time_server_t *time_server);
void time_server_attach_time_source(time_server_t *time_server,
time_source_t *time_source);
#endif /* COMMON_UTIL_TIME_MANAGER_TIME_SERVER */

View File

@@ -1,263 +0,0 @@
/*
* 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
*/
#include "time_source.h"
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#include <errno.h>
#include "common/utils/assertions.h"
#include "common/utils/system.h"
#include "common/utils/utils.h"
typedef void (*callback_function_t)(void *callback_data);
typedef void * callback_data_t;
typedef struct {
time_source_type_t type;
volatile callback_function_t callback;
volatile callback_data_t callback_data;
_Atomic bool exit;
void (*terminate)(void *this);
pthread_t thread_id;
pthread_mutex_t mutex;
pthread_cond_t cond;
} time_source_common_t;
typedef struct {
time_source_common_t common;
} time_source_realtime_t;
typedef struct {
time_source_common_t common;
volatile uint64_t iq_samples_count;
volatile uint64_t iq_samples_per_second;
} time_source_iq_t;
static void init_mutex(time_source_common_t *t)
{
int ret = pthread_mutex_init(&t->mutex, NULL);
DevAssert(ret == 0);
}
static void init_cond(time_source_common_t *t)
{
int ret = pthread_cond_init(&t->cond, NULL);
DevAssert(ret == 0);
}
static void lock(time_source_common_t *t)
{
int ret = pthread_mutex_lock(&t->mutex);
DevAssert(ret == 0);
}
static void unlock(time_source_common_t *t)
{
int ret = pthread_mutex_unlock(&t->mutex);
DevAssert(ret == 0);
}
static void condwait(time_source_common_t *t)
{
int ret = pthread_cond_wait(&t->cond, &t->mutex);
DevAssert(ret == 0);
}
static void condsignal(time_source_common_t *t)
{
int ret = pthread_cond_signal(&t->cond);
DevAssert(ret == 0);
}
static void wait_thread_termination(time_source_common_t *t)
{
void *retval;
int ret = pthread_join(t->thread_id, &retval);
DevAssert(ret == 0);
}
static struct timespec next_ms(struct timespec t)
{
/* go to next millisecond */
t.tv_nsec += 1000000;
if (t.tv_nsec > 999999999) {
t.tv_nsec -= 1000000000;
t.tv_sec++;
}
return t;
}
static void *time_source_realtime_thread(void *ts)
{
time_source_realtime_t *time_source = ts;
struct timespec now;
if (clock_gettime(CLOCK_MONOTONIC, &now) == -1)
AssertFatal(0, "clock_gettime failed\n");
/* go to next millisecond */
now = next_ms(now);
while (!time_source->common.exit) {
/* sleep */
if (clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &now, NULL) == -1) {
/* accept interruption by signals and then simply restart the sleep */
if (errno == EINTR)
continue;
AssertFatal(0, "clock_nanosleep failed\n");
}
if (time_source->common.exit)
break;
/* tick */
lock(&time_source->common);
void (*callback)(void *callback_data) = time_source->common.callback;
void *callback_data = time_source->common.callback_data;
unlock(&time_source->common);
if (callback != NULL)
callback(callback_data);
/* go to next millisecond */
now = next_ms(now);
}
return (void *)0;
}
static void *time_source_iq_samples_thread(void *ts)
{
time_source_iq_t *time_source = ts;
while (!time_source->common.exit) {
/* wait until we have at least 1ms of IQ samples */
lock(&time_source->common);
while (!time_source->common.exit
&& (time_source->iq_samples_per_second == 0
|| time_source->iq_samples_count < time_source->iq_samples_per_second / 1000))
condwait(&time_source->common);
time_source->iq_samples_count -= time_source->iq_samples_per_second / 1000;
unlock(&time_source->common);
if (time_source->common.exit)
break;
/* tick */
lock(&time_source->common);
void (*callback)(void *callback_data) = time_source->common.callback;
void *callback_data = time_source->common.callback_data;
unlock(&time_source->common);
if (callback != NULL)
callback(callback_data);
}
return (void *)0;
}
static void time_source_iq_samples_terminate(void *ts)
{
time_source_iq_t *time_source = ts;
condsignal(&time_source->common);
}
time_source_t *new_time_source(time_source_type_t type)
{
time_source_t *ret = NULL;
void *(*thread_function)(void *) = NULL;
void (*terminate_function)(void *) = NULL;
char *thread_function_name = NULL;
switch (type) {
case TIME_SOURCE_REALTIME: {
time_source_realtime_t *ts = calloc_or_fail(1, sizeof(*ts));
thread_function = time_source_realtime_thread;
thread_function_name = "time source realtime";
ret = ts;
break;
}
case TIME_SOURCE_IQ_SAMPLES: {
time_source_iq_t *ts = calloc_or_fail(1, sizeof(*ts));
thread_function = time_source_iq_samples_thread;
terminate_function = time_source_iq_samples_terminate;
thread_function_name = "time source iq samples";
ret = ts;
break;
}
}
time_source_common_t *c = ret;
c->type = type;
init_mutex(c);
init_cond(c);
c->terminate = terminate_function;
threadCreate(&c->thread_id, thread_function, c, thread_function_name, -1, SCHED_OAI);
return ret;
}
void free_time_source(time_source_t *ts)
{
time_source_common_t *time_source = ts;
time_source->exit = true;
if (time_source->terminate != NULL)
time_source->terminate(time_source);
wait_thread_termination(time_source);
free(time_source);
}
void time_source_set_callback(time_source_t *ts,
void (*callback)(void *),
void *callback_data)
{
time_source_common_t *time_source = ts;
lock(time_source);
time_source->callback = callback;
time_source->callback_data = callback_data;
unlock(time_source);
}
void time_source_iq_add(time_source_t *ts,
uint64_t iq_samples_count,
uint64_t iq_samples_per_second)
{
if (ts == NULL)
return;
time_source_iq_t *time_source = ts;
if (time_source->common.type != TIME_SOURCE_IQ_SAMPLES)
return;
lock(&time_source->common);
time_source->iq_samples_count += iq_samples_count;
if (time_source->iq_samples_per_second == 0)
time_source->iq_samples_per_second = iq_samples_per_second;
AssertFatal(time_source->iq_samples_per_second == iq_samples_per_second, "unsupported change of value 'IQ samples per second'\n");
condsignal(&time_source->common);
unlock(&time_source->common);
}

View File

@@ -38,7 +38,7 @@
int nas_sock_fd[MAX_MOBILES_PER_ENB * 2]; // Allocated for both LTE UE and NR UE.
int nas_sock_mbms_fd;
int tun_alloc(const char *dev)
static int tun_alloc(const char *dev)
{
struct ifreq ifr;
int fd, err;
@@ -157,14 +157,13 @@ static bool setInterfaceParameter(int sock_fd, const char *ifn, int af, const ch
return success;
}
typedef enum { INTERFACE_DOWN, INTERFACE_UP } if_action_t;
/*
* \brief bring interface up (up != 0) or down (up == 0)
*/
* \brief bring interface up (up != 0) or down (up == 0)
*/
typedef enum { INTERFACE_DOWN, INTERFACE_UP } if_action_t;
static bool change_interface_state(int sock_fd, const char *ifn, if_action_t if_action)
{
const char *action = if_action == INTERFACE_DOWN ? "DOWN" : "UP";
const char* action = if_action == INTERFACE_DOWN ? "DOWN" : "UP";
struct ifreq ifr = {0};
strncpy(ifr.ifr_name, ifn, sizeof(ifr.ifr_name));
@@ -190,7 +189,6 @@ fail_interface_state:
return false;
}
bool tun_config(const char* ifname, const char *ipv4, const char *ipv6)
{
AssertFatal(ipv4 != NULL || ipv6 != NULL, "need to have IP address, but none given\n");
@@ -264,19 +262,3 @@ int tun_generate_ifname(char *ifname, const char *ifprefix, int instance_id)
{
return snprintf(ifname, IFNAMSIZ, "%s%d", ifprefix, instance_id + 1);
}
int tun_generate_ue_ifname(char *ifname, int instance_id, int pdu_session_id)
{
char pdu_session_string[10];
snprintf(pdu_session_string, sizeof(pdu_session_string), "p%d", pdu_session_id);
return snprintf(ifname, IFNAMSIZ, "%s%d%s", "oaitun_ue", instance_id + 1, pdu_session_id == -1 ? "" : pdu_session_string);
}
void tun_destroy(const char *dev, int fd) {
if (change_interface_state(fd, dev, INTERFACE_DOWN) == 0) {
LOG_I(UTIL, "Interface %s is now down.\n", dev);
} else {
LOG_E(UTIL, "Could not bring interface %s down.\n", dev);
}
close(fd);
}

View File

@@ -34,7 +34,6 @@
* \param[in] instance_id unique instance number
*/
int tun_generate_ifname(char *ifname, const char *ifprefix, int instance_id);
int tun_generate_ue_ifname(char *ifname, int instance_id, int pdu_session_id);
/*!
* \brief This function initializes the TUN interface
@@ -74,18 +73,4 @@ bool tun_config(const char* ifname, const char *ipv4, const char *ipv6);
*/
void setup_ue_ipv4_route(const char* ifname, int instance_id, const char *ipv4);
/*!
* \brief This function allocates a TUN interface
* \param[in] dev name of the interface
* \return file descriptor of the allocated interface
*/
int tun_alloc(const char *dev);
/*!
* \brief This function destroys the TUN interface
* \param[in] dev name of the interface
* \param[in] fd file descriptor of the allocated interface
*/
void tun_destroy(const char *dev, int fd);
#endif /*TUN_IF_H_*/

View File

@@ -621,21 +621,26 @@ int websrv_callback_get_softmodemcmd(const struct _u_request *request, struct _u
snprintf(confstr, sizeof(confstr), "Confirm %s ?", modulestruct->cmd[j].cmdname);
acmd = json_pack("{s:s,s:s}", "name", modulestruct->cmd[j].cmdname, "confirm", confstr);
} else if (modulestruct->cmd[j].cmdflags & TELNETSRV_CMDFLAG_NEEDPARAM) {
char *question[] = {NULL, NULL};
char *question[] = {NULL,NULL};
char *helpcp = NULL;
json_t *jQ1=NULL, *jQ2=NULL;
json_t *jQs = json_array();
int ns = sscanf(modulestruct->cmd[j].helpstr, "<%m[^<>]> <%m[^<>]>", &question[0], &question[1]);
if (ns == 0) {
LOG_W(UTIL, "[websrv] Cannot find parameters for command %s %s\n", modulestruct->module, modulestruct->cmd[j].cmdname);
continue;
}
jQ1 = json_pack("{s:s,s:s,s:s}", "display", question[0], "pname", "P0", "type", "string");
json_array_append_new(jQs, jQ1);
if (ns > 1) {
jQ2 = json_pack("{s:s,s:s,s:s}", "display", (question[1] == NULL) ? "" : question[1], "pname", "P1", "type", "string");
json_array_append_new(jQs, jQ2);
if (modulestruct->cmd[j].helpstr != NULL) {
helpcp = strdup(modulestruct->cmd[j].helpstr);
int ns=sscanf(helpcp,"<%m[^<>]> <%m[^<>]>",&question[0],&question[1]);
if (ns == 0) {
LOG_W(UTIL, "[websrv] Cannot find parameters for command %s %s\n", modulestruct->module, modulestruct->cmd[j].cmdname);
continue;
}
jQ1=json_pack("{s:s,s:s,s:s}", "display",question[0], "pname", "P0", "type", "string");
json_array_append_new(jQs, jQ1);
if (ns >1) {
jQ2=json_pack("{s:s,s:s,s:s}","display", (question[1] == NULL) ? "" : question[1], "pname", "P1" , "type", "string");
json_array_append_new(jQs, jQ2);
}
}
acmd = json_pack("{s:s,s:o}", "name", modulestruct->cmd[j].cmdname, "question", jQs);
free(helpcp);
free(question[0]);
free(question[1]);
} else {

View File

@@ -24,11 +24,8 @@ The hardware on which we have tried this tutorial:
|----------------------------------------------------------------------------|----------------------------------|--------------------------------------------------|
| Gigabyte Edge E251-U70 (Intel Xeon Gold 6240R, 2.4GHz, 24C48T, 96GB DDR4) |Ubuntu 22.04.3 LTS (5.15.0-72-lowlatency)| NVIDIA ConnectX®-6 Dx 22.38.1002 |
| Dell PowerEdge R750 (Dual Intel Xeon Gold 6336Y CPU @ 2.4G, 24C/48T (185W), 512GB RDIMM, 3200MT/s) |Ubuntu 22.04.3 LTS (5.15.0-72-lowlatency)| NVIDIA Converged Accelerator A100X (24.39.2048) |
| Supermicro Grace Hopper MGX ARS-111GL-NHR (Neoverse-V2, 3.4GHz, 72C/72T, 576GB LPDDR5) | Ubuntu 22.04.5 LTS (6.5.0-1019-nvidia-64k) |NVIDIA BlueField3 (32.41.1000)|
**NOTE**:
- These are not minimum hardware requirements. This is the configuration of our servers. The NIC card should support hardware PTP time stamping.
- Starting from tag [2025.w13](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tree/2025.w13?ref_type=tags) of OAI, we are only testing with the Grace Hopper server.
**NOTE**: These are not minimum hardware requirements. This is the configuration of our servers. The NIC card should support hardware PTP time stamping.
PTP enabled switches and grandmaster clock we have tested with:
@@ -45,7 +42,6 @@ These are the radio units we've used for testing:
|-------------|------------------|
| Foxconn RPQN-7801E RU | 2.6.9r254 |
| Foxconn RPQN-7801E RU | 3.1.15_0p4 |
| Foxconn RPQN-7801E RU | v3.2.0q.551.12.E.rc2.srs-AIO |
The UEs that have been tested and confirmed working with Aerial are the following:
@@ -58,30 +54,35 @@ The UEs that have been tested and confirmed working with Aerial are the followin
| Apaltec | Tributo 5G-Dongle |
| OnePlus | Nord (AC2003) |
| Apple iPhone | 14 Pro (MQ0G3RX/A) (iOS 17.3) |
| Samsung | S23 Ultra |
## Configure your server
To set up the L1 and install the components manually refer to this [instructions page](https://docs.nvidia.com/aerial/cuda-accelerated-ran/index.html).
The first step is to obtain the NVIDIA Aerial SDK, you'll need to request access [here](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/aerial-sdk).
After obtaining access to the SDK, you can refer to [this instructions page](https://docs.nvidia.com/aerial/aerial-ran-colab-ota/current/index.html) to setup the L1 components using NVIDIAs' SDK manager, or to [this instructions page](https://docs.nvidia.com/aerial/cuda-accelerated-ran/index.html) in order to setup and install the components manually.
The currently used Aerial Version is 24-1, which is also the one currently used by the SDK Manager.
**Note**:
- To configure the Gigabyte server please refer to these [instructions](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/2025.w13/doc/Aerial_FAPI_Split_Tutorial.md)
- The last release to support the Gigabyte server is **Aerial CUDA-Accelerated RAN 24-1**.
### CPU allocation
| Server brand | Model | Nº of CPU Cores | Isolated CPUs |
|------------------|---------------|:---------------:|:--------------:|
| Grace Hopper MGX | ARS-111GL-NHR | 72 | 4-64 |
Currently, the CPU isolation is setup the following:
**Grace Hopper MGX ARS-111GL-NHR**
| Server brand | Model | Nº of CPU Cores | Isolated CPUs |
|--------------|-----------|:---------------:|:--------------:|
| Gigabyte | Edge E251-U70 | 24 | 2-10 |
**Gigabyte Edge E251-U70**
| Applicative Threads | Allocated CPUs |
|------------------------|----------------|
| PTP & PHC2SYS Services | 41 |
| Aerial L1 | 2,3,4,5,6,7,8 |
| PTP & PHC2SYS Services | 9 |
| OAI `nr-softmodem` | 13-20 |
## PTP configuration
1. You need to install the `linuxptp` debian package. It will install both ptp4l and phc2sys.
@@ -98,10 +99,14 @@ Once installed you can use this configuration file for ptp4l (`/etc/ptp4l.conf`)
domainNumber 24
slaveOnly 1
time_stamping hardware
tx_timestamp_timeout 30
tx_timestamp_timeout 1
logging_level 6
summary_interval 0
#priority1 127
[your_PTP_ENABLED_NIC]
network_transport L2
hybrid_e2e 0
```
@@ -115,7 +120,7 @@ Documentation=man:ptp4l
Restart=always
RestartSec=5s
Type=simple
ExecStart=taskset -c 41 /usr/sbin/ptp4l -f /etc/ptp.conf
ExecStart=taskset -c 9 /usr/sbin/ptp4l -f /etc/ptp.conf
[Install]
WantedBy=multi-user.target
@@ -144,16 +149,17 @@ WantedBy=multi-user.target
# Build OAI gNB
If it's not already cloned, the first step is to clone OAI repository
If installing with the Aerial SDK, you should already have the repository cloned in `~/openairinterface5g`, if
Clone OAI code base in a suitable repository, here we are cloning in `~/openairinterface5g` directory,
```bash
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git ~/openairinterface5g
cd ~/openairinterface5g/
```
## Get nvIPC sources from the L1 container
The library used for communication between L1 and L2 components is called nvIPC, and is developed by NVIDIA. It is not open-source and can't be freely distributed.
In order to achieve this communication, we need to obtain the nvIPC source files from the L1 container (cuBB) and place it in the gNB project directory `~/openairinterface5g`.
The library used for communication between L1 and L2 components is called nvIPC, and was developed by NVIDIA, as such, it is not open-source and can't be freely distributed.
In order to be able to use this library to achieve communication, we need to obtain the nvIPC source files from the L1 container (cuBB) and place it in out gNB project directory `~/openairinterface5g`.
This allows us to build and install this library when building the L2 docker container.
Check whether your L1 container is running:
@@ -171,7 +177,7 @@ cuBB
aerial@c_aerial_aerial:/opt/nvidia/cuBB#
```
After logging into the container, you need to pack the nvIPC sources and copy them to the host ( the command creates a `tar.gz` file with the following name format: `nvipc_src.YYYY.MM.DD.tar.gz`)
After logging into the container, we need to pack the nvIPC sources and copy them to the host ( the command creates a tar.gz file with the following name format: nvipc_src.YYYY.MM.DD.tar.gz)
```bash
~$ docker exec -it cuBB bash
aerial@c_aerial_aerial:/opt/nvidia/cuBB# cd cuPHY-CP/gt_common_libs
@@ -210,7 +216,7 @@ With the nvIPC sources in the project directory, the docker image can be built.
## Building OAI gNB docker image
In order to build the target image (`oai-gnb-aerial`), first you should build a common shared image (`ran-base`)
In order to build the final image, there is an intermediary image to be built (ran-base)
```bash
~$ cd ~/openairinterface5g/
~/openairinterface5g$ docker build . -f docker/Dockerfile.base.ubuntu22 --tag ran-base:latest
@@ -218,23 +224,21 @@ In order to build the target image (`oai-gnb-aerial`), first you should build a
```
# Running the setup
## Running the setup
In order to use Docker compose to automatically start and stop the setup, we need to first create a ready-made image of the L1, after compiling the L1 software and making the necessary adjustments to its configuration files.
The process of preparing the L1 is covered on NVIDIAs' documentation, and falls outside the scope of this document.
In order to use Docker Compose to automatically start and stop the setup, we first need to create a pre-built image of L1 after compiling the L1 software and making the necessary adjustments to its configuration files.
The process of preparing L1 is covered in NVIDIA's documentation and falls outside the scope of this document.
## Prepare the L1 image
After preparing the L1 software, the container needs to be committed to create an image where L1 is ready for execution, which can later be referenced by a `docker-compose.yaml` file.
*Note:* The default L1 configuration file is `cuphycontroller_P5G_FXN_GH.yaml`, located in `/opt/nvidia/cuBB/cuPHY-CP/cuphycontroller/config/`.
In this file the RU MAC address needs to be specified before commiting the image.
### Prepare the L1 image
After preparing the L1 software, the container needs to be committed in order for an image in which the L1 is ready to be executed, and that can be referenced by a docker-compose.yaml file later:
*Note:* In preparing the L1 image, the default L1 configuration file is cuphycontroller_P5G_FXN.yaml, located in `/opt/nvidia/cuBB/cuPHY-CP/cuphycontroller/config/`.
This is the file where the RU MAC address needs to be applied before commiting the image
```bash
~$ docker commit nv-cubb cubb-build:24-3
~$ docker commit nv-cubb cubb-build:24-1
~$ docker image ls
..
cubb-build 24-3 824156e0334c 2 weeks ago 23.9GB
-..
cubb-build 24-1 824156e0334c 2 weeks ago 40.1GB
..
```
## Adapt the OAI-gNB configuration file to your system/workspace
@@ -251,12 +255,14 @@ The default amf_ip_address:ipv4 value is 192.168.70.132, when installing the CN5
Both 'GNB_IPV4_ADDRESS_FOR_NG_AMF' and 'GNB_IPV4_ADDRESS_FOR_NGU' need to be set to the IP address of the NIC referenced previously.
## Running docker compose
### Aerial L1 entrypoint script
The `aerial_l1_entrypoint` script is used by the L1 container to start the L1 software and is called in the Docker Compose file.
It begins by setting up environment variables, restarting NVIDIA MPS, and finally running `cuphycontroller_scf`.
The L1 software is executed with an argument that specifies which configuration file to use. If not modified, the default argument is set to `P5G_FXN_GH`.
### Running docker compose
#### Aerial L1 entrypoint script
Before running docker-compose, we can check which L1 configuration file is to be used by cuphycontroller_scf.
This is set in the script [`aerial_l1_entrypoint.sh`](../ci-scripts/yaml_files/sa_gnb_aerial/aerial_l1_entrypoint.sh), which is used by the L1 container in order to start the L1 software.
The script begins by setting up some environment variables, restarting NVIDIA MPS, and finally running cuphycontroller_scf.
The L1 software is run with an argument that indicates which configuration file is to be used.
This argument may be changed by providing an argument to the [`aerial_l1_entrypoint.sh`](../ci-scripts/yaml_files/sa_gnb_aerial/aerial_l1_entrypoint.sh) call in [`docker-compose.yaml`](../ci-scripts/yaml_files/sa_gnb_aerial/docker-compose.yaml).
When no argument is provided (this is the default behaviour), it uses "P5G_FXN" as the cuphycontroller_scf argument.
After building the gNB image, and preparing the configuration file, the setup can be run with the following command:
@@ -265,18 +271,17 @@ cd ci-scripts/yaml_files/sa_gnb_aerial/
docker compose up -d
```
This will start both containers, beginning with `nv-cubb`, and `oai-gnb-aerial` will start only after it is ready.
This will start both containers, beginning with 'nv-cubb' and only after it being ready it starts 'oai-gnb-aerial'.
The logs can be followed using these commands:
The gNB logs can be followed with:
```bash
docker logs -f oai-gnb-aerial
docker logs -f nv-cubb
```
### Running with multiple L2s
#### Running with multiple L2s
One L1 instance can support multiple L2 instances. See also the [aerial documentation](https://developer.nvidia.com/docs/gputelecom/aerial-sdk/text/cubb_quickstart/running_cubb-end-to-end.html#run-multiple-l2-instances-with-single-l1-instance) for more details.
In OAI the shared memory prefix must be configured in the configuration file.
In OAI the share memory prefix must be configured in the configuration file.
```bash
tr_s_preference = "aerial";
@@ -284,9 +289,9 @@ In OAI the shared memory prefix must be configured in the configuration file.
```
## Stopping the setup
### Stopping the setup
Run the following command to stop and remove both containers, leaving the system ready to be restarted later:
Running the following command, will stop both containers, leaving the system ready to be run later:
```bash
cd ci-scripts/yaml_files/sa_gnb_aerial/
docker compose down

View File

@@ -2241,14 +2241,18 @@ INPUT = \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/cdot_prod.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/phy_scope_interface.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/oai_dfts_neon.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/cmult_vv.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/cmult_sv.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/dB_routines.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/dfts_load.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/log2_approx.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/phy_scope_interface.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/simde_operations.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/lut.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/nr_phy_scope.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/nr_phy_scope.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/lte_phy_scope.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/cadd_vv.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/phy_scope.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/signal_energy.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/oai_dfts.c \

View File

@@ -105,7 +105,7 @@ These modes of operation are supported:
- MAC -> PHY configuration using NR FAPI P5 interface
- MAC <-> PHY data interface using FAPI P7 interface for BCH PDU, DCI PDU, PDSCH PDU
- Generation of and scheduler procedures for MIB/SIB1
- Scheduler procedures for SIB1
- Scheduler procedures for RA
- 4-Step RA
- Contention Free RA procedure
@@ -140,7 +140,6 @@ These modes of operation are supported:
- MAC scheduling of SR reception
- Intra-frequency handover
- Initial support for RedCap
- Scheduling of SIBs (2, 19)
## gNB RLC
@@ -175,7 +174,7 @@ These modes of operation are supported:
- NR RRC (38.331) Rel 17 messages using new [asn1c](https://github.com/mouse07410/asn1c)
- LTE RRC (36.331) also updated to Rel 15
- Generation of system information (SIB2)
- Generation of MIB/SIB1 (received from DU)
- RRC can configure PDCP, RLC, MAC
- Interface with GTP-U (tunnel creation/handling for S1-U (NSA), N3 (SA), F1 interfaces)
- Integration of RRC messages and procedures supporting UE 5G SA connection

View File

@@ -232,9 +232,7 @@ In the `MACRLCs` section of the gNB/DU configuration file:
In the `gNBs` section of the gNB/DU configuration file: some of the parameters
affect RRC configuration (CellGroupConfig) of a UE, and are therefore listed
here, *also they pertain to the DU*, i.e., the scheduler. Note also that some
SIBs are configured at the DU and some at the CU; please consult the [RRC
configuration](../RRC/rrc-usage.md) as well for SIB configuration.
here, *also they pertain to the DU*, i.e., the scheduler.
* `pdsch_AntennaPorts_XP` (default 1): number of XP logical antenna
ports in PDSCH (see also [`RUNMODEM.md`](../RUNMODEM.md))
@@ -250,8 +248,6 @@ configuration](../RRC/rrc-usage.md) as well for SIB configuration.
* `do_CSIRS` (default 0): flag whether to use channel-state information
reference signal (CSI-RS)
* `do_SRS` (default 0): flag whether to use sounding reference signal (SRS)
* `do_SINR` (default 0): flag whether to enable CSI reporting of SSB-SINR (introduced in rel16)
Default setting of CSI reporting quantity is SSB-RSRP.
* `min_rxtxtime` (default 2): minimum feedback time for UE to respond to
transmissions (k1 and k2 in 3GPP spec)
* `ul_prbblacklist`: PRBs that should not be used for UL scheduling. Cf with
@@ -271,20 +267,6 @@ configuration](../RRC/rrc-usage.md) as well for SIB configuration.
options are 2, 4, 6, 8, 10, 12, 32; **32 is a Rel-17 features**)
* `num_ulharq` (default 16): as `num_dlharq` for UL (other valid option is 32;
**32 is i Rel-17 feature**)
- `du_sibs` (default `[]`): list of SIBs to transmit in the cell. Currently,
SIB19 (for NTN) is supported.
| DL MIMO |`do_CSIRS`|`do_SINR`| CSI report Quantity |
| ---------------------------- | -------- | ------- | --------------------------------------------------|
| OFF (pdsch_AntennaPorts = 1) | 0 | 0 | SSB-RSRP |
| OFF (pdsch_AntennaPorts = 1) | 0 | 1 | SSB-SINR |
| OFF (pdsch_AntennaPorts = 1) | 1 | 0 | CSI-Reference signal RSRP |
| OFF (pdsch_AntennaPorts = 1) | 1 | 1 | CSI-Reference signal SINR (not supported yet) |
| ON (pdsch_AntennaPorts > 1) | 1 | 0 | cri-RI-PMI-CQI |
DL-MIMO is configured using following parameters:
`pdsch_AntennaPorts_XP` , `pdsch_AntennaPorts_N1` , `pdsch_AntennaPorts_N2`, `maxMIMO_layers`
(see also [`RUNMODEM.md`](../RUNMODEM.md))
## ServingCellConfigCommon parameters

View File

@@ -32,8 +32,6 @@ The hardware on which we have tried this tutorial:
- The NIC card should support hardware PTP time stamping.
- If you are using Intel servers then use only Ice Lake or newer generations. In case of AMD use only 4th generation, Genoa or newer.
- If you try on any other server apart from the above listed, then choose a desktop/server with clock speed higher than 3.0 GHz and `avx512` capabilities.
- This tutorial gives few instructions for Arm targets, but DU execution on Arm systems is yet not functional.
This feature is intended to enable experiments and future improvements on Arm systems.
NICs we have tested so far:
@@ -405,10 +403,7 @@ git apply ~/openairinterface5g/cmake_targets/tools/oran_fhi_integration_patches/
Compile the fronthaul interface library by calling `make` and the option
`XRAN_LIB_SO=1` to have it build a shared object. Note that we provide two
environment variables `RTE_SDK` for the path to the source tree of DPDK, and
`XRAN_DIR` to set the path to the fronthaul library.
For building for a Arm target, set as well the environment variable `TARGET=armv8`.
DU execution on Arm systems is yet not functional.
This feature is intended to enable experiments and future improvements on Arm systems.
`XRAN_DIR` to set the path to the fronthaul library.
**Note**: you need at least gcc-11 and g++-11.
@@ -425,31 +420,6 @@ WIRELESS_SDK_TOOLCHAIN=gcc RTE_SDK=~/dpdk-stable-20.11.9/ XRAN_DIR=~/phy/fhi_lib
The shared library object `~/phy/fhi_lib/lib/build/libxran.so` must be present
before proceeding.
## For Arm targets only: Install the Arm RAN Acceleration library
DU execution on Arm systems is yet not functional.
This feature is intended to enable experiments and future improvements on Arm systems.
Clone, configure and build ArmRAL:
Note: Use option `-DCMAKE_INSTALL_PREFIX=<install-dir>` of cmake to set the installation directory of ArmRAL to `<install-dir>`.
If you omit this option, ArmRAL is installed into `/usr/local`.
```
git clone https://git.gitlab.arm.com/networking/ral.git ~/ral
cd ~/ral
git checkout armral-25.01
mkdir build
cd build
cmake -GNinja -DBUILD_SHARED_LIBS=On ../
ninja
```
Once ArmRAL is configured at your convenience and built, you can install it:
```
ninja install
```
## Build OAI gNB
You can now proceed building OAI. You build it the same way as for other

View File

@@ -108,7 +108,6 @@ Legacy unmaintained files:
- The [shared object loader](../common/utils/DOC/loader.md)
- The [threadpool](../common/utils/threadPool/thread-pool.md) used in L1
- The [LDPC implementation](../openair1/PHY/CODING/DOC/LDPCImplementation.md) is a shared library
- The [time management](time_management.md) module
## Radios

View File

@@ -67,9 +67,6 @@ RRC-specific configuration
### cell-specific options
Note that some SIBS are configured at the CU and some at the DU; please consult
the [MAC configuration](../MAC/mac-usage.md) as well for SIB configuration.
- `gNB_ID` and `gNB_name`: ID and name of the gNB
- `tracking_area_code`: the current tracking area code in the range `[0x0001,
0xfffd]`
@@ -87,8 +84,6 @@ the [MAC configuration](../MAC/mac-usage.md) as well for SIB configuration.
- `enable_sdap` (default: false): enable the use of the SDAP layer. If
deactivated, a transparent SDAP header is prepended to packets, but no
further processing is being done.
- `cu_sibs` (default: `[]`) list of SIBs to give to the DU for transmission.
Currently, SIB2 is supported.
### UE-specific configuration

View File

@@ -136,15 +136,7 @@ Here are some useful command line options for the NR UE:
| Parameter | Description |
|--------------------------|---------------------------------------------------------------------------------------------------------------|
| `--ue-scan-carrier` | Scan for cells in current bandwidth. This option can be used if the SSB position of the gNB is unknown. If multiple cells are detected, the UE will try to connect to the first cell. By default, this option is disabled and the UE attempts to only decode SSB given by `--ssb`. |
| `--ue-fo-compensation` | Enables the initial frequency offset compensation at the UE. Useful when running over the air and/or without an external clock/time source. |
| `--cont-fo-comp` | Enables the continuous frequency offset (FO) estimation and compensation. Parameter value `1` specifies that the main FO contribution comes from the local oscillator's (LO) accuracy. Parameter value `2` specifies that the main FO contribution comes from Doppler shift. |
| `--initial-fo` | Sets the known initial frequency offset. Useful especially with large Doppler frequency, e.g. LEO satellite. |
| `--freq-sync-P` | Sets the coefficient for the Proportional part of the PI-controller for the continuous frequency offset compensation. Default value 0.01. |
| `--freq-sync-I` | Sets the coefficient for the Integrating part of the PI-controller for the continuous frequency offset compensation. Default value 0.001. |
| `--ntn-initial-time-drift` | Sets the initial NTN DL time drift (feeder link and service link), given in µs/s. |
| `--autonomous-ta` | Enables the autonomous TA update, based on DL drift (useful if main contribution to DL drift is movement, e.g. LEO satellite). |
| `--time-sync-P` | Sets the coefficient for the Proportional part of the PI-controller for the time synchronization. Default value 0.5. |
| `--time-sync-I` | Sets the coefficient for the Integrating part of the PI-controller for the time synchronization. Default value 0.0. |
| `--ue-fo-compensation` | Enables the frequency offset compensation at the UE. Useful when running over the air and/or without an external clock/time source. |
| `--usrp-args` | Equivalent to the `sdr_addrs` field in the gNB config file. Used to identify the USRP and set some basic parameters (like the clock source). |
| `--clock-source` | Sets the clock source (internal or external). |
| `--time-source` | Sets the time source (internal or external). |
@@ -357,16 +349,10 @@ For LEO satellite scenarios, the parameter `--ntn-initial-time-drift` must be pr
This parameter provides the drift rate of the complete DL timing (incl. feeder link and service link) in µs/s.
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.
For LEO satellite scenario we assume the LO to be very accurate and the main FO contribution comes from Doppler shift.
Therefore, we use the command line parameter `--cont-fo-comp 2` to continuously compensate the DL Doppler and pre-compensate the UL Doppler.
The initial Doppler frequency offset must be provided via command line with the parameter `--initial-fo`.
For other information on optional NR UE command line options, please refer [here](#optional-nr-ue-command-line-options).
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 -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf --band 254 -C 2488400000 --CO -873500000 -r 25 --numerology 0 --ssb 60 --rfsim --rfsimulator.prop_delay 20 --rfsimulator.options chanmod --time-sync-I 0.1 --ntn-initial-time-drift -46 --autonomous-ta --initial-fo 57340 --cont-fo-comp 2
sudo ./ran_build/build/nr-uesoftmodem -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf --band 254 -C 2488400000 --CO -873500000 -r 25 --numerology 0 --ssb 60 --rfsim --rfsimulator.prop_delay 20 --rfsimulator.options chanmod --time-sync-I 0.1 --ntn-initial-time-drift -46 --autonomous-ta
```
# Specific OAI modes

View File

@@ -298,7 +298,7 @@ Even, a future evolution could remove this global rlc layer: rlc can be only a l
When adding a UE, external code have to call `add_rlc_srb()` and/or `add_rlc_drb()`, to remove it: `rrc_rlc_remove_ue()`
Inside UE, channels called drd or srb can be created: ??? and deleted: rrc_rlc_config_req()
nr_rlc_ms_tick() must be called periodically to manage the internal timers
nr_rlc_tick() must be called periodically to manage the internal timers
successful_delivery() and max_retx_reached(): in ??? trigger, the RLC sends a itti message to RRC: RLC_SDU_INDICATION (neutralized by #if 0 right now)
@@ -329,7 +329,7 @@ To manage UE connections, `nr_pdcp_add_srbs()` is employed for adding UE SRBs in
## PDCP Tx flow
On the Tx side (downlink in gNB), the entry functions `nr_pdcp_data_req_drb()` and `nr_pdcp_data_req_srb()` are called by the upper layer. The upper layer could be GTP or a PDCP internal thread like `gnb_tun_read_thread()`, which reads directly from the Linux socket if the 3GPP core implementation is skipped. The PDCP internals for `nr_pdcp_data_req_srb()` and `nr_pdcp_data_req_drb()` are thread-safe. Within these functions, the PDCP manager protects access to the SDU receiving function of PDCP (`recv_sdu()` callback, corresponding to `nr_pdcp_entity_recv_pdu()` for DRBs) using mutex. When necessary, the PDCP layer pushes this data to RLC by calling `rlc_data_req()`.
On the Tx side (downlink in gNB), the entry functions `nr_pdcp_data_req_drb()` and `nr_pdcp_data_req_srb()` are called by the upper layer. The upper layer could be GTP or a PDCP internal thread like `enb_tun_read_thread()`, which reads directly from the Linux socket if the 3GPP core implementation is skipped. The PDCP internals for `nr_pdcp_data_req_srb()` and `nr_pdcp_data_req_drb()` are thread-safe. Within these functions, the PDCP manager protects access to the SDU receiving function of PDCP (`recv_sdu()` callback, corresponding to `nr_pdcp_entity_recv_pdu()` for DRBs) using mutex. When necessary, the PDCP layer pushes this data to RLC by calling `rlc_data_req()`.
## PDCP Rx flow

View File

@@ -4,25 +4,28 @@
## Machines
| Machine | Lockable Resource | Function | Connected devices |
| ------------- | --------------------- | -------------------- | ----------------------------------------------------- |
| obelix | Obelix | eNB (n40, n78), nrUE | 172.21.19.13, X300 (192.168.60.2) |
| porcepix | Porcepix | Executor, EPC, 5GC | -- |
| up2 | UP2 | COTS UE | Quectel RM520N |
| nepes | Nepes | gNB (n78), EPC/5GC | B200mini (30C51EB) |
| ofqot | Ofqot | gNB (n78) | B200mini (30C51D4) |
| idefix | Idefix | COTS UE | Quectel RM500Q |
| caracal | Caracal | gNB/phytest, OAI UE | N300 (192.168.10.2), _AMD T2 card_ |
| amariue | Amarisoft-UE | nrUE | Amarisoft UE simulator |
| nano | Nano_EPC/Nano_5G_COTS_UE | Executor, EPC, adb | 2x COTS (adb) |
| hutch | Hutch | eNB (B7) | B200mini (30C5239) |
| starsky | Starsky | eNB (B40) | b200mini (30A3E3C) |
| carabe | Carabe | UE (B7UE) | B200mini (30AE8C9) |
| avra | Avra | gNB (n78) | AW2S Jaguar (192.168.80.239) |
| cacofonix | Cacofonix | gNB (n78, FHI7.2) | -- |
| matix | Matix | gNB (n77) | N310 |
| gracehopper1-oai | Gracehopper1 | gNB (n78, PNF/Nvidia CUBB + VNF) | Foxconn RU, _Nvidia Aerial integration_ |
| gracehopper3-oai | Gracehopper3 | build | -- |
| Machine | IP address | Lockable Resource | Function | Connected devices |
| ------------- | --------------- | --------------------- | ------------------ | ----------------------------------------------------- |
| asterix | 172.21.16.127 | CI-Asterix-Usage | *unused* | 172.21.19.14 |
| obelix | 172.21.16.128 | CI-Obelix-Usage | eNB (n40, n78), nrUE | 172.21.19.13, X300 (192.168.60.2) |
| porcepix | 172.21.16.136 | CI-Porcepix | Executor, EPC, 5GC | -- |
| up2 | 172.21.19.68 | CI-UP2-Usage | COTS UE | Quectel RM520N |
| nepes | 172.21.16.137 | CI-Nepes | gNB (n78), EPC/5GC | B200mini (30C51EB) |
| ofqot | 172.21.16.109 | CI-Ofqot | gNB (n78) | B200mini (30C51D4) |
| idefix | 172.21.16.135 | CI-Idefix | COTS UE | Quectel RM500Q |
| caracal | 172.21.16.132 | CI-Caracal | gNB/phytest | N300 (192.168.10.2) |
| amariue | 172.21.16.144 | CI-Amarisoft-UE-Usage | nrUE | Amarisoft UE simulator |
| nano | 172.21.18.48 | CI-Nano-Legacy-EPC | Executor, EPC, adb | 2x COTS (adb) |
| hutch | 172.21.18.46 | CI-Hutch-Legacy-FDD-eNB | eNB (B7) | B200mini (30C5239) |
| starsky | 172.21.18.45 | CI-Starsky-Legacy-TDD-eNB | eNB (B40) | b200mini (30A3E3C) |
| carabe | 172.21.18.47 | CI-Carabe-Legacy-FDD-OAI-LTE-UE | UE (B7UE) | B200mini (30AE8C9) |
| nokiabox | 172.21.19.39 | _None_ | gNB (Nokia), 5GC | _Nokia RF integrated_ |
| avra | 172.21.16.124 | CI-Avra-Usage | gNB (n78) | AW2S Jaguar (192.168.80.239) |
| orion | 172.21.16.134 | CI-Orion-Build-Sanity-Check-Deploy-Test, CI-Orion-DsTester-Deploy-Test | Build | |
| aerial2 | 172.21.16.131 | CI-Aerial2-Usage | gNB (PNF/Nvidia CUBB + VNF) | Foxconn RU, _Nvidia Aerial SDK integrated_ |
| cacofonix | 172.21.16.150 | CI-Cacofonix-Usage | gNB (n78, FHI7.2) | |
| matix | 172.21.19.58 | CI-Matix-Usage | gNB (n77) | N310 |
| gracehopper1-oai | -- | Gracehopper1 | build, gNB/Aerial | _Nvidia Aerial SDK integrated_ |
Note: The available resources, and their current usage, is indicated here:
- [Lockable resources of jenkins-oai](https://jenkins-oai.eurecom.fr/lockable-resources/):
@@ -104,8 +107,6 @@ information on how the images are built.
- target image from `Dockerfile.nr-cuup.rhel9`
- target image from `Dockerfile.lteUE.rhel9`
- target image from `Dockerfile.nrUE.rhel9`
- build image from `Dockerfile.build.fhi72.rhel9`, followed by
- target image from `Dockerfile.gNB.fhi72.rhel9`
- build image from `Dockerfile.phySim.rhel9` (creates as direct target physical simulator
image)
- build image from `Dockerfile.clang.rhel9` (compilation only, artifacts not used currently)
@@ -121,13 +122,10 @@ information on how the images are built.
- target image from `Dockerfile.nrUE.ubuntu22`
- target image from `Dockerfile.lteUE.ubuntu22`
- target image from `Dockerfile.lteRU.ubuntu22`
- target image from `Dockerfile.gNB.aerial.ubuntu22`
- build image from `Dockerfile.build.fhi72.ubuntu22`, followed by
- target image from `Dockerfile.gNB.fhi72.ubuntu22`
- build unit tests from `ci-scripts/docker/Dockerfile.unittest.ubuntu22`, and run them
- [RAN-Ubuntu-ARM-Image-Builder](https://jenkins-oai.eurecom.fr/job/RAN-Ubuntu-ARM-Image-Builder/)
~BUILD-ONLY ~4G-LTE ~5G-NR
- gracehopper3-oai: ARM Ubuntu 22 image build using docker
- gracehopper1-oai: ARM Ubuntu 22 image build using docker
- base image from `Dockerfile.base.ubuntu22`
- build image from `Dockerfile.build.ubuntu22`, followed by
- target image from `Dockerfile.gNB.ubuntu22`
@@ -139,7 +137,7 @@ information on how the images are built.
- [OAI-CN5G-COTS-UE-Test](https://jenkins-oai.eurecom.fr/job/OAI-CN5G-COTS-UE-Test/)
~5G-NR
- using 5GC bench (resources `Cetautomatix`, `Dogmatix`): Attach/Detach of UE with multiple PDU sessions
- using 5GC bench (resources `CI-Cetautomatix-OC-oaicicd-session`, `CI-Dogmatix-CN5G-gNB`): Attach/Detach of UE with multiple PDU sessions
- [OAI-FLEXRIC-RAN-Integration-Test](https://jenkins-oai.eurecom.fr/job/OAI-FLEXRIC-RAN-Integration-Test/) ~5G-NR ~nrUE
- selfix (gNB, nrUE, OAI 5GC, FlexRIC)
- uses RFsimulator, tests FlexRIC/E2 interface and xApps
@@ -173,7 +171,7 @@ information on how the images are built.
- basic NSA test
- [RAN-PhySim-Cluster](https://jenkins-oai.eurecom.fr/job/RAN-PhySim-Cluster/)
~4G-LTE ~5G-NR ~nrUE
- cluster (`RAN_OC` resource), tests in OpenShift Cluster
- cluster (`Asterix-OC-oaicicd-session` resource), tests in OpenShift Cluster
- unitary simulators (`nr_dlsim`, etc.)
- see [`./physical-simulators.md`](./physical-simulators.md) for an overview
- [RAN-RF-Sim-Test-4G](https://jenkins-oai.eurecom.fr/job/RAN-RF-Sim-Test-4G/)
@@ -199,7 +197,7 @@ information on how the images are built.
- OpenShift cluster for CN deployment and container images for gNB and UE deployment
- [RAN-SA-AERIAL-CN5G](https://jenkins-oai.eurecom.fr/job/RAN-SA-AERIAL-CN5G/)
~5G-NR
- 5G-NR SA test setup: OAI VNF + PNF/NVIDIA CUBB on gracehopper1-oai + Foxconn RU, up2 + COTS UE (Quectel RM520N), OAI CN5G
- 5G-NR SA test setup: OAI VNF + PNF/NVIDIA CUBB on Aerial2 + Foxconn RU, up2 + COTS UE (Quectel RM520N), OAI CN5G
- container images for gNB deployment
- [RAN-SA-2x2-Module-CN5G](https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-SA-2x2-Module-CN5G/)
~5G-NR

View File

@@ -29,25 +29,6 @@ cd cmake_targets/ran_build/build
sudo LD_LIBRARY_PATH=. ./nr-softmodem ...
```
### Possible problems
On some systems with specific ASan versions, executing a program compiled with
ASan might fail with an error `DEADLYSIGNAL`, or simply a segmentation fault.
Note that since OAI compiles and runs some programs _during compilation_ (for
code generation), typically already the build is impacted.
The issue is related to Address Space Layout Randomization (ASLR) settings
in Linux, a security feature designed to make it more difficult for attackers
to predict the locations of processes in memory. In this case, it is possible
to avoid the bug by running
```
sudo sysctl vm.mmap_rnd_bits=30
```
which reduces the number of bits for memory mappings used to randomize mmap
base addresses. _This reduces the security of the system._
## Undefined Behavior Sanitizer (UBSAN)
[Undefined Behavior Sanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) (UBSAN) is a runtime undefined behavior checker. It uses compile-time instrumentation to catch undefined behavior by inserting code that performs specific checks before operations that may cause it. UBSAN can be activated with the `--sanitize-undefined` option or `-fsanitize=undefined`.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 92 KiB

View File

@@ -13,15 +13,15 @@
duplexer/.style={draw,fill=white},
]
\node[label=above:cluster] (cluster)
\node[label=above:porcepix] (porcepix)
{\includegraphics[width=1.2cm]{server}};
\node[above right=-0.6cm and 2cm of cluster, label=above:gracehopper1-oai] (gracehopper1-oai)
\node[above right=-0.8cm and 2cm of porcepix, label=above:aerial2] (aerial2)
{\includegraphics[width=1.2cm]{server}}
edge (cluster);
\node[right=0.3cm of gracehopper1-oai, label=above:Foxconn, draw,
edge (porcepix);
\node[right=0.3cm of aerial2, label=above:Foxconn, draw,
minimum width=1.7cm, minimum height=0.8cm] (foxconn)
{O-RU} edge (gracehopper1-oai);
{O-RU} edge (aerial2);
\node[below right=+0.45cm and 0.35cm of foxconn.east] (antf1)
{\includegraphics[width=0.3cm]{antenna}} edge (foxconn.east);
\node[below right=-0.1cm and 0.35cm of foxconn.east] (antf2)
@@ -31,7 +31,7 @@
\node[above right=+0.45cm and 0.35cm of foxconn.east] (antf4)
{\includegraphics[width=0.3cm]{antenna}} edge (foxconn.east);
\node[above right=+1.5cm and 2cm of cluster, label=above:matix] (matix)
\node[above right=+1.3cm and 2cm of porcepix, label=above:matix] (matix)
{\includegraphics[width=1.2cm]{server}};
\node[right=0.3cm of matix, label=above:N310] (n310a)
{\includegraphics[width=1.5cm]{n310}} edge (matix);
@@ -41,9 +41,22 @@
\node[above right=-0.1cm and 0.35cm of b77o.east] (anto2)
{\includegraphics[width=0.3cm]{antenna}} edge (b77o);
\node[below right=-0.4cm and 2cm of cluster, label=above:cacofonix] (cacofonix)
\node[below right=-0.6cm and 2cm of porcepix, label=above:obelix] (obelix)
{\includegraphics[width=1.2cm]{server}}
edge (cluster);
edge (porcepix);
\node[right=0.3cm of obelix, label=above:N310] (n310o)
{\includegraphics[width=1.5cm]{n310}} edge (obelix);
\node[right=.2cm of n310o, duplexer] (b78o) {n40} edge (n310o);
\node[below right=-0.1cm and 0.35cm of b78o.east] (anto1)
{\includegraphics[width=0.3cm]{antenna}} edge (b78o);
\node[above right=-0.1cm and 0.35cm of b78o.east] (anto2)
{\includegraphics[width=0.3cm]{antenna}} edge (b78o);
\node[below=2cm of porcepix, label=above:Cluster] (cluster)
{\includegraphics[width=1.2cm]{server}};
\node[right=2cm of cluster, label=above:cacofonix] (cacofonix)
{\includegraphics[width=1.2cm]{server}}
edge (cluster);
\node[right=0.3cm of cacofonix, label=above:VVDN, draw,
minimum width=1.7cm, minimum height=0.8cm] (vvdn)
{O-RU} edge (cacofonix);
@@ -56,28 +69,7 @@
\node[above right=+0.45cm and 0.35cm of vvdn.east] (antv4)
{\includegraphics[width=0.3cm]{antenna}} edge (vvdn.east);
\node[below=2cm of cluster, label=above:porcepix] (porcepix)
{\includegraphics[width=1.2cm]{server}};
\node[right=2cm of porcepix, label=above:obelix] (obelix)
{\includegraphics[width=1.2cm]{server}}
edge (porcepix);
\node[right=0.3cm of obelix, label=above:N310] (n310o)
{\includegraphics[width=1.5cm]{n310}} edge (obelix);
\node[right=.2cm of n310o, duplexer] (b78o) {n40} edge (n310o);
\node[below right=-0.1cm and 0.35cm of b78o.east] (anto1)
{\includegraphics[width=0.3cm]{antenna}} edge (b78o);
\node[above right=-0.1cm and 0.35cm of b78o.east] (anto2)
{\includegraphics[width=0.3cm]{antenna}} edge (b78o);
%\node[right=0.3cm of cacofonix, label=above:N310] (n310o)
% {\includegraphics[width=1.5cm]{n310}} edge (cacofonix);
\node[right=.2cm of n310o, duplexer] (b78o) {n40} edge (n310o);
\node[below right=-0.1cm and 0.35cm of b78o.east] (anto1)
{\includegraphics[width=0.3cm]{antenna}} edge (b78o);
\node[above right=-0.1cm and 0.35cm of b78o.east] (anto2)
{\includegraphics[width=0.3cm]{antenna}} edge (b78o);
\node[above right=+0.0cm and 5.0cm of vvdn.east, label=above:RM520N-GL] (quectel)
\node[above right=+0.0cm and 5.0cm of n310o.east, label=above:RM520N-GL] (quectel)
{\includegraphics[height=1.2cm]{quectel}};
\node[above left=-0.1cm and 0.8cm of quectel.west] (aq2)
{\includegraphics[width=0.3cm]{antenna}} edge (quectel);

View File

@@ -1,286 +0,0 @@
# Time management module
[[_TOC_]]
## Introduction
Several parts of the 4G/5G protocol stack keep track of time, for example
for timeout events (in RRC, PDCP, or RLC for example).
The obvious simple way to deal with time is to use the computer's realtime
clock. This works well when we run the stack in realtime, with real
radio equipment. But in simulation the system may run faster or slower
than realtime, so we need another way to deal with time. A good solution
is then to base time on the current IQ data processed by the system. So time
becomes "IQ samples" based, not realtime.
The system may be decomposed into various components (CU, DU, RU, various
UEs) running either in realtime or simulation. Time may be distributed
to all these components from only one time source for accurate execution
of the scenario, or each component may have its own time source, either
based on realtime or IQ samples.
## Overall structure
The time management module is made of three main parts. The first one
is the time source. It can either be realtime or "IQ samples" based.
In one running scenario of the system, there can be one or more time
sources (imagine one for the gNB, and one per each UE). There can also
be only one time source, shared between various users of the time
manager.
The second part is the server. One server is attached to one time source
and receives a tick every millisecond (real or simulated) from the time
source. It distributes the tick to the various connected clients.
And finally the last part is the client, which connects to a single server
and receives ticks from it. The client does not have a time source attached
to it. It gets the time from the server.
It is possible for a program (monolithic gNB for example) to have only
a time source, without server or client.
## Configuration
To configure the time management module, add the following section in
the configuration file.
```
time_management = {
#valid time sources: realtime, iq_samples
time_source = realtime
#valid modes: standalone, server, client
mode = standalone
#set ip/port of server (for server mode, this is the address/port to bind to;
#for client mode, this is the address/port to connect to)
server_ip = "127.0.0.1"
server_port = 7374
}
```
If not set in the configuration file, some default is applied, depending
on the program run. (See the function `time_manager_start()` for details.)
It is also possible to pass configuration parameters on the command line.
For example add `--time_manager.time_source iq_samples` to the command line
to set the time source to `iq_samples`. The same syntax is applicable to the
other parameters.
## Examples
Here come some examples of configuration for typical use cases of OAI.
### Monolithic gNB realtime
This is a very simple example. The gNB runs in `standalone` mode with
a `realtime` time source.
```
time_management = {
time_source = realtime
mode = standalone
}
```
### Monolithic gNB "IQ samples time"
For this configuration, it's the same as the previous example, but the
time source is now `iq_samples`.
```
time_management = {
time_source = iq_samples
mode = standalone
}
```
### RF simulator CU/DU "IQ samples time"
Let's suppose the CU runs on a machine with IP address 1.2.3.4 and the DU
runs on a machine with IP address 10.11.12.13.
The DU has the time source and so is the server. The CU acts as a client.
Here comes the configuration for the CU.
```
time_management = {
mode = client
server_ip = "10.11.12.13"
server_port = 7374
}
```
And here is the configuration for the DU.
```
time_management = {
time_source = iq_samples
mode = server
server_ip = "10.11.12.13"
server_port = 7374
}
```
### RF simulator CU/DU "realtime"
Let's suppose the CU runs on a machine with IP address 1.2.3.4 and the DU
runs on a machine with IP address 10.11.12.13.
CU and DU can both run in standalone mode, with no exchange between them.
Any one of them can also acts as a server and the other one as a client.
Let's suppose for this example that the CU and the DU run in client/server
mode. Let's set the CU as the time source and so as the server. The DU acts
as a client.
Here comes the configuration for the CU.
```
time_management = {
time_source = realtime
mode = server
server_ip = "1.2.3.4"
server_port = 7374
}
```
And here is the configuration for the DU.
```
time_management = {
mode = client
server_ip = "1.2.3.4"
server_port = 7374
}
```
Note that the time management module is flexible. It's possible to
configure more complex setups. For example the time source can be a gNB
and several UEs can be connected as client.
One could also write a simple program acting as a time source and distributing
time to everyone (one or several gNB, several UEs).
## Programming API
Here comes the internal API of the time manager module. The (simpler) OAI
API is described afterwards.
### Time source
- opaque type: `time_source_t`
- create a time source:
```
time_source_t *new_time_source(time_source_type_t type)
```
where `type` is one of:
* `TIME_SOURCE_REALTIME`
* `TIME_SOURCE_IQ_SAMPLES`
- delete a time source:
```
void free_time_source(time_source_t *time_source)
```
- set millisecond callback:
```
void time_source_set_callback(time_source_t *time_source,
void (*callback)(void *),
void *callback_data)
```
where `callback` is a function that will be called for each millisecond using
the provided `callback_data`
- for IQ samples time management, the user of the time source must call
this function when it processes IQ samples:
```
void time_source_iq_add(time_source_t *time_source,
uint64_t iq_samples_count,
uint64_t iq_samples_per_second)
```
then the time source will generate a tick for each block for IQ samples
lasting one millisecond. (If you pass `iq_samples_count` lasting several
milliseconds then the time source will generate several ticks in a row,
one for each millisecond.)
### Server
- opaque type: `time_server_t`
- create a server:
```
time_server_t *new_time_server(const char *ip,
int port,
void (*callback)(void *),
void *callback_data)
```
where ip/port is the IP adress and port the server will listen to
and `callback` is a function that will be called for each millisecond using
the provided `callback_data`
- delete a server:
```
void free_time_server(time_server_t *time_server)
```
- attach a time source:
```
void time_server_attach_time_source(time_server_t *time_server,
time_source_t *time_source)
```
### Client
- opaque type: `time_client_t`
- create a client:
```
time_client_t *new_time_client(const char *server_ip,
int server_port,
void (*callback)(void *),
void *callback_data)
```
the client will connect on given server ip/port
and use the `callback` with `callback_data` for each tick received
- delete a client:
```
void free_time_client(time_client_t *time_client)
```
### Threading
Each component (time source, server, client) runs its own thread which will
be the one calling the configured callback. Be careful of using proper
synchronization techniques in your callback to have correct behavior with
the other threads of the program.
## OAI API
OAI uses the time manager through a simplified API. All the code is contained
in `time_manager.c`, together with some global variables (so that there is no
need to pass objects around, to limit risks of misuse).
Each program (for example: gnb, ue, cu, du) calls the `time_manager_start()`
function, passing the callback functions to be called when a tick is generated
(several callbacks can be passed) and a default time source. Based on this,
`time_manager_start()` initializes what is needed.
The function `time_manager_iq_samples()` is to be called by programs that
read IQ samples. It is called unconditionally. It may do nothing if the
configuration is to use realtime ticks and not IQ samples ticks.
When the program exits, it calls `timer_manager_finish()` which in turns stops
the various threads created by `time_manager_start()` and releases all the
allocated data.
Here comes the API.
- init the time manager:
```
void time_manager_start(time_manager_tick_function_t *tick_functions,
int tick_functions_count,
time_source_type_t time_source);
```
(for valid values of `client_type` and `running_mode` see in
`time_manager.h`)
- update IQ samples' based time manager:
```
void time_manager_iq_samples(uint64_t iq_samples_count,
uint64_t iq_samples_per_second)
```
- terminate the time manager:
```
void time_manager_finish(void)
```

View File

@@ -1,101 +0,0 @@
#/*
# * 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
# */
#---------------------------------------------------------------------
#
# Dockerfile for the Open-Air-Interface RAN Build for FHI 7.2
# Valid for UBUNTU 22.04
#
#---------------------------------------------------------------------
FROM ran-base:latest AS ran-base
ARG E2AP_VERSION=E2AP_V3
ARG KPM_VERSION=KPM_V3_00
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Europe
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
DEBIAN_FRONTEND=noninteractive apt-get install --yes \
meson \
wget \
xz-utils \
pkg-config \
libnuma-dev && \
rm -rf /var/lib/apt/lists/*
RUN rm -Rf /oai-ran
WORKDIR /oai-ran
COPY . .
## Download and build DPDK
RUN wget http://fast.dpdk.org/rel/dpdk-20.11.9.tar.xz && \
tar -xvf dpdk-20.11.9.tar.xz && \
cd dpdk-stable-20.11.9 && \
meson build && \
ninja -C build && \
ninja install -C build
## Build Fronthaul library
RUN git clone https://gerrit.o-ran-sc.org/r/o-du/phy.git /opt/phy && \
cd /opt/phy && \
git checkout oran_f_release_v1.0 &&\
git apply /oai-ran/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch && \
cd /opt/phy/fhi_lib/lib && \
TARGET=armv8 WIRELESS_SDK_TOOLCHAIN=gcc RTE_SDK=/oai-ran/dpdk-stable-20.11.9/ XRAN_DIR=/opt/phy/fhi_lib make XRAN_LIB_SO=1
## Build Arm RAN Acceleration Library
RUN git clone https://git.gitlab.arm.com/networking/ral.git /opt/ral && \
cd /opt/ral && \
git checkout armral-25.01 &&\
mkdir build && \
cd build && \
cmake -GNinja -DBUILD_SHARED_LIBS=On /opt/ral/ && \
ninja && \
ninja install
FROM ran-base AS ran-build-fhi72
## Build and install OAI
#run build_oai to build the target image
RUN /bin/sh oaienv && \
cd cmake_targets && \
mkdir -p log && \
./build_oai \
--gNB \
--build-lib "telnetsrv enbscope uescope nrscope" \
-t oran_fhlib_5g --cmake-opt -Dxran_LOCATION=/opt/phy/fhi_lib/lib \
--build-e2 --cmake-opt -DXAPP_MULTILANGUAGE=OFF --cmake-opt -DKPM_VERSION=$KPM_VERSION --cmake-opt -DE2AP_VERSION=$E2AP_VERSION \
$BUILD_OPTION && \
# Mainly to see if the sanitize option was perfectly executed
ldd ran_build/build/nr-softmodem && \
ldd ran_build/build/liboran_fhlib_5g.so && \
ldd /opt/phy/fhi_lib/lib/build/libxran.so
## Build FlexRIC for SM Models
RUN mkdir -p openair2/E2AP/flexric/build && \
cd openair2/E2AP/flexric/build && \
cmake -GNinja -DCMAKE_BUILD_TYPE=Release \
-DXAPP_MULTILANGUAGE=OFF \
-DKPM_VERSION=$KPM_VERSION \
-DE2AP_VERSION=$E2AP_VERSION \
-DCMAKE_C_COMPILER=gcc-12 \
-DCMAKE_CXX_COMPILER=g++-12 .. && \
ninja && \
ninja install

View File

@@ -61,7 +61,7 @@ RUN /bin/sh oaienv && \
--gNB \
--build-lib 'telnetsrv enbscope uescope nrscope' \
-t oran_fhlib_5g --cmake-opt -Dxran_LOCATION=/opt/phy/fhi_lib/lib \
--build-e2 --cmake-opt -DKPM_VERSION=$KPM_VERSION --cmake-opt -DE2AP_VERSION=$E2AP_VERSION" &&\
--build-e2 --cmake-opt -DXAPP_MULTILANGUAGE=OFF --cmake-opt -DKPM_VERSION=$KPM_VERSION --cmake-opt -DE2AP_VERSION=$E2AP_VERSION" &&\
# Mainly to see if the sanitize option was perfectly executed
ldd ran_build/build/nr-softmodem && \
ldd ran_build/build/liboran_fhlib_5g.so && \
@@ -72,6 +72,7 @@ RUN mkdir -p openair2/E2AP/flexric/build && \
cd openair2/E2AP/flexric/build && \
scl enable gcc-toolset-13 "\
cmake -GNinja -DCMAKE_BUILD_TYPE=Release \
-DXAPP_MULTILANGUAGE=OFF \
-DKPM_VERSION=$KPM_VERSION \
-DE2AP_VERSION=$E2AP_VERSION .. &&\
ninja && \

View File

@@ -71,7 +71,7 @@ RUN /bin/sh oaienv && \
--gNB \
--build-lib "telnetsrv enbscope uescope nrscope" \
-t oran_fhlib_5g --cmake-opt -Dxran_LOCATION=/opt/phy/fhi_lib/lib \
--build-e2 --cmake-opt -DKPM_VERSION=$KPM_VERSION --cmake-opt -DE2AP_VERSION=$E2AP_VERSION \
--build-e2 --cmake-opt -DXAPP_MULTILANGUAGE=OFF --cmake-opt -DKPM_VERSION=$KPM_VERSION --cmake-opt -DE2AP_VERSION=$E2AP_VERSION \
$BUILD_OPTION && \
# Mainly to see if the sanitize option was perfectly executed
ldd ran_build/build/nr-softmodem && \
@@ -82,6 +82,7 @@ RUN /bin/sh oaienv && \
RUN mkdir -p openair2/E2AP/flexric/build && \
cd openair2/E2AP/flexric/build && \
cmake -GNinja -DCMAKE_BUILD_TYPE=Release \
-DXAPP_MULTILANGUAGE=OFF \
-DKPM_VERSION=$KPM_VERSION \
-DE2AP_VERSION=$E2AP_VERSION \
-DCMAKE_C_COMPILER=gcc-12 \

View File

@@ -41,7 +41,8 @@ RUN /bin/sh oaienv && \
scl enable gcc-toolset-13 "\
CXXFLAGS='-Werror -fstack-protector-strong' CFLAGS='-Werror -fstack-protector-strong' ./build_oai -c --ninja \
--eNB --gNB --RU --UE --nrUE \
--build-e2 --cmake-opt -DKPM_VERSION=$KPM_VERSION --cmake-opt -DE2AP_VERSION=$E2AP_VERSION \
--build-e2 --cmake-opt -DXAPP_MULTILANGUAGE=OFF --cmake-opt \
-DKPM_VERSION=$KPM_VERSION --cmake-opt -DE2AP_VERSION=$E2AP_VERSION \
--build-lib 'telnetsrv enbscope uescope nrscope' \
--build-tool-opt -k10 \
-w USRP -t Ethernet \
@@ -56,6 +57,7 @@ RUN mkdir -p openair2/E2AP/flexric/build && \
cd openair2/E2AP/flexric/build && \
scl enable gcc-toolset-13 "\
cmake -GNinja -DCMAKE_BUILD_TYPE=Release \
-DXAPP_MULTILANGUAGE=OFF \
-DKPM_VERSION=$KPM_VERSION \
-DE2AP_VERSION=$E2AP_VERSION .. &&\
ninja && \

View File

@@ -43,7 +43,7 @@ RUN /bin/sh oaienv && \
--eNB --gNB --RU --UE --nrUE \
--build-lib "telnetsrv enbscope uescope nrscope" \
-w USRP -t Ethernet \
--build-e2 --cmake-opt -DKPM_VERSION=$KPM_VERSION --cmake-opt -DE2AP_VERSION=$E2AP_VERSION \
--build-e2 --cmake-opt -DXAPP_MULTILANGUAGE=OFF --cmake-opt -DKPM_VERSION=$KPM_VERSION --cmake-opt -DE2AP_VERSION=$E2AP_VERSION \
--noavx512 \
--build-tool-opt -k10 \
--cmake-opt -DCMAKE_C_FLAGS="-Werror" --cmake-opt -DCMAKE_CXX_FLAGS="-Werror" $BUILD_OPTION && \
@@ -57,6 +57,7 @@ RUN /bin/sh oaienv && \
RUN mkdir -p openair2/E2AP/flexric/build && \
cd openair2/E2AP/flexric/build && \
cmake -GNinja -DCMAKE_BUILD_TYPE=Release \
-DXAPP_MULTILANGUAGE=OFF \
-DKPM_VERSION=$KPM_VERSION \
-DE2AP_VERSION=$E2AP_VERSION \
-DCMAKE_C_COMPILER=gcc-12 \

View File

@@ -31,7 +31,6 @@
#include "openair2/F1AP/f1ap_ids.h"
#include "openair2/GNB_APP/gnb_config.h"
#include "nr_pdcp/nr_pdcp_oai_api.h"
#include "common/utils/time_manager/time_manager.h"
RAN_CONTEXT_t RC;
THREAD_STRUCT thread_struct;
@@ -103,12 +102,16 @@ ngran_node_t get_node_type()
return ngran_gNB_CUUP;
}
rlc_op_status_t nr_rlc_data_req(const protocol_ctxt_t *const ctxt_pP,
const srb_flag_t srb_flagP,
const rb_id_t rb_idP,
const mui_t muiP,
sdu_size_t sdu_sizeP,
uint8_t *sdu_pP)
rlc_op_status_t rlc_data_req(const protocol_ctxt_t *const pc,
const srb_flag_t sf,
const MBMS_flag_t mf,
const rb_id_t rb_id,
const mui_t mui,
const confirm_t c,
const sdu_size_t size,
uint8_t *const buf,
const uint32_t *const a,
const uint32_t *const b)
{
abort();
return 0;
@@ -120,6 +123,16 @@ int nr_rlc_get_available_tx_space(const rnti_t rntiP, const logical_chan_id_t ch
return 0;
}
void nr_rlc_add_drb(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig)
{
abort();
}
void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p, e1ap_bearer_setup_resp_t *e1ap_resp)
{
abort();
}
f1ap_cudu_inst_t *getCxt(instance_t instanceP)
{
// the E1 module uses F1's getCxt() to decide whether there is F1-U and if
@@ -133,6 +146,8 @@ f1ap_cudu_inst_t *getCxt(instance_t instanceP)
}
configmodule_interface_t *uniqCfg = NULL;
void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, uint32_t gNB_ue_ngap_id) { };
int main(int argc, char **argv)
{
/// static configuration for NR at the moment
@@ -140,16 +155,6 @@ int main(int argc, char **argv)
exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
}
logInit();
// start time manager with some reasonable default for the running mode
// (may be overwritten in configuration file or command line)
void nr_pdcp_ms_tick(void);
time_manager_tick_function_t tick_functions[] = {
nr_pdcp_ms_tick
};
int tick_functions_count = 1;
time_manager_start(tick_functions, tick_functions_count, TIME_SOURCE_REALTIME);
// strdup to put the sring in the core file for post mortem identification
LOG_I(HW, "Version: %s\n", strdup(OAI_PACKAGE_VERSION));
set_softmodem_sighandler();
@@ -188,8 +193,6 @@ int main(int argc, char **argv)
printf("TYPE <CTRL-C> TO TERMINATE\n");
itti_wait_tasks_end(NULL);
time_manager_finish();
logClean();
printf("Bye.\n");
return 0;

View File

@@ -31,45 +31,54 @@
*/
#define _GNU_SOURCE
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
#include <pthread.h>
#include <fcntl.h> // for SEEK_SET
#include <pthread.h> // for pthread_join
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "common/utils/LOG/log.h"
#include "common/utils/system.h"
#include "PHY/NR_ESTIMATION/nr_ul_estimation.h"
#include "openair1/PHY/NR_TRANSPORT/nr_dlsch.h"
#include "openair1/PHY/NR_TRANSPORT/nr_ulsch.h"
#include "NR_PHY_INTERFACE/NR_IF_Module.h"
#include "PHY/INIT/nr_phy_init.h"
#include "PHY/MODULATION/nr_modulation.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/TOOLS/tools_defs.h"
#include "PHY/defs_RU.h"
#include "PHY/defs_common.h"
#include "PHY/defs_gNB.h"
#include "PHY/defs_nr_common.h"
#include "PHY/impl_defs_nr.h"
#include "SCHED_NR/fapi_nr_l1.h"
#include "SCHED_NR/phy_frame_config_nr.h"
#include "SCHED_NR/sched_nr.h"
#include "assertions.h"
#include "common/ran_context.h"
#include "common/utils/LOG/log.h"
#include "executables/softmodem-common.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include "nfapi_nr_interface_scf.h"
#include "notified_fifo.h"
#include "openair2/NR_PHY_INTERFACE/nr_sched_response.h"
#include "thread-pool.h"
#include "time_meas.h"
#include "utils.h"
#include <common/utils/LOG/log.h>
#include <common/utils/system.h>
#include "PHY/types.h"
#include "PHY/INIT/nr_phy_init.h"
#include "PHY/defs_gNB.h"
#include "SCHED_NR/sched_nr.h"
#include "SCHED_NR/fapi_nr_l1.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/MODULATION/nr_modulation.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "openair2/NR_PHY_INTERFACE/nr_sched_response.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "radio/COMMON/common_lib.h"
#include "PHY/LTE_TRANSPORT/if4_tools.h"
#include "PHY/phy_extern.h"
#include "common/ran_context.h"
#include "RRC/LTE/rrc_extern.h"
#include "PHY_INTERFACE/phy_interface.h"
#include "common/utils/LOG/log.h"
#include "UTIL/OTG/otg_tx.h"
#include "UTIL/OTG/otg_externs.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
#include "gnb_paramdef.h"
#include <executables/softmodem-common.h>
#include "T.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include "executables/softmodem-common.h"
#include <nfapi/oai_integration/nfapi_pnf.h>
#include <openair1/PHY/NR_TRANSPORT/nr_ulsch.h>
#include <openair1/PHY/NR_TRANSPORT/nr_dlsch.h>
#include <PHY/NR_ESTIMATION/nr_ul_estimation.h>
// #define USRP_DEBUG 1
#include "executables/thread-common.h"
//#define TICK_TO_US(ts) (ts.diff)
#define TICK_TO_US(ts) (ts.trials==0?0:ts.diff/ts.trials)
#define L1STATSSTRLEN 16384
static void rx_func(processingData_L1_t *param);
@@ -267,11 +276,9 @@ void *nrL1_stats_thread(void *param) {
char output[L1STATSSTRLEN];
memset(output,0,L1STATSSTRLEN);
wait_sync("L1_stats_thread");
FILE *fd=fopen("nrL1_stats.log","w");
if (!fd) {
LOG_W(NR_PHY, "Cannot open nrL1_stats.log: %d, %s\n", errno, strerror(errno));
return NULL;
}
FILE *fd;
fd=fopen("nrL1_stats.log","w");
AssertFatal(fd!=NULL,"Cannot open nrL1_stats.log\n");
reset_meas(&gNB->phy_proc_tx);
reset_meas(&gNB->dlsch_encoding_stats);

View File

@@ -47,7 +47,6 @@
#include "SCHED_NR/sched_nr.h"
#include "common/utils/LOG/log.h"
#include "common/utils/time_manager/time_manager.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include <executables/softmodem-common.h>
@@ -1250,10 +1249,6 @@ void *ru_thread(void *param)
slot++;
}
// pretend we have 1 iq sample per slot
// and so slots_per_frame * 100 iq samples per second (1 frame being 10ms)
time_manager_iq_samples(1, fp->slots_per_frame * 100);
// synchronization on input FH interface, acquire signals/data and block
LOG_D(PHY,"[RU_thread] read data: frame_rx = %d, tti_rx = %d\n", frame, slot);

View File

@@ -28,7 +28,6 @@
#include "PHY/TOOLS/smbv.h"
unsigned short config_frames[4] = {2,9,11,13};
#endif
#include "common/utils/time_manager/time_manager.h"
#ifdef ENABLE_AERIAL
#include "nfapi/oai_integration/aerial/fapi_nvIPC.h"
#endif
@@ -86,7 +85,6 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "utils.h"
#include "x2ap_eNB.h"
#include "openair1/SCHED_NR/sched_nr.h"
#include "openair2/SDAP/nr_sdap/nr_sdap.h"
pthread_cond_t nfapi_sync_cond;
pthread_mutex_t nfapi_sync_mutex;
@@ -466,14 +464,23 @@ int start_L1L2(module_id_t gnb_id)
NR_BCCH_BCH_Message_t *mib = mac->common_channels[0].mib;
const NR_BCCH_DL_SCH_Message_t *sib1 = mac->common_channels[0].sib1;
/* update existing config in F1 Setup request structures */
f1ap_setup_req_t *sr = mac->f1_config.setup_req;
DevAssert(sr->num_cells_available == 1);
f1ap_served_cell_info_t *info = &sr->cell[0].info;
DevAssert(info->mode == F1AP_MODE_TDD);
/* update existing config in F1 Setup request structures */
DevAssert(scc->tdd_UL_DL_ConfigurationCommon != NULL);
info->tdd = read_tdd_config(scc); /* updates radio config */
prepare_du_configuration_update(mac, info, mib, sib1);
/* send gNB-DU configuration update to RRC */
f1ap_gnb_du_configuration_update_t update = {
.transaction_id = 1,
.num_cells_to_modify = 1,
};
update.cell_to_modify[0].old_nr_cellid = info->nr_cellid;
update.cell_to_modify[0].info = *info;
update.cell_to_modify[0].sys_info = get_sys_info(mib, sib1);
mac->mac_rrc.gnb_du_configuration_update(&update);
init_NR_RU(config_get_if(), NULL);
@@ -499,8 +506,11 @@ static void wait_nfapi_init(char *thread_name)
}
void init_pdcp(void) {
uint32_t pdcp_initmask = IS_SOFTMODEM_NOS1 ? ENB_NAS_USE_TUN_BIT : LINK_ENB_PDCP_TO_GTPV1U_BIT;
if (!NODE_IS_DU(get_node_type())) {
nr_pdcp_layer_init();
nr_pdcp_module_init(pdcp_initmask, 0);
}
}
@@ -519,9 +529,9 @@ static void initialize_agent(ngran_node_t node_type, e2_agent_args_t oai_args)
const gNB_RRC_INST* rrc = RC.nrrrc[0];
assert(rrc != NULL && "rrc cannot be NULL");
const int mcc = rrc->configuration.plmn[0].mcc;
const int mnc = rrc->configuration.plmn[0].mnc;
const int mnc_digit_len = rrc->configuration.plmn[0].mnc_digit_length;
const int mcc = rrc->configuration.mcc[0];
const int mnc = rrc->configuration.mnc[0];
const int mnc_digit_len = rrc->configuration.mnc_digit_length[0];
// const ngran_node_t node_type = rrc->node_type;
int nb_id = 0;
int cu_du_id = 0;
@@ -598,6 +608,8 @@ int main( int argc, char **argv ) {
char *pckg = strdup(OAI_PACKAGE_VERSION);
LOG_I(HW, "Version: %s\n", pckg);
// don't create if node doesn't connect to RRC/S1/GTP
const ngran_node_t node_type = get_node_type();
// Init RAN context
if (!(CONFIG_ISFLAGSET(CONFIG_ABORT)))
NRRCConfig();
@@ -612,9 +624,6 @@ int main( int argc, char **argv ) {
RCconfig_nr_prs();
}
// don't create if node doesn't connect to RRC/S1/GTP
const ngran_node_t node_type = get_node_type();
if (NFAPI_MODE != NFAPI_MODE_PNF) {
int ret = create_gNB_tasks(node_type, uniqCfg);
AssertFatal(ret == 0, "cannot create ITTI tasks\n");
@@ -629,38 +638,6 @@ int main( int argc, char **argv ) {
pthread_mutex_init(&sync_mutex, NULL);
}
// start time manager with some reasonable default for the running mode
// (may be overwritten in configuration file or command line)
void nr_pdcp_ms_tick(void);
void x2ap_ms_tick();
void nr_rlc_ms_tick(void);
time_manager_tick_function_t tick_functions[3];
int tick_functions_count = 0;
if (NODE_IS_MONOLITHIC(node_type)) {
/* monolithic */
tick_functions[tick_functions_count++] = nr_pdcp_ms_tick;
tick_functions[tick_functions_count++] = nr_rlc_ms_tick;
/* x2ap is enabled when in NSA mode */
if (get_softmodem_params()->nsa)
tick_functions[tick_functions_count++] = x2ap_ms_tick;
} else if (NODE_IS_CU(node_type)) {
/* CU */
tick_functions[tick_functions_count++] = nr_pdcp_ms_tick;
/* x2ap is enabled when in NSA mode */
if (get_softmodem_params()->nsa)
tick_functions[tick_functions_count++] = x2ap_ms_tick;
} else {
/* DU */
tick_functions[tick_functions_count++] = nr_rlc_ms_tick;
}
time_manager_start(tick_functions, tick_functions_count,
// iq_samples time source for monolithic/du with rfsim,
// realtime time source for other cases
IS_SOFTMODEM_RFSIM
&& (NODE_IS_MONOLITHIC(node_type) || NODE_IS_DU(node_type))
? TIME_SOURCE_IQ_SAMPLES
: TIME_SOURCE_REALTIME);
// start the main threads
number_of_cards = 1;
@@ -758,18 +735,11 @@ int main( int argc, char **argv ) {
if (RC.nb_nr_L1_inst > 0 || RC.nb_RU > 0)
stop_L1(0);
if (RC.nb_nr_macrlc_inst > 0) {
DevAssert(RC.nb_nr_macrlc_inst == 1);
mac_top_destroy_gNB(RC.nrmac[0]);
}
pthread_cond_destroy(&sync_cond);
pthread_mutex_destroy(&sync_mutex);
pthread_cond_destroy(&nfapi_sync_cond);
pthread_mutex_destroy(&nfapi_sync_mutex);
time_manager_finish();
free(pckg);
logClean();
printf("Bye.\n");

View File

@@ -41,8 +41,6 @@
#include "instrumentation.h"
#include "common/utils/threadPool/notified_fifo.h"
#include "position_interface.h"
#include "nr_phy_common.h"
#include "common/utils/time_manager/time_manager.h"
/*
* NR SLOT PROCESSING SEQUENCE
@@ -106,9 +104,7 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg);
static void start_process_slot_tx(void* arg) {
notifiedFIFO_elt_t *newTx = arg;
nr_rxtx_thread_data_t *curMsgTx = NotifiedFifoData(newTx);
int num_ul_actors_to_use =
get_nrUE_params()->num_ul_actors == 0 ? NUM_UL_ACTORS : min(get_nrUE_params()->num_ul_actors, NUM_UL_ACTORS);
pushNotifiedFIFO(&curMsgTx->UE->ul_actors[curMsgTx->proc.nr_slot_tx % num_ul_actors_to_use].fifo, newTx);
pushNotifiedFIFO(&curMsgTx->UE->ul_actor.fifo, newTx);
}
static size_t dump_L1_UE_meas_stats(PHY_VARS_NR_UE *ue, char *output, size_t max_len)
@@ -440,13 +436,9 @@ static void UE_synch(void *arg) {
((ret.rx_offset << 1) / fp->samples_per_subframe * fp->slots_per_subframe)
+ round((float)((ret.rx_offset << 1) % fp->samples_per_subframe) / fp->samples_per_slot0);
if (get_nrUE_params()->cont_fo_comp) {
UE->freq_offset = freq_offset;
} else {
// rerun with new cell parameters and frequency-offset
nr_rf_card_config_freq(cfg0, ul_carrier, dl_carrier, freq_offset);
UE->rfdevice.trx_set_freq_func(&UE->rfdevice, cfg0);
}
// rerun with new cell parameters and frequency-offset
// todo: the freq_offset computed on DL shall be scaled before being applied to UL
nr_rf_card_config_freq(cfg0, ul_carrier, dl_carrier, freq_offset);
if (get_nrUE_params()->agc) {
nr_ue_adjust_rx_gain(UE, cfg0, UE->adjust_rxgain);
@@ -460,6 +452,7 @@ static void UE_synch(void *arg) {
cfg0->rx_freq[0],
cfg0->tx_freq[0]);
UE->rfdevice.trx_set_freq_func(&UE->rfdevice, cfg0);
UE->is_synchronized = 1;
} else {
int gain_change = 0;
@@ -558,17 +551,11 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action)
writeBlockSize -= dummyBlockSize;
}
// pre-compensate UL frequency offset
if (flags != TX_BURST_INVALID && get_nrUE_params()->cont_fo_comp) {
double ul_freq_offset = -UE->freq_offset * ((double)fp->ul_CarrierFreq / (double)fp->dl_CarrierFreq);
if (get_nrUE_params()->cont_fo_comp == 2) // different from LO frequency error compensation, Doppler UL pre-compensation has to be negative
ul_freq_offset = -ul_freq_offset;
for (int i = 0; i < fp->nb_antennas_tx; i++)
nr_fo_compensation(ul_freq_offset, fp->samples_per_subframe, writeTimestamp, txp[i], txp[i], writeBlockSize);
}
int tmp = openair0_write_reorder(&UE->rfdevice, writeTimestamp, txp, writeBlockSize, fp->nb_antennas_tx, flags);
AssertFatal(tmp == writeBlockSize, "");
for (int i = 0; i < fp->nb_antennas_tx; i++)
memset(txp[i], 0, writeBlockSize);
}
void processSlotTX(void *arg)
@@ -601,7 +588,6 @@ void processSlotTX(void *arg)
UE->if_inst->sl_indication(&sl_indication);
stop_meas(&UE->ue_ul_indication_stats);
}
dynamic_barrier_join(rxtxD->next_barrier);
if (phy_data.sl_tx_action) {
@@ -628,14 +614,12 @@ void processSlotTX(void *arg)
UE->if_inst->ul_indication(&ul_indication);
stop_meas(&UE->ue_ul_indication_stats);
}
dynamic_barrier_join(rxtxD->next_barrier);
phy_procedures_nrUE_TX(UE, proc, &phy_data);
}
} else {
dynamic_barrier_join(rxtxD->next_barrier);
}
RU_write(rxtxD, sl_tx_action);
dynamic_barrier_join(rxtxD->next_barrier);
TracyCZoneEnd(ctx);
}
@@ -675,9 +659,7 @@ static int handle_sync_req_from_mac(PHY_VARS_NR_UE *UE)
for (int i = 0; i < NUM_DL_ACTORS; i++) {
flush_actor(UE->dl_actors + i);
}
for (int i = 0; i < NUM_UL_ACTORS; i++) {
flush_actor(UE->ul_actors + i);
}
flush_actor(&UE->ul_actor);
clean_UE_harq(UE);
UE->is_synchronized = 0;
@@ -707,6 +689,16 @@ static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE,
process_msg_rcc_to_mac(msg);
} while (msg);
if (IS_SOFTMODEM_NOS1 || IS_SA_MODE(get_softmodem_params())) {
/* send tick to RLC and PDCP every ms */
if (proc->nr_slot_rx % fp->slots_per_subframe == 0) {
void nr_rlc_tick(int frame, int subframe);
void nr_pdcp_tick(int frame, int subframe);
nr_rlc_tick(proc->frame_rx, proc->nr_slot_rx / fp->slots_per_subframe);
nr_pdcp_tick(proc->frame_rx, proc->nr_slot_rx / fp->slots_per_subframe);
}
}
if (UE->if_inst)
UE->if_inst->slot_indication(UE->Mod_id, false);
@@ -722,10 +714,8 @@ static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE,
sampleShift = pbch_pdcch_processing(UE, proc, phy_data);
if (phy_data->dlsch[0].active && phy_data->dlsch[0].rnti_type == TYPE_C_RNTI_) {
// indicate to tx thread to wait for DLSCH decoding
if (phy_data->dlsch[0].dlsch_config.k1_feedback) { // if feedback is 0 there is no HARQ associated with this DLSCH
const int ack_nack_slot = (proc->nr_slot_rx + phy_data->dlsch[0].dlsch_config.k1_feedback) % UE->frame_parms.slots_per_frame;
tx_wait_for_dlsch[ack_nack_slot]++;
}
const int ack_nack_slot = (proc->nr_slot_rx + phy_data->dlsch[0].dlsch_config.k1_feedback) % UE->frame_parms.slots_per_frame;
tx_wait_for_dlsch[ack_nack_slot]++;
}
}
if (fp->frame_type == FDD || !dl_slot) {
@@ -874,12 +864,13 @@ static inline int get_readBlockSize(uint16_t slot, NR_DL_FRAME_PARMS *fp) {
static inline void apply_ntn_config(PHY_VARS_NR_UE *UE,
NR_DL_FRAME_PARMS *fp,
int slot_nr,
bool *update_ntn_system_information,
int *duration_rx_to_tx,
int *timing_advance,
int *ntn_koffset)
{
if (UE->ntn_config_message->update) {
UE->ntn_config_message->update = false;
if (*update_ntn_system_information) {
*update_ntn_system_information = false;
double total_ta_ms = UE->ntn_config_message->ntn_config_params.ntn_total_time_advance_ms;
UE->timing_advance = fp->samples_per_subframe * total_ta_ms;
@@ -925,8 +916,6 @@ void *UE_thread(void *arg)
if (usrp_tx_thread == 1)
UE->rfdevice.trx_write_init(&UE->rfdevice);
InitSinLUT();
notifiedFIFO_t nf;
initNotifiedFIFO(&nf);
@@ -961,9 +950,13 @@ void *UE_thread(void *arg)
double ntn_init_time_drift = get_nrUE_params()->ntn_init_time_drift;
int ntn_koffset = 0;
int duration_rx_to_tx = NR_UE_CAPABILITY_SLOT_RX_TO_TX;
int nr_slot_tx_offset = 0;
bool update_ntn_system_information = false;
while (!oai_exit) {
nr_slot_tx_offset = 0;
if (syncRunning) {
notifiedFIFO_elt_t *res = pollNotifiedFIFO(&nf);
@@ -1088,9 +1081,11 @@ void *UE_thread(void *arg)
absolute_slot++;
TracyCFrameMark;
// pretend we have 1 iq sample per slot
// and so nb_slot_frame * 100 iq samples per second (1 frame being 10ms)
time_manager_iq_samples(1, nb_slot_frame * 100);
if (UE->ntn_config_message->update) {
UE->ntn_config_message->update = false;
update_ntn_system_information = true;
nr_slot_tx_offset = UE->ntn_config_message->ntn_config_params.cell_specific_k_offset << fp->numerology_index;
}
int slot_nr = absolute_slot % nb_slot_frame;
nr_rxtx_thread_data_t curMsg = {0};
@@ -1181,8 +1176,8 @@ void *UE_thread(void *arg)
shiftForNextFrame = ret;
pushNotifiedFIFO(&UE->dl_actors[curMsg.proc.nr_slot_rx % NUM_DL_ACTORS].fifo, newRx);
// apply new NTN timing information
apply_ntn_config(UE, fp, slot_nr, &duration_rx_to_tx, &timing_advance, &ntn_koffset);
// apply new duration next run to avoid thread dead lock
apply_ntn_config(UE, fp, slot_nr, &update_ntn_system_information, &duration_rx_to_tx, &timing_advance, &ntn_koffset);
// Start TX slot processing here. It runs in parallel with RX slot processing
// in current code, DURATION_RX_TO_TX constant is the limit to get UL data to encode from a RX slot
@@ -1193,6 +1188,7 @@ void *UE_thread(void *arg)
curMsgTx->writeBlockSize = writeBlockSize;
curMsgTx->proc.timestamp_tx = writeTimestamp;
curMsgTx->UE = UE;
curMsgTx->proc.nr_slot_tx_offset = nr_slot_tx_offset;
int slot = curMsgTx->proc.nr_slot_tx;
int slot_and_frame = slot + curMsgTx->proc.frame_tx * UE->frame_parms.slots_per_frame;

View File

@@ -49,6 +49,7 @@
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
//#include "../../SIMU/USER/init_lte.h"
#include "RRC/LTE/rrc_vars.h"
#include "PHY_INTERFACE/phy_interface_vars.h"
#include "NR_IF_Module.h"
#include "openair1/SIMULATION/TOOLS/sim.h"
@@ -59,10 +60,10 @@
unsigned short config_frames[4] = {2,9,11,13};
#endif
#include "common/utils/LOG/log.h"
#include "common/utils/time_manager/time_manager.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
#include "enb_config.h"
#include "LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
#include "intertask_interface.h"
@@ -74,7 +75,7 @@ unsigned short config_frames[4] = {2,9,11,13};
#include <openair2/LAYER2/NR_MAC_UE/mac_proto.h>
#include <openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h>
#include <openair1/SCHED_NR_UE/fapi_nr_ue_l1.h>
#include "nr_rlc/nr_rlc_oai_api.h"
/* Callbacks, globals and object handlers */
//#include "stats.h"
@@ -88,6 +89,7 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "nr_nas_msg.h"
#include <openair1/PHY/MODULATION/nr_modulation.h>
#include "openair2/GNB_APP/gnb_paramdef.h"
#include "pdcp.h"
#include "actor.h"
THREAD_STRUCT thread_struct;
@@ -222,8 +224,6 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){
UE->chest_freq = nrUE_params.chest_freq;
UE->chest_time = nrUE_params.chest_time;
UE->no_timing_correction = nrUE_params.no_timing_correction;
UE->initial_fo = nrUE_params.initial_fo;
UE->cont_fo_comp = nrUE_params.cont_fo_comp;
LOG_I(PHY,"Set UE_fo_compensation %d, UE_scan_carrier %d, UE_no_timing_correction %d \n, chest-freq %d, chest-time %d\n",
UE->UE_fo_compensation, UE->UE_scan_carrier, UE->no_timing_correction, UE->chest_freq, UE->chest_time);
@@ -299,10 +299,25 @@ void init_openair0()
static void init_pdcp(int ue_id)
{
if (get_softmodem_params()->nsa && nr_rlc_module_init(NR_RLC_OP_MODE_UE) != 0) {
uint32_t pdcp_initmask = (!IS_SOFTMODEM_NOS1) ? LINK_ENB_PDCP_TO_GTPV1U_BIT : LINK_ENB_PDCP_TO_GTPV1U_BIT;
/*if (IS_SOFTMODEM_RFSIM || (nfapi_getmode()==NFAPI_UE_STUB_PNF)) {
pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT;
}*/
// previous code was:
// if (IS_SOFTMODEM_NOKRNMOD)
// pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT;
// The kernel module (KRNMOD) has been removed from the project, so the 'if'
// was removed but the flag 'pdcp_initmask' was kept, as "no kernel module"
// was always set. further refactoring could take it out
pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT;
if (get_softmodem_params()->nsa && rlc_module_init(0) != 0) {
LOG_I(RLC, "Problem at RLC initiation \n");
}
nr_pdcp_layer_init();
nr_pdcp_module_init(pdcp_initmask, ue_id);
}
// Stupid function addition because UE itti messages queues definition is common with eNB
@@ -432,11 +447,6 @@ int main(int argc, char **argv)
}
}
if (create_tasks_nrue(1) < 0) {
printf("cannot create ITTI tasks\n");
exit(-1); // need a softer mode
}
int mode_offset = get_softmodem_params()->nsa ? NUMBER_OF_UE_MAX : 1;
uint16_t node_number = get_softmodem_params()->node_number;
ue_id_g = (node_number == 0) ? 0 : node_number - 2;
@@ -455,20 +465,9 @@ int main(int argc, char **argv)
get_channel_model_mode(uniqCfg);
}
// start time manager with some reasonable default for the running mode
// (may be overwritten in configuration file or command line)
void nr_pdcp_ms_tick(void);
void nr_rlc_ms_tick(void);
time_manager_tick_function_t tick_functions[] = {
nr_pdcp_ms_tick,
nr_rlc_ms_tick
};
int tick_functions_count = 2;
time_manager_start(tick_functions, tick_functions_count,
// iq_samples time source for rfsim,
// realtime time source if not
IS_SOFTMODEM_RFSIM ? TIME_SOURCE_IQ_SAMPLES
: TIME_SOURCE_REALTIME);
// Delay to allow the convergence of the IIR filter on PRACH noise measurements at gNB side
if (IS_SOFTMODEM_RFSIM && !get_softmodem_params()->phy_test)
sleep(3);
if (!get_softmodem_params()->nsa && get_softmodem_params()->emulate_l1)
start_oai_nrue_threads();
@@ -509,9 +508,7 @@ int main(int argc, char **argv)
for (int i = 0; i < NUM_DL_ACTORS; i++) {
init_actor(&UE[CC_id]->dl_actors[i], "DL_", -1);
}
for (int i = 0; i < NUM_UL_ACTORS; i++) {
init_actor(&UE[CC_id]->ul_actors[i], "UL_", -1);
}
init_actor(&UE[CC_id]->ul_actor, "UL_", -1);
init_nr_ue_vars(UE[CC_id], inst);
if (UE[CC_id]->sl_mode) {
@@ -556,6 +553,11 @@ int main(int argc, char **argv)
// wait for end of program
printf("TYPE <CTRL-C> TO TERMINATE\n");
if (create_tasks_nrue(1) < 0) {
printf("cannot create ITTI tasks\n");
exit(-1); // need a softer mode
}
// Sleep a while before checking all parameters have been used
// Some are used directly in external threads, asynchronously
sleep(2);
@@ -576,9 +578,7 @@ int main(int argc, char **argv)
for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
PHY_VARS_NR_UE *phy_vars = PHY_vars_UE_g[0][CC_id];
if (phy_vars) {
for (int i = 0; i < NUM_UL_ACTORS; i++) {
shutdown_actor(&phy_vars->ul_actors[i]);
}
shutdown_actor(&phy_vars->ul_actor);
for (int i = 0; i < NUM_DL_ACTORS; i++) {
shutdown_actor(&phy_vars->dl_actors[i]);
}
@@ -595,9 +595,6 @@ int main(int argc, char **argv)
}
free_nrLDPC_coding_interface(&nrLDPC_coding_interface);
time_manager_finish();
free(pckg);
return 0;
}

View File

@@ -5,9 +5,6 @@
#include "common/utils/threadPool/thread-pool.h"
#include "PHY/defs_nr_UE.h"
extern int NB_UE_INST;
extern uint16_t ue_id_g;
#define CONFIG_HLP_IF_FREQ "IF frequency for RF, if needed\n"
#define CONFIG_HLP_IF_FREQ_OFF "UL IF frequency offset for RF, if needed\n"
#define CONFIG_HLP_DLSCH_PARA "number of threads for dlsch processing 0 for no parallelization\n"
@@ -17,12 +14,7 @@ extern uint16_t ue_id_g;
#define CONFIG_HLP_TIME_SYNC_I "coefficient for Integrating part of time sync PI controller\n"
#define CONFIG_HLP_NTN_INIT_TIME_DRIFT "Initial NTN DL time drift (feeder link and service link), 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_INITIAL_FO "Initially compensated DL frequency offset (e.g. known Doppler shift in NTN LEO scenario)\n"
#define CONFIG_HLP_FREQ_SYNC_P "coefficient for Proportional part of continuous frequency offset compensation PI controller\n"
#define CONFIG_HLP_FREQ_SYNC_I "coefficient for Integrating part of continuous frequency offset compensation PI controller\n"
#define CONFIG_HLP_CONT_FO_COMP "Enable continuous frequency offset (FO) estimation and compensation and specify main FO source (1 = local oscillator, 2 = Doppler shift)\n"
#define CONFIG_HLP_AGC "Rx Gain control used for UE\n"
#define CONFIG_HLP_NUM_UL_ACTORS "Number of UL actors to use. Set to 0 to use the default value\n"
/***************************************************************************************************************************************/
/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
@@ -73,12 +65,7 @@ extern uint16_t ue_id_g;
{"time-sync-I", CONFIG_HLP_TIME_SYNC_I, 0, .dblptr=&(nrUE_params.time_sync_I), .defdblval=0.0, TYPE_DOUBLE, 0}, \
{"ntn-initial-time-drift", CONFIG_HLP_NTN_INIT_TIME_DRIFT, 0, .dblptr=&(nrUE_params.ntn_init_time_drift), .defdblval=0.0, TYPE_DOUBLE, 0}, \
{"autonomous-ta", CONFIG_HLP_AUTONOMOUS_TA, PARAMFLAG_BOOL, .iptr=&(nrUE_params.autonomous_ta), .defintval=0, TYPE_INT, 0}, \
{"initial-fo", CONFIG_HLP_INITIAL_FO, 0, .dblptr=&(nrUE_params.initial_fo), .defdblval=0.0, TYPE_DOUBLE, 0}, \
{"freq-sync-P", CONFIG_HLP_FREQ_SYNC_P, 0, .dblptr=&(nrUE_params.freq_sync_P), .defdblval=0.01, TYPE_DOUBLE, 0}, \
{"freq-sync-I", CONFIG_HLP_FREQ_SYNC_I, 0, .dblptr=&(nrUE_params.freq_sync_I), .defdblval=0.001, TYPE_DOUBLE, 0}, \
{"cont-fo-comp", CONFIG_HLP_CONT_FO_COMP, 0, .iptr=&(nrUE_params.cont_fo_comp), .defintval=0, TYPE_INT, 0}, \
{"agc", CONFIG_HLP_AGC, PARAMFLAG_BOOL, .iptr=&(nrUE_params.agc), .defintval=0, TYPE_INT, 0}, \
{"num-ul-actors", CONFIG_HLP_NUM_UL_ACTORS, 0, .iptr=&nrUE_params.num_ul_actors, .defintval=0, TYPE_INT, 0}, \
}
// clang-format on
@@ -102,10 +89,6 @@ typedef struct {
double time_sync_I;
double ntn_init_time_drift;
int autonomous_ta;
double initial_fo;
double freq_sync_P;
double freq_sync_I;
int cont_fo_comp;
int agc;
char *usrp_args;
char *tx_subdev;
@@ -118,7 +101,6 @@ typedef struct {
double rx_gain_off;
int vcdflag;
int tx_max_power;
int num_ul_actors;
} nrUE_params_t;
extern uint64_t get_nrUE_optmask(void);
extern uint64_t set_nrUE_optmask(uint64_t bitmask);

View File

@@ -21,6 +21,8 @@
#include "position_interface.h"
extern uint16_t NB_UE_INST;
static void read_position_coordinates(char *sectionName, position_t *position)
{
paramdef_t position_params[] = POSITION_CONFIG_PARAMS_DEF;
@@ -34,4 +36,4 @@ void get_position_coordinates(int Mod_id, position_t *position)
char positionName[64];
snprintf(positionName, sizeof(positionName), "position%d", Mod_id);
read_position_coordinates(positionName, position);
}
}

View File

@@ -144,7 +144,6 @@ extern "C"
#define EMULATE_L1 softmodem_params.emulate_l1
#define CONTINUOUS_TX softmodem_params.continuous_tx
#define SYNC_REF softmodem_params.sync_ref
#define DEFAULT_PDU_ID softmodem_params.default_pdu_session_id
#define DEFAULT_RFCONFIG_FILE "/usr/local/etc/syriq/ue.band7.tm1.PRB100.NR40.dat";
@@ -189,7 +188,6 @@ extern int usrp_tx_thread;
{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, .iptr=&softmodem_params.threequarter_fs, .defintval=0, TYPE_INT, 0}, \
{"imscope" , CONFIG_HLP_IMSCOPE, PARAMFLAG_BOOL, .uptr=&enable_imscope, .defintval=0, TYPE_UINT, 0}, \
{"imscope-record" , CONFIG_HLP_IMSCOPE_RECORD,PARAMFLAG_BOOL, .uptr=&enable_imscope_record, .defintval=0, TYPE_UINT, 0}, \
{"default_pdu_id", NULL, 0, .iptr=&DEFAULT_PDU_ID, .defintval=10, TYPE_INT, 0}, \
}
// clang-format on
@@ -236,7 +234,6 @@ extern int usrp_tx_thread;
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
}
// clang-format on
@@ -346,7 +343,6 @@ typedef struct {
uint32_t sync_ref;
int no_itti;
int threequarter_fs;
int default_pdu_session_id;
} softmodem_params_t;
#define IS_SA_MODE(sM_params) (!(sM_params)->phy_test && !(sM_params)->do_ra && !(sM_params)->nsa)

View File

@@ -129,8 +129,6 @@ typedef struct {
short rsrp_dBm;
long arfcn;
rlm_t radiolink_monitoring; // -1 no monitoring, 0 out_of_sync, 1 in_sync
// SINR value times 10 as reporting granularity is 0.5
float sinr_dB;
} fapi_nr_ssb_pdu_t;
typedef struct {

View File

@@ -350,7 +350,7 @@ int32_t LDPCdecoder(t_nrLDPC_dec_params *p_decParams,
uint16_t Zc = p_decParams->Z;
uint8_t BG = p_decParams->BG;
// uint8_t numMaxIter = p_decParams->numMaxIter;
int block_length = p_decParams->Kprime;
int block_length = p_decParams->block_length;
// e_nrLDPC_outMode outMode = p_decParams->outMode;
uint8_t row,col;
if(BG == 1){

View File

@@ -627,7 +627,7 @@ static inline void nr_polar_rate_matching_int16(int16_t *input,
memset(output, 0, N * sizeof(*output)); // puncturing
else { // shortening
for (int i = 0; i <= N - 1; i++)
output[i] = INT16_MAX;
output[i] = 32767; // instead of INFINITY, to prevent [-Woverflow]
}
for (int i = 0; i <= E - 1; i++)

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