mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-15 21:50:27 +00:00
Compare commits
20 Commits
pre-commit
...
Aerial_Int
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
606483b385 | ||
|
|
e8f339eeed | ||
|
|
4d0df9cc9c | ||
|
|
484a16c414 | ||
|
|
d68a05bbce | ||
|
|
a101d0f94b | ||
|
|
29c50f7c09 | ||
|
|
acf402b359 | ||
|
|
0e0c79b0e1 | ||
|
|
6d61f40c8b | ||
|
|
2c10e18218 | ||
|
|
07dbb34c21 | ||
|
|
6525a2c3f2 | ||
|
|
c888d93b69 | ||
|
|
a0aeddb482 | ||
|
|
ff97c7a139 | ||
|
|
a0cdd58ced | ||
|
|
0828d57956 | ||
|
|
130b0c436f | ||
|
|
4e475063d7 |
@@ -726,7 +726,6 @@ set(SCHED_SRC_NR_UE
|
||||
add_library(SCHED_NR_UE_LIB ${SCHED_SRC_NR_UE})
|
||||
target_link_libraries(SCHED_NR_UE_LIB PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
|
||||
|
||||
|
||||
# nFAPI
|
||||
#################################
|
||||
set(NFAPI_COMMON_SRC
|
||||
@@ -2066,6 +2065,8 @@ add_executable(nr-softmodem
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/phy_scope_interface.c
|
||||
)
|
||||
|
||||
include(${OPENAIR_DIR}/nfapi/CMakeLists.txt)
|
||||
|
||||
target_link_libraries(nr-softmodem PRIVATE
|
||||
-Wl,--start-group
|
||||
UTIL HASHTABLE SCTP_CLIENT SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU GTPV1U SECURITY
|
||||
|
||||
@@ -18,6 +18,17 @@ up2:
|
||||
IF: wwan0
|
||||
MTU: 1500
|
||||
|
||||
sphex_quectel:
|
||||
Host: sphex
|
||||
InitScript: sudo stdbuf -oL /home/oaicicd/quectel-CM/quectel-CM -4 -s oai.ipv4 &> /tmp/quecel-cm.log &
|
||||
TermScript: sudo -S killall --signal SIGKILL quectel-CM
|
||||
AttachScript: sudo python3 ci_ctl_qtel.py /dev/ttyUSB3 wup
|
||||
DetachScript: sudo python3 ci_ctl_qtel.py /dev/ttyUSB3 detach
|
||||
NetworkScript: ip a show dev wwan0
|
||||
IF: wwan0
|
||||
MTU: 1500
|
||||
LogStore: /media/ci_qlogs
|
||||
|
||||
adb_ue_1:
|
||||
Host: nano
|
||||
InitScript: /home/oaicicd/ci_ctl_adb.sh initialize R3CM40LZPHT
|
||||
|
||||
@@ -58,7 +58,7 @@ import cls_oaicitest
|
||||
# Helper functions used here and in other classes
|
||||
# (e.g., cls_cluster.py)
|
||||
#-----------------------------------------------------------
|
||||
IMAGES = ['oai-enb', 'oai-lte-ru', 'oai-lte-ue', 'oai-gnb', 'oai-nr-cuup', 'oai-gnb-aw2s', 'oai-nr-ue', 'oai-gnb-asan', 'oai-nr-ue-asan', 'oai-nr-cuup-asan']
|
||||
IMAGES = ['oai-enb', 'oai-lte-ru', 'oai-lte-ue', 'oai-gnb', 'oai-nr-cuup', 'oai-gnb-aw2s', 'oai-nr-ue', 'oai-gnb-asan', 'oai-nr-ue-asan', 'oai-nr-cuup-asan', 'oai-gnb-aerial']
|
||||
|
||||
def CreateWorkspace(sshSession, sourcePath, ranRepository, ranCommitID, ranTargetBranch, ranAllowMerge):
|
||||
if ranCommitID == '':
|
||||
@@ -383,6 +383,7 @@ class Containerize():
|
||||
imageNames.append(('oai-physim', 'phySim', 'oai-physim', ''))
|
||||
if self.host == 'Ubuntu':
|
||||
imageNames.append(('oai-lte-ru', 'lteRU', 'oai-lte-ru', ''))
|
||||
imageNames.append(('oai-gnb-aerial', 'gNB.aerial', 'oai-gnb-aerial', ''))
|
||||
# Building again the 5G images with Address Sanitizer
|
||||
imageNames.append(('ran-build', 'build', 'ran-build-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
|
||||
imageNames.append(('oai-gnb', 'gNB', 'oai-gnb-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
|
||||
@@ -480,7 +481,11 @@ class Containerize():
|
||||
cmd.run(f'sed -i -e "s#ran-build:latest#ran-build-asan:{imageTag}#" docker/Dockerfile.{pattern}{self.dockerfileprefix}')
|
||||
elif image != 'ran-build':
|
||||
cmd.run(f'sed -i -e "s#ran-build:latest#ran-build:{imageTag}#" docker/Dockerfile.{pattern}{self.dockerfileprefix}')
|
||||
if image == 'oai-gnb-aerial':
|
||||
cmd.run('cp -f /opt/nvidia-ipc/nvipc_src.2023.11.28.tar.gz .')
|
||||
ret = cmd.run(f'{self.cli} build {self.cliBuildOptions} --target {image} --tag {name}:{imageTag} --file docker/Dockerfile.{pattern}{self.dockerfileprefix} {option} . > cmake_targets/log/{name}.log 2>&1', timeout=1200)
|
||||
if image == 'oai-gnb-aerial':
|
||||
cmd.run('rm -f nvipc_src.2023.11.28.tar.gz')
|
||||
if image == 'ran-build' and ret.returncode == 0:
|
||||
cmd.run(f"docker run --name test-log -d {name}:{imageTag} /bin/true")
|
||||
cmd.run(f"docker cp test-log:/oai-ran/cmake_targets/log/ cmake_targets/log/{name}/")
|
||||
@@ -959,7 +964,7 @@ class Containerize():
|
||||
|
||||
# Checking Status
|
||||
grep = ''
|
||||
if svcName != '': grep = f' | grep -A3 {svcName}'
|
||||
if svcName != '': grep = f' | grep -A3 --color=never {svcName}'
|
||||
mySSH.command(f'docker compose --file ci-docker-compose.yml config {grep}', '\$', 5)
|
||||
result = re.search('container_name: (?P<container_name>[a-zA-Z0-9\-\_]+)', mySSH.getBefore())
|
||||
unhealthyNb = 0
|
||||
@@ -1008,8 +1013,8 @@ class Containerize():
|
||||
if healthyNb == 1:
|
||||
cnt = 0
|
||||
while (cnt < 20):
|
||||
mySSH.command('docker logs ' + containerName + ' | egrep --text --color=never -i "wait|sync|Starting"', '\$', 30)
|
||||
result = re.search('got sync|Starting E1AP at CU UP|Starting F1AP at CU|Got sync|Waiting for RUs to be configured', mySSH.getBefore())
|
||||
mySSH.command('docker logs ' + containerName + ' | egrep --text --color=never -i "wait|sync|Starting|ready"', '\$', 30)
|
||||
result = re.search('got sync|Starting E1AP at CU UP|Starting F1AP at CU|Got sync|Waiting for RUs to be configured|Received CONFIG.response, gNB is ready', mySSH.getBefore())
|
||||
if result is None:
|
||||
time.sleep(6)
|
||||
cnt += 1
|
||||
@@ -1096,9 +1101,6 @@ class Containerize():
|
||||
filename = f'{svcName}-{HTML.testCase_id}.log'
|
||||
mySSH.run(f'docker compose -f {yamlDir}/ci-docker-compose.yml logs --no-log-prefix -- {svcName} &> {lSourcePath}/cmake_targets/log/{filename}')
|
||||
copyin_res = mySSH.copyin(f'{lSourcePath}/cmake_targets/log/{filename}', f'{filename}') and copyin_res
|
||||
# when nv-cubb container is available, copy L1 pcap, OAI Aerial pipeline
|
||||
if 'nv-cubb' in allServices:
|
||||
mySSH.run(f'cp {lSourcePath}/cmake_targets/share/gnb_nvipc.pcap {lSourcePath}/cmake_targets/gnb_nvipc.pcap')
|
||||
|
||||
mySSH.run(f'docker compose -f {yamlDir}/ci-docker-compose.yml down -v')
|
||||
|
||||
@@ -1119,14 +1121,15 @@ class Containerize():
|
||||
HTML.CreateHtmlTestRow('UE log Analysis', 'OK', CONST.ALL_PROCESSES_OK)
|
||||
else:
|
||||
for svcName in services:
|
||||
filename = f'{svcName}-{HTML.testCase_id}.log'
|
||||
logging.debug(f'\u001B[1m Analyzing logfile {filename}\u001B[0m')
|
||||
logStatus = RAN.AnalyzeLogFile_eNB(filename, HTML, self.ran_checkers)
|
||||
if (logStatus < 0):
|
||||
HTML.CreateHtmlTestRow(RAN.runtime_stats, 'KO', logStatus)
|
||||
self.exitStatus = 1
|
||||
else:
|
||||
HTML.CreateHtmlTestRow(RAN.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
|
||||
if svcName != 'nv-cubb':
|
||||
filename = f'{svcName}-{HTML.testCase_id}.log'
|
||||
logging.debug(f'\u001B[1m Analyzing logfile {filename}\u001B[0m')
|
||||
logStatus = RAN.AnalyzeLogFile_eNB(filename, HTML, self.ran_checkers)
|
||||
if (logStatus < 0):
|
||||
HTML.CreateHtmlTestRow(RAN.runtime_stats, 'KO', logStatus)
|
||||
self.exitStatus = 1
|
||||
else:
|
||||
HTML.CreateHtmlTestRow(RAN.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
|
||||
# all the xNB run logs shall be on the server 0 for logCollecting
|
||||
if self.eNB_serverId[self.eNB_instance] != '0':
|
||||
mySSH.copyout(f'./*.log', f'{lSourcePath}/cmake_targets/', recursive=True)
|
||||
|
||||
262
ci-scripts/conf_files/gnb-vnf.sa.band78.273prb.aerial.conf
Normal file
262
ci-scripts/conf_files/gnb-vnf.sa.band78.273prb.aerial.conf
Normal file
@@ -0,0 +1,262 @@
|
||||
Active_gNBs = ( "gNB-OAI");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
|
||||
sa = 1;
|
||||
nfapi = "AERIAL";
|
||||
|
||||
gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_ID = 0xe00;
|
||||
gNB_name = "gNB-OAI";
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1;
|
||||
plmn_list = ({
|
||||
mcc = 208;
|
||||
mnc = 97;
|
||||
mnc_length = 2;
|
||||
snssaiList = (
|
||||
{
|
||||
sst = 1;
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
nr_cellid = 12345678L;
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
pdsch_AntennaPorts_XP = 2;
|
||||
pusch_AntennaPorts = 2;
|
||||
do_CSIRS = 1;
|
||||
do_SRS = 0;
|
||||
min_rxtxtime = 2;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
controlResourceSetZero = 12;
|
||||
searchSpaceZero = 0;
|
||||
}
|
||||
);
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
|
||||
physCellId = 0;
|
||||
|
||||
# downlinkConfigCommon
|
||||
#frequencyInfoDL
|
||||
# this is 3300.24 + 134*12*30e3 = 3348.48 MHz (5G NR GSCN: 7741)
|
||||
absoluteFrequencySSB = 649920;
|
||||
#652860; #should be 649920
|
||||
#647520;
|
||||
#647540;
|
||||
#649920;
|
||||
#650208;
|
||||
#647540;
|
||||
dl_frequencyBand = 78;
|
||||
# this is 3300.24 MHz
|
||||
dl_absoluteFrequencyPointA = 646724;
|
||||
#649104;
|
||||
#646724;
|
||||
#scs-SpecificCarrierList
|
||||
dl_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
dl_subcarrierSpacing = 1;
|
||||
dl_carrierBandwidth = 273;
|
||||
#initialDownlinkBWP
|
||||
#genericParameters
|
||||
# this is RBstart=0,L=162 (275*(275-L+1))+(274-RBstart))
|
||||
initialDLBWPlocationAndBandwidth = 1099;
|
||||
#
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialDLBWPsubcarrierSpacing = 1;
|
||||
#pdcch-ConfigCommon
|
||||
initialDLBWPcontrolResourceSetZero = 12;
|
||||
initialDLBWPsearchSpaceZero = 0;
|
||||
|
||||
#uplinkConfigCommon
|
||||
#frequencyInfoUL
|
||||
ul_frequencyBand = 78;
|
||||
#scs-SpecificCarrierList
|
||||
ul_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
ul_subcarrierSpacing = 1;
|
||||
ul_carrierBandwidth = 273;
|
||||
pMax = 20;
|
||||
#initialUplinkBWP
|
||||
#genericParameters
|
||||
initialULBWPlocationAndBandwidth = 1099;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialULBWPsubcarrierSpacing = 1;
|
||||
#rach-ConfigCommon
|
||||
#rach-ConfigGeneric
|
||||
prach_ConfigurationIndex = 159;# testMAC 158; OAI gNB 98
|
||||
#prach_msg1_FDM
|
||||
#0 = one, 1=two, 2=four, 3=eight
|
||||
prach_msg1_FDM = 0;
|
||||
prach_msg1_FrequencyStart = 0;
|
||||
zeroCorrelationZoneConfig = 12;
|
||||
preambleReceivedTargetPower = -96;
|
||||
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
|
||||
preambleTransMax = 6;
|
||||
#powerRampingStep
|
||||
# 0=dB0,1=dB2,2=dB4,3=dB6
|
||||
powerRampingStep = 1;
|
||||
#ra_ReponseWindow
|
||||
#1,2,4,8,10,20,40,80
|
||||
ra_ResponseWindow = 5;
|
||||
#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 = 3;
|
||||
#oneHalf (0..15) 4,8,12,16,...60,64
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
|
||||
#ra_ContentionResolutionTimer
|
||||
#(0..7) 8,16,24,32,40,48,56,64
|
||||
ra_ContentionResolutionTimer = 7;
|
||||
rsrp_ThresholdSSB = 19;
|
||||
#prach-RootSequenceIndex_PR
|
||||
#1 = 839, 2 = 139
|
||||
prach_RootSequenceIndex_PR = 2;
|
||||
prach_RootSequenceIndex = 1;
|
||||
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
|
||||
#
|
||||
msg1_SubcarrierSpacing = 1,
|
||||
# restrictedSetConfig
|
||||
# 0=unrestricted, 1=restricted type A, 2=restricted type B
|
||||
restrictedSetConfig = 0,
|
||||
|
||||
msg3_DeltaPreamble = 1;
|
||||
p0_NominalWithGrant = -90;
|
||||
|
||||
# pucch-ConfigCommon setup :
|
||||
# pucchGroupHopping
|
||||
# 0 = neither, 1= group hopping, 2=sequence hopping
|
||||
pucchGroupHopping = 0;
|
||||
hoppingId = 40;
|
||||
p0_nominal = -90;
|
||||
# ssb_PositionsInBurs_BitmapPR
|
||||
# 1=short, 2=medium, 3=long
|
||||
ssb_PositionsInBurst_PR = 2;
|
||||
ssb_PositionsInBurst_Bitmap = 1;
|
||||
|
||||
# ssb_periodicityServingCell
|
||||
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
|
||||
ssb_periodicityServingCell = 2;
|
||||
|
||||
# dmrs_TypeA_position
|
||||
# 0 = pos2, 1 = pos3
|
||||
dmrs_TypeA_Position = 0;
|
||||
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
subcarrierSpacing = 1;
|
||||
|
||||
|
||||
#tdd-UL-DL-ConfigurationCommon
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
referenceSubcarrierSpacing = 1;
|
||||
# pattern1
|
||||
# dl_UL_TransmissionPeriodicity
|
||||
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
|
||||
dl_UL_TransmissionPeriodicity = 5; #6;
|
||||
nrofDownlinkSlots = 3; #7;
|
||||
nrofDownlinkSymbols = 6;
|
||||
nrofUplinkSlots = 1; #2;
|
||||
nrofUplinkSymbols = 0;
|
||||
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
|
||||
# ------- SCTP definitions
|
||||
SCTP :
|
||||
{
|
||||
# Number of streams to use in input/output
|
||||
SCTP_INSTREAMS = 2;
|
||||
SCTP_OUTSTREAMS = 2;
|
||||
};
|
||||
|
||||
|
||||
////////// AMF parameters:
|
||||
amf_ip_address = ( { ipv4 = "192.168.71.132";
|
||||
ipv6 = "192:168:30::17";
|
||||
active = "yes";
|
||||
preference = "ipv4";
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
GNB_INTERFACE_NAME_FOR_NG_AMF = "eno1";
|
||||
GNB_IPV4_ADDRESS_FOR_NG_AMF = "172.21.16.131";
|
||||
GNB_INTERFACE_NAME_FOR_NGU = "eno";
|
||||
GNB_IPV4_ADDRESS_FOR_NGU = "172.21.16.131";
|
||||
GNB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||
};
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
MACRLCs = (
|
||||
{
|
||||
num_cc = 1;
|
||||
local_s_if_name = "lo:";
|
||||
remote_s_address = "127.0.0.1"; // pnf addr [!]
|
||||
local_s_address = "127.0.0.2"; // vnf addr
|
||||
local_s_portc = 50001; // vnf p5 port
|
||||
remote_s_portc = 50000; // pnf p5 port [!]
|
||||
local_s_portd = 50011; // vnf p7 port [!]
|
||||
remote_s_portd = 50010; // pnf p7 port [!]
|
||||
tr_s_preference = "aerial";
|
||||
tr_n_preference = "local_RRC";
|
||||
pusch_TargetSNRx10 = 200; # 150;
|
||||
pucch_TargetSNRx10 = 200; #200;
|
||||
ulsch_max_frame_inactivity = 10;
|
||||
dl_max_mcs = 28;
|
||||
ul_max_mcs = 28;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
security = {
|
||||
# preferred ciphering algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nea0, nea1, nea2, nea3
|
||||
ciphering_algorithms = ( "nea0" );
|
||||
|
||||
# preferred integrity algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nia0, nia1, nia2, nia3
|
||||
integrity_algorithms = ( "nia2", "nia0" );
|
||||
|
||||
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
|
||||
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
|
||||
drb_ciphering = "yes";
|
||||
drb_integrity = "no";
|
||||
};
|
||||
|
||||
log_config :
|
||||
{
|
||||
global_log_level ="info";
|
||||
hw_log_level ="info";
|
||||
phy_log_level ="info";
|
||||
mac_log_level ="info";
|
||||
rlc_log_level ="info";
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
ngap_log_level ="debug";
|
||||
f1ap_log_level ="debug";
|
||||
};
|
||||
@@ -262,10 +262,12 @@ class EPCManagement():
|
||||
logging.debug('Starting OAI CN5G')
|
||||
mySSH.command('if [ -d ' + self.SourceCodePath + '/scripts ]; then echo ' + self.Password + ' | sudo -S rm -Rf ' + self.SourceCodePath + '/scripts ; fi', '\$', 5)
|
||||
mySSH.command('mkdir -p ' + self.SourceCodePath + '/scripts', '\$', 5)
|
||||
mySSH.command('cd /opt/oai-cn5g-fed-v1.5/docker-compose', '\$', 5)
|
||||
mySSH.command(f'cd {self.SourceCodePath}/docker-compose', '\$', 5)
|
||||
mySSH.command('python3 ./core-network.py '+self.cfgDeploy, '\$', 60)
|
||||
if re.search('start-mini-as-ue', self.cfgDeploy):
|
||||
dFile = 'docker-compose-mini-nrf-asue.yaml'
|
||||
elif re.search('basic', self.cfgDeploy):\
|
||||
dFile = 'docker-compose-basic-nrf.yaml'
|
||||
else:
|
||||
dFile = 'docker-compose-mini-nrf.yaml'
|
||||
mySSH.command('docker-compose -f ' + dFile + ' ps -a', '\$', 60)
|
||||
@@ -582,7 +584,7 @@ class EPCManagement():
|
||||
mySSH.command('docker logs ' + c + ' > ' + self.SourceCodePath + '/logs/' + c + '.log', '\$', 5)
|
||||
|
||||
logging.debug('Terminating OAI CN5G')
|
||||
mySSH.command('cd /opt/oai-cn5g-fed-v1.5/docker-compose', '\$', 5)
|
||||
mySSH.command(f'cd {self.SourceCodePath}/docker-compose', '\$', 5)
|
||||
mySSH.command('python3 ./core-network.py '+self.cfgUnDeploy, '\$', 60)
|
||||
mySSH.command('docker volume prune --force || true', '\$', 60)
|
||||
time.sleep(2)
|
||||
|
||||
139
ci-scripts/xml_files/container_sa_aerial_quectel.xml
Normal file
139
ci-scripts/xml_files/container_sa_aerial_quectel.xml
Normal file
@@ -0,0 +1,139 @@
|
||||
<!--
|
||||
|
||||
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-AERIAL-SA</htmlTabRef>
|
||||
<htmlTabName>AERIAL 100 MHz TDD SA</htmlTabName>
|
||||
<htmlTabIcon>tasks</htmlTabIcon>
|
||||
<repeatCount>1</repeatCount>
|
||||
<TestCaseRequestedList>
|
||||
111111
|
||||
000222
|
||||
001111
|
||||
002222
|
||||
002223
|
||||
000111
|
||||
100000
|
||||
000011
|
||||
000022
|
||||
000033
|
||||
000222
|
||||
003333
|
||||
222222
|
||||
</TestCaseRequestedList>
|
||||
<TestCaseExclusionList></TestCaseExclusionList>
|
||||
|
||||
<testCase id="111111">
|
||||
<class>Pull_Local_Registry</class>
|
||||
<desc>Pull Images from Local Registry</desc>
|
||||
<test_svr_id>0</test_svr_id>
|
||||
<images_to_pull>oai-gnb-aerial</images_to_pull>
|
||||
</testCase>
|
||||
|
||||
<testCase id="001111">
|
||||
<class>Initialize_UE</class>
|
||||
<desc>Initialize Quectel</desc>
|
||||
<id>sphex_quectel</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="002222">
|
||||
<class>Deploy_Object</class>
|
||||
<desc>Deploy PNF/Nvidia CUBB in a container</desc>
|
||||
<yaml_path>ci-scripts/yaml_files/sa_gnb_aerial</yaml_path>
|
||||
<services>nv-cubb</services>
|
||||
<eNB_instance>0</eNB_instance>
|
||||
<eNB_serverId>0</eNB_serverId>
|
||||
</testCase>
|
||||
|
||||
<testCase id="002223">
|
||||
<class>Deploy_Object</class>
|
||||
<desc>Deploy VNF in a container</desc>
|
||||
<yaml_path>ci-scripts/yaml_files/sa_gnb_aerial</yaml_path>
|
||||
<services>oai-gnb-aerial</services>
|
||||
<eNB_instance>0</eNB_instance>
|
||||
<eNB_serverId>0</eNB_serverId>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000111">
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach Quectel</desc>
|
||||
<id>sphex_quectel</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="100000">
|
||||
<class>Custom_Command</class>
|
||||
<desc>Adding a IP route</desc>
|
||||
<node>sphex</node>
|
||||
<command>sudo ip route add 192.168.71.128/26 via 12.1.1.151 dev wwan0</command>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000011">
|
||||
<class>Ping</class>
|
||||
<desc>Ping: 100pings in 20sec</desc>
|
||||
<id>sphex_quectel</id>
|
||||
<ping_args>-c 100 -i 0.2 %cn_ip%</ping_args>
|
||||
<ping_packetloss_threshold>5</ping_packetloss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000022">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (DL/UDP/80M)(30 sec)(single-ue profile)</desc>
|
||||
<iperf_args>-u -b 80M -t 30 -R</iperf_args>
|
||||
<direction>IPERF3</direction>
|
||||
<id>sphex_quectel</id>
|
||||
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
|
||||
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
|
||||
</testCase>
|
||||
|
||||
<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>
|
||||
<direction>IPERF3</direction>
|
||||
<id>sphex_quectel</id>
|
||||
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
|
||||
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000222">
|
||||
<class>Detach_UE</class>
|
||||
<desc>Detach Quectel</desc>
|
||||
<id>sphex_quectel</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="003333">
|
||||
<class>Terminate_UE</class>
|
||||
<desc>Terminate Quectel</desc>
|
||||
<id>sphex_quectel</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="222222">
|
||||
<class>Undeploy_Object</class>
|
||||
<desc>Undeploy gNB</desc>
|
||||
<yaml_path>ci-scripts/yaml_files/sa_gnb_aerial</yaml_path>
|
||||
<eNB_instance>0</eNB_instance>
|
||||
<eNB_serverId>0</eNB_serverId>
|
||||
<d_retx_th>20,100,100,100</d_retx_th>
|
||||
<u_retx_th>20,100,100,100</u_retx_th>
|
||||
</testCase>
|
||||
</testCaseList>
|
||||
|
||||
52
ci-scripts/xml_files/container_sa_aerial_quectel_cleanup.xml
Normal file
52
ci-scripts/xml_files/container_sa_aerial_quectel_cleanup.xml
Normal file
@@ -0,0 +1,52 @@
|
||||
<!--
|
||||
|
||||
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-aerial-cleanup</htmlTabRef>
|
||||
<htmlTabName>CleanUp AERIAL</htmlTabName>
|
||||
<htmlTabIcon>trash</htmlTabIcon>
|
||||
<TestCaseRequestedList>
|
||||
111111
|
||||
222222
|
||||
333333
|
||||
</TestCaseRequestedList>
|
||||
<TestCaseExclusionList></TestCaseExclusionList>
|
||||
|
||||
<testCase id="111111">
|
||||
<class>Clean_Test_Server_Images</class>
|
||||
<desc>Clean Test Images on Test Server</desc>
|
||||
<test_svr_id>0</test_svr_id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="222222">
|
||||
<class>Detach_UE</class>
|
||||
<desc>Terminate UE</desc>
|
||||
<id>sphex_quectel</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="333333">
|
||||
<class>Terminate_UE</class>
|
||||
<desc>Terminate UE</desc>
|
||||
<id>sphex_quectel</id>
|
||||
</testCase>
|
||||
|
||||
</testCaseList>
|
||||
45
ci-scripts/xml_files/fr1_cn5g_basic_deploy.xml
Normal file
45
ci-scripts/xml_files/fr1_cn5g_basic_deploy.xml
Normal file
@@ -0,0 +1,45 @@
|
||||
<!--
|
||||
|
||||
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>cn5g-start-tab</htmlTabRef>
|
||||
<htmlTabName>CN5G-Start</htmlTabName>
|
||||
<htmlTabIcon>log-in</htmlTabIcon>
|
||||
<TestCaseRequestedList>
|
||||
000100
|
||||
000200
|
||||
</TestCaseRequestedList>
|
||||
<TestCaseExclusionList>
|
||||
</TestCaseExclusionList>
|
||||
|
||||
<testCase id="000100">
|
||||
<class>Terminate_5GCN</class>
|
||||
<desc>Terminate 5G Core</desc>
|
||||
<args>--type stop-basic</args>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000200">
|
||||
<class>Initialize_5GCN</class>
|
||||
<desc>Initialize 5G Core</desc>
|
||||
<args>--type start-basic</args>
|
||||
</testCase>
|
||||
</testCaseList>
|
||||
39
ci-scripts/xml_files/fr1_cn5g_basic_undeploy.xml
Normal file
39
ci-scripts/xml_files/fr1_cn5g_basic_undeploy.xml
Normal file
@@ -0,0 +1,39 @@
|
||||
<!--
|
||||
|
||||
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>cn5g-start-tab</htmlTabRef>
|
||||
<htmlTabName>CN5G-Start</htmlTabName>
|
||||
<htmlTabIcon>log-in</htmlTabIcon>
|
||||
<TestCaseRequestedList>
|
||||
000300
|
||||
</TestCaseRequestedList>
|
||||
<TestCaseExclusionList>
|
||||
</TestCaseExclusionList>
|
||||
|
||||
<testCase id="000300">
|
||||
<class>Terminate_5GCN</class>
|
||||
<desc>Terminate 5G Core</desc>
|
||||
<args>--type stop-basic</args>
|
||||
</testCase>
|
||||
</testCaseList>
|
||||
|
||||
46
ci-scripts/yaml_files/sa_gnb_aerial/aerial_l1_entrypoint.sh
Executable file
46
ci-scripts/yaml_files/sa_gnb_aerial/aerial_l1_entrypoint.sh
Executable file
@@ -0,0 +1,46 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check if cuBB_SDK is defined, if not, use default path
|
||||
cuBB_Path="${cuBB_SDK:-/opt/nvidia/cuBB}"
|
||||
|
||||
# Run gdrcopy insmod
|
||||
cd "$cuBB_Path"/cuPHY-CP/external/gdrcopy/ || exit 1
|
||||
|
||||
./insmod.sh
|
||||
cd "$cuBB_Path" || exit 1
|
||||
# Add gdrcopy to LD_LIBRARY_PATH
|
||||
export LD_LIBRARY_PATH=/usr/local/nvidia/lib:/usr/local/nvidia/lib64:/opt/mellanox/dpdk/lib/x86_64-linux-gnu:/opt/mellanox/doca/lib/x86_64-linux-gnu:/opt/nvidia/cuBB/cuPHY-CP/external/gdrcopy/build/x86_64/
|
||||
|
||||
# Restart MPS
|
||||
# Export variables
|
||||
export CUDA_DEVICE_MAX_CONNECTIONS=8
|
||||
export CUDA_MPS_PIPE_DIRECTORY=/var
|
||||
export CUDA_MPS_LOG_DIRECTORY=/var
|
||||
|
||||
# Stop existing MPS
|
||||
echo quit | nvidia-cuda-mps-control
|
||||
|
||||
# Start MPS
|
||||
nvidia-cuda-mps-control -d
|
||||
echo start_server -uid 0 | nvidia-cuda-mps-control
|
||||
|
||||
# Start cuphycontroller_scf
|
||||
# Check if an argument is provided
|
||||
if [ $# -eq 0 ]; then
|
||||
# No argument provided, use default value
|
||||
argument="P5G_SCF_FXN"
|
||||
else
|
||||
# Argument provided, use it
|
||||
argument="$1"
|
||||
fi
|
||||
|
||||
export NVIPC_DEBUG_EN=2
|
||||
|
||||
"$cuBB_Path"/build/cuPHY-CP/cuphycontroller/examples/cuphycontroller_scf "$argument"
|
||||
#Collect pcap
|
||||
"$cuBB_Path"/build/cuPHY-CP/gt_common_libs/nvIPC/tests/pcap/pcap_collect
|
||||
|
||||
cp -f nvipc.pcap /opt/cuBB/share
|
||||
cp -f /tmp/phy.log /opt/cuBB/share
|
||||
chmod 666 /opt/cuBB/share/nvipc.pcap
|
||||
chmod 666 /opt/cuBB/share/phy.log
|
||||
65
ci-scripts/yaml_files/sa_gnb_aerial/docker-compose.yaml
Normal file
65
ci-scripts/yaml_files/sa_gnb_aerial/docker-compose.yaml
Normal file
@@ -0,0 +1,65 @@
|
||||
version: "3.8"
|
||||
services:
|
||||
nv-cubb:
|
||||
container_name: nv-cubb
|
||||
deploy:
|
||||
resources:
|
||||
reservations:
|
||||
devices:
|
||||
- driver: nvidia
|
||||
count: all
|
||||
capabilities:
|
||||
- gpu
|
||||
network_mode: host
|
||||
shm_size: 4096m
|
||||
privileged: true
|
||||
stdin_open: true
|
||||
tty: true
|
||||
volumes:
|
||||
- /lib/modules:/lib/modules
|
||||
- /dev/hugepages:/dev/hugepages
|
||||
- /usr/src:/usr/src
|
||||
- ./aerial_l1_entrypoint.sh:/opt/nvidia/cuBB/aerial_l1_entrypoint.sh
|
||||
- /var/log/aerial:/var/log/aerial
|
||||
- /tmp/share:/opt/cuBB/share
|
||||
userns_mode: host
|
||||
ipc: "shareable"
|
||||
image: cubb-build:23-2
|
||||
environment:
|
||||
- cuBB_SDK=/opt/nvidia/cuBB
|
||||
command: bash -c " rm -rf /tmp/phy.log && chmod +x /opt/nvidia/cuBB/aerial_l1_entrypoint.sh && /opt/nvidia/cuBB/aerial_l1_entrypoint.sh"
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL",'grep -q "L1 is ready!" /tmp/phy.log && echo 0 || echo 1']
|
||||
interval: 20s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
oai-gnb-aerial:
|
||||
cpuset: "13-20"
|
||||
image: oai-gnb-aerial:latest
|
||||
depends_on:
|
||||
nv-cubb:
|
||||
condition: service_healthy
|
||||
privileged: true
|
||||
ipc: "container:nv-cubb"
|
||||
environment:
|
||||
USE_ADDITIONAL_OPTIONS: --log_config.global_log_options level,nocolor,time
|
||||
deploy:
|
||||
resources:
|
||||
reservations:
|
||||
devices:
|
||||
- driver: nvidia
|
||||
count: all
|
||||
capabilities:
|
||||
- gpu
|
||||
network_mode: host
|
||||
shm_size: 4096m
|
||||
stdin_open: true
|
||||
tty: true
|
||||
volumes:
|
||||
- ../../conf_files/gnb-vnf.sa.band78.273prb.aerial.conf:/opt/oai-gnb/etc/gnb.conf
|
||||
container_name: oai-gnb-aerial
|
||||
healthcheck:
|
||||
test: /bin/bash -c "ps aux | grep -v grep | grep -c softmodem"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
@@ -93,7 +93,7 @@ Options:
|
||||
--UE-gen-nvram [output path]
|
||||
Specify gen_nvram_path (default \"$gen_nvram_path\")
|
||||
-w | --hardware
|
||||
USRP, BLADERF, LMSSDR, IRIS, SIMU, AW2SORI, None (Default)
|
||||
USRP, BLADERF, LMSSDR, IRIS, SIMU, AW2SORI, AERIAL, None (Default)
|
||||
Adds this RF board support (in external packages installation and in compilation)
|
||||
-t | --transport
|
||||
Selects the transport protocol type, options: None, Ethernet, benetel4g, benetel5g, oran_fhlib_5g
|
||||
@@ -289,6 +289,10 @@ function main() {
|
||||
TARGET_LIST="$TARGET_LIST aw2sori_transpro"
|
||||
CMAKE_CMD="$CMAKE_CMD -DOAI_$2=ON"
|
||||
;;
|
||||
"AERIAL"|"Aerial"|"aerial")
|
||||
HW="OAI_AERIAL"
|
||||
CMAKE_CMD="$CMAKE_CMD -DOAI_AERIAL=ON"
|
||||
;;
|
||||
"None")
|
||||
;;
|
||||
*)
|
||||
|
||||
76
cmake_targets/tools/install_libraries_to_system.patch
Normal file
76
cmake_targets/tools/install_libraries_to_system.patch
Normal file
@@ -0,0 +1,76 @@
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 04cfa53..6eef6d6 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -42,6 +42,8 @@ OPTION(DOCA_GPU_DPDK "Enable DOCA GPUNetIO" ON)
|
||||
OPTION(NVIPC_DOCA_ENABLE "Build libnvipc.so with DOCA" ON)
|
||||
OPTION(NVIPC_DOCA_GPUNETIO "Use DOCA gpunetio in DOCA GPU DMA" OFF)
|
||||
|
||||
+project(gt_common_libs)
|
||||
+
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
# Disable NVIPC_DOCA_ENABLE if DOCA version < 2
|
||||
diff --git a/nvIPC/CMakeLists.txt b/nvIPC/CMakeLists.txt
|
||||
index 633bbb7..dad7a7a 100644
|
||||
--- a/nvIPC/CMakeLists.txt
|
||||
+++ b/nvIPC/CMakeLists.txt
|
||||
@@ -19,7 +19,7 @@
|
||||
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-
|
||||
+include(GNUInstallDirs)
|
||||
# lib: nvipc
|
||||
set(SOURCES configs/nv_ipc_config.c
|
||||
configs/nv_ipc_yaml_parser.cpp
|
||||
@@ -68,6 +68,8 @@ target_include_directories(nvipc PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE
|
||||
target_include_directories(nvipc PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/cuda>)
|
||||
target_include_directories(nvipc PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/gpudata>)
|
||||
|
||||
+set_target_properties(nvipc PROPERTIES PUBLIC_HEADER $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
|
||||
+
|
||||
target_compile_options(nvipc PRIVATE ${AERIAL_ARCH_TUNE_FLAGS})
|
||||
|
||||
if(NVIPC_DPDK_ENABLE OR NVIPC_DOCA_GPUNETIO)
|
||||
@@ -120,4 +122,8 @@ else()
|
||||
target_link_libraries(nvipc PUBLIC rt -pthread nvlog)
|
||||
endif()
|
||||
|
||||
+install(TARGETS nvipc
|
||||
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
+ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/..)
|
||||
+
|
||||
add_subdirectory(tests)
|
||||
diff --git a/nvlog/CMakeLists.txt b/nvlog/CMakeLists.txt
|
||||
index 7b65242..c0c5080 100644
|
||||
--- a/nvlog/CMakeLists.txt
|
||||
+++ b/nvlog/CMakeLists.txt
|
||||
@@ -20,6 +20,8 @@
|
||||
# STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
+include(GNUInstallDirs)
|
||||
+
|
||||
if(NOT CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g")
|
||||
@@ -42,6 +44,8 @@ target_include_directories(nvlog PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../extern
|
||||
target_include_directories(nvlog PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../external/fmtlog_flat)
|
||||
target_link_libraries(nvlog rt -pthread yaml fmtlog-shared fmt::fmt)
|
||||
|
||||
+set_target_properties(nvlog PROPERTIES PUBLIC_HEADER $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
|
||||
+
|
||||
######## libnvlog_static.a #############
|
||||
add_library(nvlog_static STATIC ${SOURCES})
|
||||
set_property(TARGET nvlog_static PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
@@ -68,5 +72,9 @@ target_compile_options(nvlog_static PRIVATE ${AERIAL_ARCH_TUNE_FLAGS})
|
||||
#add_executable(nvlog_observer ${SOURCES})
|
||||
#target_link_libraries(nvlog_observer nvlog_static -pthread)
|
||||
|
||||
+install(TARGETS nvlog
|
||||
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
+ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/../)
|
||||
+
|
||||
######## test directory ################
|
||||
add_subdirectory(test)
|
||||
266
doc/Aerial_FAPI_Split_Tutorial.md
Normal file
266
doc/Aerial_FAPI_Split_Tutorial.md
Normal file
@@ -0,0 +1,266 @@
|
||||
<table style="border-collapse: collapse; border: none;">
|
||||
<tr style="border-collapse: collapse; border: none;">
|
||||
<td style="border-collapse: collapse; border: none;">
|
||||
<a href="http://www.openairinterface.org/">
|
||||
<img src="./images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
</img>
|
||||
</a>
|
||||
</td>
|
||||
<td style="border-collapse: collapse; border: none; vertical-align: center;">
|
||||
<b><font size = "5">OAI 7.2 Fronthaul Interface 5G SA Tutorial</font></b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
[[_TOC_]]
|
||||
|
||||
# Prerequisites
|
||||
|
||||
The hardware on which we have tried this tutorial:
|
||||
|
||||
| Hardware (CPU,RAM) |Operating System (kernel) | NIC (Vendor,Driver,Firmware) |
|
||||
|----------------------------------------------------------------------------|----------------------------------|--------------------------------------------------|
|
||||
| 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) |
|
||||
|
||||
**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:
|
||||
|
||||
| Vendor | Software Version |
|
||||
|--------------------------|------------------|
|
||||
| Fibrolan Falcon-RX/812/G | 8.0.25.4 |
|
||||
| CISCO C93180YC-FX3 | 10.2(4) |
|
||||
| Qulsar Qg2 (Grandmaster) | 12.1.27 |
|
||||
|
||||
|
||||
These are the radio units we've used for testing:
|
||||
|
||||
| Vendor | Software Version |
|
||||
|-------------|------------------|
|
||||
| Foxconn RPQN-7801E RU | 2.6.9r254 |
|
||||
| Foxconn RPQN-7801E RU | 3.1.15_0p4 |
|
||||
|
||||
|
||||
The UEs that have been tested and confirmed working with Aerial are the following:
|
||||
|
||||
| Vendor | Model |
|
||||
|-----------------|-------------------------------|
|
||||
| Sierra Wireless | EM9191 |
|
||||
| Quectel | RM500Q-GL |
|
||||
| Apaltec | Tributo 5G-Dongle |
|
||||
| OnePlus | Nord (AC2003) |
|
||||
| Apple iPhone | 14 Pro (MQ0G3RX/A) (iOS 17.3) |
|
||||
|
||||
|
||||
## Configure your server
|
||||
|
||||
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-research-cloud/current/index.html) to setup the L1 components using NVIDIAs' SDK manager, or to [this instructions page](https://developer.nvidia.com/docs/gputelecom/aerial-sdk/aerial-sdk-archive/aerial-sdk-23-2/index.html) in order to setup and install the components manually.
|
||||
|
||||
The currently used Aerial Version is 23-2, which is also the one currently used by the SDK Manager.
|
||||
|
||||
|
||||
### CPU allocation
|
||||
|
||||
Currently, the CPU isolation is setup the following:
|
||||
|
||||
| Server brand | Model | Nº of CPU Cores | Isolated CPUs |
|
||||
|--------------|-----------|:---------------:|:--------------:|
|
||||
| Gigabyte | Edge E251-U70 | 24 | 2-10 |
|
||||
|
||||
|
||||
**Gigabyte Edge E251-U70**
|
||||
|
||||
| Applicative Threads | Allocated CPUs |
|
||||
|------------------------|----------------|
|
||||
| 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.
|
||||
|
||||
```bash
|
||||
#Ubuntu
|
||||
sudo apt install linuxptp -y
|
||||
```
|
||||
|
||||
Once installed you can use this configuration file for ptp4l (`/etc/ptp4l.conf`). Here the clock domain is 24 so you can adjust it according to your PTP GM clock domain
|
||||
|
||||
```
|
||||
[global]
|
||||
domainNumber 24
|
||||
slaveOnly 1
|
||||
time_stamping hardware
|
||||
tx_timestamp_timeout 1
|
||||
logging_level 6
|
||||
summary_interval 0
|
||||
#priority1 127
|
||||
|
||||
[your_PTP_ENABLED_NIC]
|
||||
network_transport L2
|
||||
hybrid_e2e 0
|
||||
|
||||
```
|
||||
|
||||
The service of ptp4l (`/lib/systemd/system/ptp4l.service`) should be configured as below:
|
||||
```
|
||||
[Unit]
|
||||
Description=Precision Time Protocol (PTP) service
|
||||
Documentation=man:ptp4l
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
RestartSec=5s
|
||||
Type=simple
|
||||
ExecStart=taskset -c 9 /usr/sbin/ptp4l -f /etc/ptp.conf
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
```
|
||||
|
||||
and service of phc2sys (`/lib/systemd/system/phc2sys.service`) should be configured as below:
|
||||
```
|
||||
[Unit]
|
||||
Description=Synchronize system clock or PTP hardware clock (PHC)
|
||||
Documentation=man:phc2sys
|
||||
After=ntpdate.service
|
||||
Requires=ptp4l.service
|
||||
After=ptp4l.service
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
RestartSec=5s
|
||||
Type=simple
|
||||
ExecStart=/usr/sbin/phc2sys -a -r -r -n 24
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
```
|
||||
|
||||
# Build OAI gNB
|
||||
|
||||
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/
|
||||
git checkout Aerial_Integration
|
||||
```
|
||||
|
||||
## Get nvIPC sources from the L1 container
|
||||
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:
|
||||
```bash
|
||||
~$ docker container ls -a
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
a9681a0c4a10 14dca2002237 "/opt/nvidia/nvidia_…" 3 months ago Exited (137) 10 days ago cuBB
|
||||
|
||||
```
|
||||
If it is not running, you may start it and logging into the container by running the following:
|
||||
```bash
|
||||
~$ docker start cuBB
|
||||
cuBB
|
||||
~$ docker exec -it cuBB bash
|
||||
root@c_aerial_aerial:/opt/nvidia/cuBB#
|
||||
```
|
||||
|
||||
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
|
||||
root@c_aerial_aerial:/opt/nvidia/cuBB# cd cuPHY-CP/gt_common_libs
|
||||
root@c_aerial_aerial:/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs#./pack_nvipc.sh
|
||||
nvipc_src.****.**.**/
|
||||
...
|
||||
---------------------------------------------
|
||||
Pack nvipc source code finished:
|
||||
/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs/nvipc_src.****.**.**.tar.gz
|
||||
root@c_aerial_aerial:/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs# cp nvipc_src.****.**.**.tar.gz /opt/cuBB/share/
|
||||
root@c_aerial_aerial:/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs# exit
|
||||
```
|
||||
|
||||
The file should now be present in the `~/openairinterface5g/ci-scripts/yaml_files/sa_gnb_aerial/` directory, from where it is moved into `~/openairinterface5g`
|
||||
```bash
|
||||
~$ mv ~/openairinterface5g/ci-scripts/yaml_files/sa_gnb_aerial/nvipc_src.****.**.**.tar.gz ~/openairinterface5g/
|
||||
```
|
||||
With the nvIPC sources in the project directory, the docker image can be built.
|
||||
|
||||
## Building OAI gNB docker image
|
||||
|
||||
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.ubuntu20 --tag ran-base:latest
|
||||
~/openairinterface5g$ docker build . -f docker/Dockerfile.gNB.aerial.ubuntu20 --tag oai-gnb-aerial:latest
|
||||
```
|
||||
|
||||
|
||||
## 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.
|
||||
|
||||
### 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:
|
||||
```bash
|
||||
~$ docker commit nv-cubb cubb-build:23-2
|
||||
~$ docker image ls
|
||||
..
|
||||
cubb-build 23-2 824156e0334c 2 weeks ago 40.1GB
|
||||
..
|
||||
```
|
||||
|
||||
## Adapt the OAI-gNB configuration file to your system/workspace
|
||||
|
||||
Edit the sample OAI gNB configuration file and check following parameters:
|
||||
|
||||
* `gNBs` section
|
||||
* The PLMN section shall match the one defined in the AMF
|
||||
* `amf_ip_address` shall be the correct AMF IP address in your system
|
||||
* `GNB_INTERFACE_NAME_FOR_NG_AMF` and `GNB_IPV4_ADDRESS_FOR_NG_AMF` shall match your DU N2 interface name and IP address
|
||||
* `GNB_INTERFACE_NAME_FOR_NGU` and `GNB_IPV4_ADDRESS_FOR_NGU` shall match your DU N3 interface name and IP address
|
||||
|
||||
The default amf_ip_address:ipv4 value is 192.168.70.132, when installing the CN5G following [this tutorial](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop/doc/NR_SA_Tutorial_OAI_CN5G.md)
|
||||
Both 'GNB_INTERFACE_NAME_FOR_NG_AMF' and 'GNB_INTERFACE_NAME_FOR_NGU' need to be set to the network interface name used by the gNB host to connect to the CN5G.
|
||||
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
|
||||
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, this begins by installing a module 'gdrcopy', setting up some environment variables, restarting NVIDIA MPS, and finally running cuphycontroller with an argument that represent which L1 configuration file is to be used, this argument may be changed by providing an argument in docker-compose.yaml.
|
||||
When no argument is provided (this is the default behaviour), it uses "P5G_SCF_FXN" as a cuphycontroller_scf argument.
|
||||
|
||||
After building the gNB image, and preparing the configuration file, the setup can be run with the following command:
|
||||
|
||||
```bash
|
||||
cd ci-scripts/yaml_files/sa_gnb_aerial/
|
||||
docker compose up -d
|
||||
|
||||
```
|
||||
This will start both containers, beginning with 'nv-cubb' and only after it being ready it starts 'oai-gnb-aerial'.
|
||||
|
||||
The gNB logs can be followed with:
|
||||
|
||||
```bash
|
||||
docker logs -f oai-gnb-aerial
|
||||
```
|
||||
|
||||
### Stopping the setup
|
||||
|
||||
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
|
||||
|
||||
```
|
||||
103
docker/Dockerfile.gNB.aerial.ubuntu20
Normal file
103
docker/Dockerfile.gNB.aerial.ubuntu20
Normal file
@@ -0,0 +1,103 @@
|
||||
#/*
|
||||
# * 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 BUILD service
|
||||
# Valid for Ubuntu 22.04
|
||||
#
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
FROM ran-base:latest as ran-build
|
||||
|
||||
RUN apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install --yes \
|
||||
wget \
|
||||
ninja-build \
|
||||
#unzip is needed for protobuf
|
||||
unzip \
|
||||
moreutils \
|
||||
vim-tiny \
|
||||
nano \
|
||||
# To build libnvipc
|
||||
cmake libpcap-dev libcunit1-dev libnuma-dev pkg-config
|
||||
|
||||
RUN rm -Rf /oai-ran
|
||||
WORKDIR /oai-ran
|
||||
COPY . .
|
||||
|
||||
RUN /bin/sh oaienv && \
|
||||
tar -xvzf nvipc_src.*.tar.gz && \
|
||||
cd nvipc_src.* && \
|
||||
git init && \
|
||||
git apply ../cmake_targets/tools/install_libraries_to_system.patch --verbose && \
|
||||
rm -rf build && mkdir build && cd build && \
|
||||
cmake .. -DNVIPC_DPDK_ENABLE=OFF -DNVIPC_DOCA_ENABLE=OFF -DNVIPC_CUDA_ENABLE=OFF -DENABLE_SLT_RSP=ON && \
|
||||
make -j && make install
|
||||
|
||||
RUN /bin/sh oaienv && \
|
||||
cd cmake_targets && \
|
||||
mkdir -p log && \
|
||||
./build_oai -w AERIAL --gNB --ninja
|
||||
|
||||
|
||||
#start from scratch for target executable
|
||||
FROM ubuntu:focal as oai-gnb-aerial
|
||||
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 \
|
||||
software-properties-common \
|
||||
procps \
|
||||
libsctp1 \
|
||||
tzdata \
|
||||
libatlas3-base \
|
||||
libconfig9 \
|
||||
openssl \
|
||||
net-tools \
|
||||
iperf \
|
||||
iproute2 \
|
||||
iputils-ping \
|
||||
gdb \
|
||||
libusb-1.0-0 && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /opt/oai-gnb/bin
|
||||
COPY --from=ran-build \
|
||||
/oai-ran/cmake_targets/ran_build/build/nr-softmodem ./
|
||||
COPY ./docker/scripts/gnb_entrypoint.sh ./entrypoint.sh
|
||||
|
||||
COPY --from=ran-build /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so /usr/local/lib/
|
||||
|
||||
#copy files from nvIPC
|
||||
COPY --from=ran-build \
|
||||
/usr/local/lib/libfmtlog-shared.so \
|
||||
/usr/local/lib/libnvlog.so \
|
||||
/usr/local/lib/libnvipc.so \
|
||||
/usr/local/lib/
|
||||
|
||||
|
||||
WORKDIR /opt/oai-gnb
|
||||
COPY --from=ran-build /tini /tini
|
||||
ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"]
|
||||
CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"]
|
||||
109
docker/Dockerfile.gNB.aerial.ubuntu20.sanitize-address
Normal file
109
docker/Dockerfile.gNB.aerial.ubuntu20.sanitize-address
Normal file
@@ -0,0 +1,109 @@
|
||||
#/*
|
||||
# * 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 BUILD service
|
||||
# Valid for Ubuntu 22.04
|
||||
#
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
FROM ran-base:latest as ran-build
|
||||
|
||||
RUN apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install --yes \
|
||||
wget \
|
||||
ninja-build \
|
||||
#unzip is needed for protobuf
|
||||
unzip \
|
||||
moreutils \
|
||||
vim-tiny \
|
||||
nano \
|
||||
# To build libnvipc
|
||||
cmake libpcap-dev libcunit1-dev libnuma-dev pkg-config
|
||||
|
||||
RUN rm -Rf /oai-ran
|
||||
WORKDIR /oai-ran
|
||||
COPY . .
|
||||
|
||||
RUN /bin/sh oaienv && \
|
||||
tar -xvzf nvipc_src.*.tar.gz && \
|
||||
cd nvipc_src.* && \
|
||||
git init && \
|
||||
git apply ../cmake_targets/tools/install_libraries_to_system.patch --verbose && \
|
||||
rm -rf build && mkdir build && cd build && \
|
||||
cmake .. -DNVIPC_DPDK_ENABLE=OFF -DNVIPC_DOCA_ENABLE=OFF -DNVIPC_CUDA_ENABLE=OFF -DENABLE_SLT_RSP=ON && \
|
||||
make -j && make install
|
||||
|
||||
RUN /bin/sh oaienv && \
|
||||
cd cmake_targets && \
|
||||
mkdir -p log && \
|
||||
./build_oai -w AERIAL --gNB --ninja --sanitize-address
|
||||
|
||||
|
||||
#start from scratch for target executable
|
||||
FROM ubuntu:focal as oai-gnb-aerial
|
||||
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 \
|
||||
software-properties-common \
|
||||
procps \
|
||||
libsctp1 \
|
||||
tzdata \
|
||||
libatlas3-base \
|
||||
libconfig9 \
|
||||
openssl \
|
||||
net-tools \
|
||||
iperf \
|
||||
iproute2 \
|
||||
iputils-ping \
|
||||
gdb \
|
||||
libusb-1.0-0 && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /opt/oai-gnb/bin
|
||||
COPY --from=ran-build \
|
||||
/oai-ran/cmake_targets/ran_build/build/nr-softmodem ./
|
||||
COPY ./docker/scripts/gnb_entrypoint.sh ./entrypoint.sh
|
||||
|
||||
COPY --from=ran-build \
|
||||
/oai-ran/cmake_targets/ran_build/build/libcoding.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/librfsimulator.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libdfts.so \
|
||||
/oai-ran/cmake_targets/ran_build/build/libldpc*.so \
|
||||
/usr/local/lib/
|
||||
|
||||
#copy files from nvIPC
|
||||
COPY --from=ran-build \
|
||||
/usr/local/lib/libfmtlog-shared.so \
|
||||
/usr/local/lib/libnvlog.so \
|
||||
/usr/local/lib/libnvipc.so \
|
||||
/usr/local/lib/
|
||||
|
||||
|
||||
WORKDIR /opt/oai-gnb
|
||||
COPY --from=ran-build /tini /tini
|
||||
ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"]
|
||||
CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"]
|
||||
@@ -394,7 +394,7 @@ void init_gNB_Tpool(int inst) {
|
||||
// this will be removed when the msgDataTx is not necessary anymore
|
||||
gNB->msgDataTx = msgDataTx;
|
||||
|
||||
if ((!get_softmodem_params()->emulate_l1) && (!IS_SOFTMODEM_NOSTATS_BIT) && (NFAPI_MODE!=NFAPI_MODE_VNF))
|
||||
if ((!get_softmodem_params()->emulate_l1) && (!IS_SOFTMODEM_NOSTATS_BIT) && (NFAPI_MODE!=NFAPI_MODE_VNF) && (NFAPI_MODE != NFAPI_MODE_AERIAL))
|
||||
threadCreate(&proc->L1_stats_thread,nrL1_stats_thread,(void*)gNB,"L1_stats",-1,OAI_PRIORITY_RT_LOW);
|
||||
|
||||
}
|
||||
|
||||
@@ -1285,7 +1285,7 @@ void *ru_thread( void *param ) {
|
||||
|
||||
while (!oai_exit) {
|
||||
|
||||
if (NFAPI_MODE==NFAPI_MODE_VNF) {
|
||||
if (NFAPI_MODE==NFAPI_MODE_VNF || NFAPI_MODE == NFAPI_MODE_AERIAL ) {
|
||||
// We should make a VNF main loop with proper tasks calls in case of VNF
|
||||
slot_start = timespec_add(slot_start,slot_duration);
|
||||
struct timespec curr_time;
|
||||
|
||||
@@ -80,7 +80,9 @@ unsigned short config_frames[4] = {2,9,11,13};
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
#include "gnb_config.h"
|
||||
#include "openair2/E1AP/e1ap_common.h"
|
||||
|
||||
#ifdef ENABLE_AERIAL
|
||||
#include "nfapi/oai_integration/aerial/fapi_nvIPC.h"
|
||||
#endif
|
||||
#ifdef E2_AGENT
|
||||
#include "openair2/E2AP/flexric/src/agent/e2_agent_api.h"
|
||||
#include "openair2/E2AP/RAN_FUNCTION/init_ran_func.h"
|
||||
@@ -286,9 +288,15 @@ static int create_gNB_tasks(ngran_node_t node_type, configmodule_interface_t *cf
|
||||
itti_wait_ready(1);
|
||||
LOG_I(PHY, "%s() Task ready initialize structures\n", __FUNCTION__);
|
||||
|
||||
#ifdef ENABLE_AERIAL
|
||||
AssertFatal(NFAPI_MODE == NFAPI_MODE_AERIAL,"Can only be run with '--nfapi AERIAL' when compiled with AERIAL support, if you want to run other (n)FAPI modes, please run ./build_oai without -w AERIAL");
|
||||
#endif
|
||||
|
||||
RCconfig_verify(cfg, node_type);
|
||||
|
||||
RCconfig_nr_prs();
|
||||
if(NFAPI_MODE != NFAPI_MODE_AERIAL){
|
||||
RCconfig_nr_prs();
|
||||
}
|
||||
|
||||
if (RC.nb_nr_macrlc_inst > 0)
|
||||
RCconfig_nr_macrlc(cfg);
|
||||
@@ -687,7 +695,7 @@ int main( int argc, char **argv ) {
|
||||
pthread_mutex_init(&sync_mutex, NULL);
|
||||
usleep(1000);
|
||||
|
||||
if (NFAPI_MODE) {
|
||||
if (NFAPI_MODE && NFAPI_MODE != NFAPI_MODE_AERIAL) {
|
||||
printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n");
|
||||
pthread_cond_init(&sync_cond,NULL);
|
||||
pthread_mutex_init(&sync_mutex, NULL);
|
||||
@@ -706,7 +714,7 @@ int main( int argc, char **argv ) {
|
||||
printf("wait_gNBs()\n");
|
||||
wait_gNBs();
|
||||
printf("About to Init RU threads RC.nb_RU:%d\n", RC.nb_RU);
|
||||
int sl_ahead=6;
|
||||
int sl_ahead = NFAPI_MODE == NFAPI_MODE_AERIAL ? 0 : 6;
|
||||
if (RC.nb_RU >0) {
|
||||
printf("Initializing RU threads\n");
|
||||
init_NR_RU(uniqCfg, get_softmodem_params()->rf_config_file);
|
||||
@@ -749,7 +757,9 @@ int main( int argc, char **argv ) {
|
||||
|
||||
if (RC.nb_RU > 0)
|
||||
start_NR_RU();
|
||||
|
||||
#ifdef ENABLE_AERIAL
|
||||
nvIPC_Init();
|
||||
#endif
|
||||
if (RC.nb_nr_L1_inst > 0) {
|
||||
printf("wait RUs\n");
|
||||
wait_RUs();
|
||||
@@ -778,7 +788,7 @@ int main( int argc, char **argv ) {
|
||||
load_softscope("nrqt", &p);
|
||||
}
|
||||
|
||||
if (NFAPI_MODE != NFAPI_MODE_PNF && NFAPI_MODE != NFAPI_MODE_VNF) {
|
||||
if (NFAPI_MODE != NFAPI_MODE_PNF && NFAPI_MODE != NFAPI_MODE_VNF && NFAPI_MODE != NFAPI_MODE_AERIAL) {
|
||||
printf("Not NFAPI mode - call init_eNB_afterRU()\n");
|
||||
init_eNB_afterRU();
|
||||
} else {
|
||||
|
||||
@@ -103,7 +103,7 @@ extern "C"
|
||||
#define CONFIG_HLP_NOKRNMOD "(noS1 only): Use tun instead of namesh module \n"
|
||||
#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n"
|
||||
#define CONFIG_HLP_USRP_THREAD "having extra thead for usrp tx\n"
|
||||
#define CONFIG_HLP_NFAPI "Change the nFAPI mode for NR 'MONOLITHIC', 'PNF', 'VNF','UE_STUB_PNF','UE_STUB_OFFNET','STANDALONE_PNF'\n"
|
||||
#define CONFIG_HLP_NFAPI "Change the nFAPI mode for NR 'MONOLITHIC', 'PNF', 'VNF', 'AERIAL','UE_STUB_PNF','UE_STUB_OFFNET','STANDALONE_PNF'\n"
|
||||
#define CONFIG_L1_EMULATOR "Run in L1 emulated mode (disable PHY layer)\n"
|
||||
#define CONFIG_HLP_CONTINUOUS_TX "perform continuous transmission, even in TDD mode (to work around USRP issues)\n"
|
||||
#define CONFIG_HLP_STATS_DISABLE "disable globally the stats generation and persistence"
|
||||
@@ -232,9 +232,9 @@ extern int usrp_tx_thread;
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s3a = { config_checkstr_assign_integer, \
|
||||
{"MONOLITHIC", "PNF", "VNF","UE_STUB_PNF","UE_STUB_OFFNET","STANDALONE_PNF"}, \
|
||||
{NFAPI_MONOLITHIC, NFAPI_MODE_PNF, NFAPI_MODE_VNF,NFAPI_UE_STUB_PNF,NFAPI_UE_STUB_OFFNET,NFAPI_MODE_STANDALONE_PNF}, \
|
||||
6 } }, \
|
||||
{"MONOLITHIC", "PNF", "VNF", "AERIAL","UE_STUB_PNF","UE_STUB_OFFNET","STANDALONE_PNF"}, \
|
||||
{NFAPI_MONOLITHIC, NFAPI_MODE_PNF, NFAPI_MODE_VNF, NFAPI_MODE_AERIAL,NFAPI_UE_STUB_PNF,NFAPI_UE_STUB_OFFNET,NFAPI_MODE_STANDALONE_PNF}, \
|
||||
7 } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
|
||||
2
maketags
2
maketags
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
echo "building ctags for openair1 and openair2 ..."
|
||||
ctags -e -R --exclude=openair1/DOCS/ --exclude=openair2/DOCS/ --exclude=openair1/SIMULATION/ --exclude=targets/DOCS/ --exclude=targets/PROJECTS/ openair1 openair2 openair3 targets cmake_targets common nfapi executables radio
|
||||
ctags -e -R --exclude=openair1/DOCS/ --exclude=openair2/DOCS/ --exclude=openair1/SIMULATION/ --exclude=targets/DOCS/ --exclude=targets/PROJECTS/ openair1 openair2 openair3 targets cmake_targets common fapi nfapi executables radio
|
||||
|
||||
|
||||
1
nfapi/CMakeLists.txt
Normal file
1
nfapi/CMakeLists.txt
Normal file
@@ -0,0 +1 @@
|
||||
include(${OPENAIR_DIR}/nfapi/oai_integration/aerial/CMakeLists.txt)
|
||||
33
nfapi/oai_integration/aerial/CMakeLists.txt
Normal file
33
nfapi/oai_integration/aerial/CMakeLists.txt
Normal file
@@ -0,0 +1,33 @@
|
||||
add_boolean_option(OAI_AERIAL OFF "Activate OAI's AERIAL driver" OFF)
|
||||
if (OAI_AERIAL)
|
||||
message(STATUS "Building with support for Aerial")
|
||||
|
||||
target_sources(
|
||||
nr-softmodem
|
||||
PRIVATE
|
||||
${OPENAIR_DIR}/nfapi/oai_integration/aerial/fapi_nvIPC.c
|
||||
${OPENAIR_DIR}/nfapi/oai_integration/aerial/fapi_vnf_p7.c
|
||||
${OPENAIR_DIR}/nfapi/oai_integration/aerial/fapi_vnf_p5.c )
|
||||
|
||||
find_library(NVIPC_LIB nvipc REQUIRED)
|
||||
if (NOT NVIPC_LIB)
|
||||
message(FATAL_ERROR "-- nvipc library not found")
|
||||
else ()
|
||||
message(STATUS " nvipc library found in ${NVIPC_LIB}")
|
||||
#add_library(nvipc STATIC SHARED IMPORTED GLOBAL)
|
||||
endif ()
|
||||
|
||||
find_library(NVLOG_LIB nvlog REQUIRED)
|
||||
if (NOT NVLOG_LIB)
|
||||
message(FATAL_ERROR "-- nvlog library not found")
|
||||
else ()
|
||||
message(STATUS " nvlog library found in ${NVLOG_LIB}")
|
||||
endif ()
|
||||
|
||||
add_compile_definitions(ENABLE_L2_SLT_RSP)
|
||||
add_compile_definitions(FAPI_BYTE_ORDERING_BIG_ENDIAN)
|
||||
add_compile_definitions(ENABLE_AERIAL)
|
||||
target_link_libraries(nr-softmodem PRIVATE "${NVLOG_LIB}" "${NVIPC_LIB}")
|
||||
else()
|
||||
message(STATUS "No Support for Aerial")
|
||||
endif()
|
||||
683
nfapi/oai_integration/aerial/fapi_nvIPC.c
Normal file
683
nfapi/oai_integration/aerial/fapi_nvIPC.c
Normal file
@@ -0,0 +1,683 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*! \file fapi/oai-integration/fapi_nvIPC.c
|
||||
* \brief OAI MAC/Aerial L1 interface file using FAPI over shared memory
|
||||
* \author Ruben S. Silva
|
||||
* \date 2023
|
||||
* \version 0.1
|
||||
* \company OpenAirInterface Software Alliance
|
||||
* \email: contact@openairinterface.org, rsilva@allbesmart.pt
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#ifdef ENABLE_AERIAL
|
||||
#define _GNU_SOURCE
|
||||
#include <sched.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
#include <stdatomic.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/epoll.h>
|
||||
#include "fapi_nvIPC.h"
|
||||
#include "nfapi_interface.h"
|
||||
#include "nfapi.h"
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
#include "nfapi/open-nFAPI/vnf/inc/vnf_p7.h"
|
||||
|
||||
#include "fapi_vnf_p5.h"
|
||||
#include "fapi_vnf_p7.h"
|
||||
|
||||
#define MAX_EVENTS 10
|
||||
#define RECV_BUF_LEN 8192
|
||||
char cpu_buf_recv[RECV_BUF_LEN];
|
||||
|
||||
uint16_t sfn = 0, slot = 0;
|
||||
nv_ipc_t *ipc;
|
||||
nfapi_vnf_config_t *vnf_config = 0;
|
||||
|
||||
void set_config(nfapi_vnf_config_t *conf)
|
||||
{
|
||||
vnf_config = conf;
|
||||
}
|
||||
static uint16_t old_sfn = 0;
|
||||
static uint16_t old_slot = 0;
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Handle an RX message
|
||||
static int ipc_handle_rx_msg(nv_ipc_t *ipc, nv_ipc_msg_t *msg)
|
||||
{
|
||||
if (msg == NULL) {
|
||||
LOG_E(NFAPI_VNF, "%s: ERROR: buffer is empty\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *p_cpu_data = NULL;
|
||||
if (msg->data_buf != NULL) {
|
||||
int gpu;
|
||||
if (msg->data_pool == NV_IPC_MEMPOOL_CUDA_DATA) {
|
||||
gpu = 1;
|
||||
} else {
|
||||
gpu = 0;
|
||||
}
|
||||
|
||||
#ifdef NVIPC_CUDA_ENABLE
|
||||
// Test CUDA: call CUDA functions to change all string to lower case
|
||||
test_cuda_to_lower_case(test_cuda_device_id, msg->data_buf, TEST_DATA_BUF_LEN, gpu);
|
||||
#endif
|
||||
|
||||
if (gpu) {
|
||||
p_cpu_data = cpu_buf_recv;
|
||||
memset(cpu_buf_recv, 0, RECV_BUF_LEN);
|
||||
ipc->cuda_memcpy_to_host(ipc, p_cpu_data, msg->data_buf, RECV_BUF_LEN);
|
||||
} else {
|
||||
p_cpu_data = msg->data_buf;
|
||||
}
|
||||
}
|
||||
|
||||
int messageBufLen = msg->msg_len;
|
||||
int dataBufLen = msg->data_len;
|
||||
uint8_t msgbuf[messageBufLen];
|
||||
uint8_t databuf[dataBufLen];
|
||||
memcpy(msgbuf, msg->msg_buf, messageBufLen);
|
||||
memcpy(databuf, msg->data_buf, dataBufLen);
|
||||
uint8_t *pReadPackedMessage = msgbuf;
|
||||
uint8_t *pReadData = databuf;
|
||||
uint8_t *end = msgbuf + messageBufLen;
|
||||
uint8_t *data_end = databuf + dataBufLen;
|
||||
|
||||
// unpack FAPI messages and handle them
|
||||
if (vnf_config != 0) {
|
||||
// first, unpack the header
|
||||
fapi_phy_api_msg *fapi_msg = calloc(1, sizeof(fapi_phy_api_msg));
|
||||
if (!(pull8(&pReadPackedMessage, &fapi_msg->num_msg, end) && pull8(&pReadPackedMessage, &fapi_msg->opaque_handle, end)
|
||||
&& pull16(&pReadPackedMessage, &fapi_msg->message_id, end)
|
||||
&& pull32(&pReadPackedMessage, &fapi_msg->message_length, end))) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "FAPI message header unpack failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (fapi_msg->message_id) {
|
||||
case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
|
||||
|
||||
if (vnf_config->nr_param_resp) {
|
||||
nfapi_nr_param_response_scf_t msg_param_resp;
|
||||
aerial_unpack_nr_param_response(&pReadPackedMessage, end, &msg_param_resp, &vnf_config->codec_config);
|
||||
(vnf_config->nr_param_resp)(vnf_config, vnf_config->pnf_list->p5_idx, &msg_param_resp);
|
||||
}
|
||||
break;
|
||||
|
||||
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE: {
|
||||
// unpack message
|
||||
nfapi_nr_config_response_scf_t msg_config_response;
|
||||
aerial_unpack_nr_config_response(&pReadPackedMessage, end, &msg_config_response, &vnf_config->codec_config);
|
||||
// Check the error code
|
||||
if (msg_config_response.error_code == NFAPI_NR_CONFIG_MSG_OK) {
|
||||
// Invoke the call back
|
||||
if (vnf_config->nr_config_resp) {
|
||||
(vnf_config->nr_config_resp)(vnf_config, vnf_config->pnf_list->p5_idx, &msg_config_response);
|
||||
}
|
||||
} else {
|
||||
// Error code not OK (MSG_INVALID_CONFIG)
|
||||
/* MSG_INVALID_CONFIG.response structure
|
||||
* Error code uint8_t
|
||||
* Number of invalid or unsupported TLVs uint8_t
|
||||
* Number of invalid TLVs that can only be configured in IDLE state uint8_t
|
||||
* Number of invalid TLVs that can only be configured in RUNNING state uint8_t
|
||||
* Number of missing TLVs uint8_t
|
||||
* List of invalid or unsupported TLVs
|
||||
* List of invalid TLVs that can only be configured in IDLE state
|
||||
* List of invalid TLVs that can only be configured in RUNNING state
|
||||
* List of missing TLVs
|
||||
* */
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION: {
|
||||
// TODO : ADD Support for NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION (0x06)
|
||||
LOG_D(NFAPI_VNF,"Received NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION\n");
|
||||
break;
|
||||
}
|
||||
|
||||
case NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION: {
|
||||
// TODO: Add Support for NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION (0x07)
|
||||
LOG_D(NFAPI_VNF,"Received NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION\n");
|
||||
//for (int i = 0; i < msg->msg_len; i++) {
|
||||
// printf(" msg->msg_buf[%d] = 0x%02x\n", i, ((uint8_t *) msg->msg_buf)[i]);
|
||||
//}
|
||||
LOG_D(NFAPI_VNF,"old sfn %u\n", old_sfn);
|
||||
LOG_D(NFAPI_VNF,"old slot %u\n", old_slot);
|
||||
|
||||
break;
|
||||
}
|
||||
// P7 Messages
|
||||
// P7 Message Handlers -> ((vnf_info *)vnf_config->user_data)->p7_vnfs->config->
|
||||
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION: {
|
||||
nfapi_nr_slot_indication_scf_t ind;
|
||||
aerial_unpack_nr_slot_indication(&pReadPackedMessage,
|
||||
end,
|
||||
&ind,
|
||||
&((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config);
|
||||
// check if the sfn/slot unpacked come wrong at any time, should be old + 1 (slot 0 -- 19, sfn 0 -- 1023)
|
||||
// add 1 to current sfn number
|
||||
uint16_t old_slot_plus = ((old_slot + 1) % 20);
|
||||
uint16_t old_sfn_plus = old_slot_plus == 0 ? ((old_sfn + 1) % 1024) : old_sfn;
|
||||
if (old_slot_plus != ind.slot || old_sfn_plus != ind.sfn) {
|
||||
LOG_E(NFAPI_VNF,
|
||||
"\n============================================================================\n"
|
||||
"sfn slot doesn't match unpacked one! L2->L1 %d.%d vs L1->L2 %d.%d \n"
|
||||
"============================================================================\n",
|
||||
old_sfn,
|
||||
old_slot,
|
||||
ind.sfn,
|
||||
ind.slot);
|
||||
}
|
||||
old_sfn = ind.sfn;
|
||||
old_slot = ind.slot;
|
||||
if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_slot_indication) {
|
||||
(((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_slot_indication)(&ind);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION: {
|
||||
nfapi_nr_rx_data_indication_t ind;
|
||||
ind.header.message_id = fapi_msg->message_id;
|
||||
ind.header.message_length = fapi_msg->message_length;
|
||||
aerial_unpack_nr_rx_data_indication(
|
||||
&pReadPackedMessage,
|
||||
end,
|
||||
&pReadData,
|
||||
data_end,
|
||||
&ind,
|
||||
&((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config);
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s: Handling RX Indication\n", __FUNCTION__);
|
||||
if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_rx_data_indication) {
|
||||
(((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_rx_data_indication)(&ind);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION: {
|
||||
nfapi_nr_crc_indication_t crc_ind;
|
||||
crc_ind.header.message_id = fapi_msg->message_id;
|
||||
crc_ind.header.message_length = fapi_msg->message_length;
|
||||
aerial_unpack_nr_crc_indication(&pReadPackedMessage,
|
||||
end,
|
||||
&crc_ind,
|
||||
&((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config);
|
||||
if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_crc_indication) {
|
||||
(((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_crc_indication)(&crc_ind);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION: {
|
||||
nfapi_nr_uci_indication_t ind;
|
||||
aerial_unpack_nr_uci_indication(&pReadPackedMessage,
|
||||
end,
|
||||
&ind,
|
||||
&((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config);
|
||||
|
||||
if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_uci_indication) {
|
||||
(((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_uci_indication)(&ind);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION: {
|
||||
nfapi_nr_srs_indication_t ind;
|
||||
aerial_unpack_nr_srs_indication(&pReadPackedMessage,
|
||||
end,
|
||||
&ind,
|
||||
&((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config);
|
||||
if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_srs_indication) {
|
||||
(((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_srs_indication)(&ind);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION: {
|
||||
nfapi_nr_rach_indication_t ind;
|
||||
aerial_unpack_nr_rach_indication(&pReadPackedMessage,
|
||||
end,
|
||||
&ind,
|
||||
&((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config);
|
||||
if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_rach_indication) {
|
||||
(((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_rach_indication)(&ind);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s P5 Unknown message ID %d\n", __FUNCTION__, fapi_msg->message_id);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t buf[1024];
|
||||
|
||||
nv_ipc_config_t nv_ipc_config;
|
||||
|
||||
int aerial_send_P5_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p4_p5_message_header_t *header)
|
||||
{
|
||||
if (ipc == NULL) {
|
||||
return -1;
|
||||
}
|
||||
nv_ipc_msg_t send_msg = {0};
|
||||
// look for the specific message
|
||||
switch (header->message_id) {
|
||||
case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE:
|
||||
break;
|
||||
default: {
|
||||
if (header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
|
||||
// if(config && config->pack_p4_p5_vendor_extension) {
|
||||
// result = (config->pack_p4_p5_vendor_extension)(header, ppWritePackedMsg, end, config);
|
||||
// } else {
|
||||
// NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve ecoder provided\n", __FUNCTION__, header->message_id);
|
||||
// }
|
||||
} else {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
send_msg.msg_id = header->message_id;
|
||||
send_msg.cell_id = 0;
|
||||
send_msg.msg_len = packedMsgLength + 8; // adding 8 to account for the size of the FAPI header
|
||||
send_msg.data_len = 0;
|
||||
send_msg.data_buf = NULL;
|
||||
send_msg.data_pool = NV_IPC_MEMPOOL_CPU_MSG;
|
||||
|
||||
// procedure is allocate->fill->send
|
||||
int alloc_retval = ipc->tx_allocate(ipc, &send_msg, 0);
|
||||
if (alloc_retval != 0) {
|
||||
LOG_E(NFAPI_VNF, "%s error: allocate TX buffer failed Error: %d\n", __FUNCTION__, alloc_retval);
|
||||
ipc->tx_release(ipc, &send_msg);
|
||||
return alloc_retval;
|
||||
}
|
||||
|
||||
memcpy(send_msg.msg_buf, packedBuf, send_msg.msg_len);
|
||||
LOG_D(NFAPI_VNF,
|
||||
"send: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n",
|
||||
send_msg.cell_id,
|
||||
send_msg.msg_id,
|
||||
send_msg.msg_len,
|
||||
send_msg.data_len,
|
||||
send_msg.data_pool);
|
||||
// Send the message
|
||||
int send_retval = ipc->tx_send_msg(ipc, &send_msg);
|
||||
if (send_retval < 0) {
|
||||
LOG_E(NFAPI_VNF, "%s error: send TX message failed Error: %d\n", __FUNCTION__, send_retval);
|
||||
ipc->tx_release(ipc, &send_msg);
|
||||
return send_retval;
|
||||
}
|
||||
|
||||
ipc->notify(ipc, 1); // notify that there's 1 message in queue
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_send_P7_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p7_message_header_t *header)
|
||||
{
|
||||
if (ipc == NULL) {
|
||||
return -1;
|
||||
}
|
||||
nv_ipc_msg_t send_msg;
|
||||
uint8_t *pPacketBodyField = &((uint8_t *)packedBuf)[8];
|
||||
uint8_t *pPackMessageEnd = packedBuf + packedMsgLength + 8;
|
||||
|
||||
uint16_t present_sfn = 0;
|
||||
uint16_t present_slot = 0;
|
||||
pull16(&pPacketBodyField, &present_sfn, pPackMessageEnd);
|
||||
pull16(&pPacketBodyField, &present_slot, pPackMessageEnd);
|
||||
|
||||
if (present_sfn != old_sfn || present_slot != old_slot) {
|
||||
LOG_E(NFAPI_VNF,
|
||||
"\n============================================================================\n"
|
||||
"sfn slot doesn't match unpacked one! L2->L1 %d.%d vs L1->L2 %d.%d \n"
|
||||
"============================================================================\n",
|
||||
present_sfn,
|
||||
present_slot,
|
||||
old_sfn,
|
||||
old_slot);
|
||||
}
|
||||
// look for the specific message
|
||||
switch (header->message_id) {
|
||||
case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
|
||||
case NFAPI_UE_RELEASE_REQUEST:
|
||||
case NFAPI_UE_RELEASE_RESPONSE:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
|
||||
case NFAPI_TIMING_INFO:
|
||||
case 0x8f:
|
||||
break;
|
||||
default: {
|
||||
if (header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
|
||||
} else {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
send_msg.msg_id = header->message_id;
|
||||
send_msg.cell_id = 0;
|
||||
send_msg.msg_len = packedMsgLength + 8; // adding 8 to account for the size of the FAPI header
|
||||
send_msg.data_len = 0;
|
||||
send_msg.data_buf = NULL;
|
||||
send_msg.data_pool = NV_IPC_MEMPOOL_CPU_MSG;
|
||||
// procedure is allocate->fill->send
|
||||
|
||||
// Allocate buffer for TX message
|
||||
int alloc_retval = ipc->tx_allocate(ipc, &send_msg, 0);
|
||||
if (alloc_retval != 0) {
|
||||
LOG_E(NFAPI_VNF, "%s error: allocate TX buffer failed Error: %d\n", __FUNCTION__, alloc_retval);
|
||||
ipc->tx_release(ipc, &send_msg);
|
||||
return alloc_retval;
|
||||
}
|
||||
|
||||
memcpy(send_msg.msg_buf, packedBuf, send_msg.msg_len);
|
||||
LOG_D(NFAPI_VNF,
|
||||
"send: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n",
|
||||
send_msg.cell_id,
|
||||
send_msg.msg_id,
|
||||
send_msg.msg_len,
|
||||
send_msg.data_len,
|
||||
send_msg.data_pool);
|
||||
// Send the message
|
||||
int send_retval = ipc->tx_send_msg(ipc, &send_msg);
|
||||
if (send_retval < 0) {
|
||||
LOG_E(NFAPI_VNF, "%s error: send TX message failed Error: %d\n", __FUNCTION__, send_retval);
|
||||
ipc->tx_release(ipc, &send_msg);
|
||||
return send_retval;
|
||||
}
|
||||
|
||||
ipc->notify(ipc, 1); // notify that there's 1 message in queue
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_send_P7_msg_with_data(void *packedBuf,
|
||||
uint32_t packedMsgLength,
|
||||
void *dataBuf,
|
||||
uint32_t dataLength,
|
||||
nfapi_p7_message_header_t *header)
|
||||
{
|
||||
if (ipc == NULL) {
|
||||
return -1;
|
||||
}
|
||||
nv_ipc_msg_t send_msg;
|
||||
uint8_t *pPacketBodyField = &((uint8_t *)packedBuf)[8];
|
||||
uint8_t *pPackMessageEnd = packedBuf + packedMsgLength + 8;
|
||||
uint16_t present_sfn = 0;
|
||||
uint16_t present_slot = 0;
|
||||
pull16(&pPacketBodyField, &present_sfn, pPackMessageEnd);
|
||||
pull16(&pPacketBodyField, &present_slot, pPackMessageEnd);
|
||||
|
||||
if (present_sfn != old_sfn || present_slot != old_slot) {
|
||||
LOG_E(NFAPI_VNF,
|
||||
"\n============================================================================\n"
|
||||
"sfn slot doesn't match unpacked one! L2->L1 %d.%d vs L1->L2 %d.%d \n"
|
||||
"============================================================================\n",
|
||||
present_sfn,
|
||||
present_slot,
|
||||
old_sfn,
|
||||
old_slot);
|
||||
}
|
||||
// look for the specific message
|
||||
switch (header->message_id) {
|
||||
case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
|
||||
case NFAPI_UE_RELEASE_REQUEST:
|
||||
case NFAPI_UE_RELEASE_RESPONSE:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
|
||||
case NFAPI_TIMING_INFO:
|
||||
break;
|
||||
default: {
|
||||
if (header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
|
||||
} else {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
send_msg.msg_id = header->message_id;
|
||||
send_msg.cell_id = 0;
|
||||
send_msg.msg_len = packedMsgLength + 8; // adding 8 to account for the size of the FAPI header
|
||||
send_msg.data_len = dataLength;
|
||||
send_msg.data_pool = NV_IPC_MEMPOOL_CPU_DATA;
|
||||
|
||||
// procedure is allocate->fill->send
|
||||
|
||||
// Allocate buffer for TX message
|
||||
int alloc_retval = ipc->tx_allocate(ipc, &send_msg, 0);
|
||||
if (alloc_retval != 0) {
|
||||
LOG_E(NFAPI_VNF, "%s error: allocate TX buffer failed Error: %d\n", __FUNCTION__, alloc_retval);
|
||||
ipc->tx_release(ipc, &send_msg);
|
||||
return alloc_retval;
|
||||
}
|
||||
|
||||
memcpy(send_msg.msg_buf, packedBuf, send_msg.msg_len);
|
||||
memcpy(send_msg.data_buf, dataBuf, send_msg.data_len);
|
||||
LOG_D(NFAPI_VNF,
|
||||
"send: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n",
|
||||
send_msg.cell_id,
|
||||
send_msg.msg_id,
|
||||
send_msg.msg_len,
|
||||
send_msg.data_len,
|
||||
send_msg.data_pool);
|
||||
// Send the message
|
||||
int send_retval = ipc->tx_send_msg(ipc, &send_msg);
|
||||
if (send_retval != 0) {
|
||||
LOG_E(NFAPI_VNF, "%s error: send TX message failed Error: %d\n", __FUNCTION__, send_retval);
|
||||
ipc->tx_release(ipc, &send_msg);
|
||||
return send_retval;
|
||||
}
|
||||
|
||||
ipc->notify(ipc, 1); // notify that there's 1 message in queue
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Always allocate message buffer, but allocate data buffer only when data_len > 0
|
||||
static int aerial_recv_msg(nv_ipc_t *ipc, nv_ipc_msg_t *recv_msg)
|
||||
{
|
||||
if (ipc == NULL) {
|
||||
return -1;
|
||||
}
|
||||
recv_msg->msg_buf = NULL;
|
||||
recv_msg->data_buf = NULL;
|
||||
|
||||
// Allocate buffer for TX message
|
||||
if (ipc->rx_recv_msg(ipc, recv_msg) < 0) {
|
||||
LOG_D(NFAPI_VNF, "%s: no more message available\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
LOG_D(NFAPI_VNF,
|
||||
"recv: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n",
|
||||
recv_msg->cell_id,
|
||||
recv_msg->msg_id,
|
||||
recv_msg->msg_len,
|
||||
recv_msg->data_len,
|
||||
recv_msg->data_pool);
|
||||
ipc_handle_rx_msg(ipc, recv_msg);
|
||||
|
||||
// Release buffer of RX message
|
||||
int release_retval = ipc->rx_release(ipc, recv_msg);
|
||||
if (release_retval != 0) {
|
||||
LOG_E(NFAPI_VNF, "%s error: release RX buffer failed Error: %d\n", __FUNCTION__, release_retval);
|
||||
return release_retval;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool recv_task_running = false;
|
||||
int stick_this_thread_to_core(int core_id)
|
||||
{
|
||||
int num_cores = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
if (core_id < 0 || core_id >= num_cores)
|
||||
return EINVAL;
|
||||
|
||||
cpu_set_t cpuset;
|
||||
CPU_ZERO(&cpuset);
|
||||
CPU_SET(core_id, &cpuset);
|
||||
|
||||
pthread_t current_thread = pthread_self();
|
||||
return pthread_setaffinity_np(current_thread, sizeof(cpu_set_t), &cpuset);
|
||||
}
|
||||
void *epoll_recv_task(void *arg)
|
||||
{
|
||||
struct epoll_event ev, events[MAX_EVENTS];
|
||||
stick_this_thread_to_core(10);
|
||||
LOG_D(NFAPI_VNF,"Aerial recv task start \n");
|
||||
int epoll_fd = epoll_create1(0);
|
||||
if (epoll_fd == -1) {
|
||||
LOG_E(NFAPI_VNF, "%s epoll_create failed\n", __func__);
|
||||
}
|
||||
|
||||
int ipc_rx_event_fd = ipc->get_fd(ipc);
|
||||
ev.events = EPOLLIN;
|
||||
ev.data.fd = ipc_rx_event_fd;
|
||||
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, ev.data.fd, &ev) == -1) {
|
||||
LOG_E(NFAPI_VNF, "%s epoll_ctl failed\n", __func__);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (!recv_task_running) {
|
||||
recv_task_running = true;
|
||||
}
|
||||
LOG_D(NFAPI_VNF, "%s: epoll_wait fd_rx=%d ...\n", __func__, ipc_rx_event_fd);
|
||||
|
||||
int nfds;
|
||||
do {
|
||||
// epoll_wait() may return EINTR when get unexpected signal SIGSTOP from system
|
||||
nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
|
||||
} while (nfds == -1 && errno == EINTR);
|
||||
|
||||
if (nfds < 0) {
|
||||
LOG_E(NFAPI_VNF, "epoll_wait failed: epoll_fd=%d nfds=%d err=%d - %s\n", epoll_fd, nfds, errno, strerror(errno));
|
||||
}
|
||||
|
||||
int n = 0;
|
||||
for (n = 0; n < nfds; ++n) {
|
||||
if (events[n].data.fd == ipc_rx_event_fd) {
|
||||
ipc->get_value(ipc);
|
||||
nv_ipc_msg_t recv_msg;
|
||||
while (aerial_recv_msg(ipc, &recv_msg) == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
close(epoll_fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int create_recv_thread(void)
|
||||
{
|
||||
pthread_t thread_id;
|
||||
|
||||
void *(*recv_task)(void *);
|
||||
|
||||
recv_task = epoll_recv_task;
|
||||
|
||||
int ret = pthread_create(&thread_id, NULL, recv_task, NULL);
|
||||
if (ret != 0) {
|
||||
LOG_E(NFAPI_VNF, "%s failed, ret = %d\n", __func__, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int load_hard_code_config(nv_ipc_config_t *config, int module_type, nv_ipc_transport_t _transport)
|
||||
{
|
||||
// Create configuration
|
||||
config->ipc_transport = _transport;
|
||||
if (set_nv_ipc_default_config(config, module_type) < 0) {
|
||||
LOG_E(NFAPI_VNF, "%s: set configuration failed\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef NVIPC_CUDA_ENABLE
|
||||
int test_cuda_device_id = get_cuda_device_id();
|
||||
#else
|
||||
int test_cuda_device_id = -1;
|
||||
#endif
|
||||
LOG_D(NFAPI_VNF,"CUDA device ID configured : %d \n", test_cuda_device_id);
|
||||
config->transport_config.shm.cuda_device_id = test_cuda_device_id;
|
||||
if (test_cuda_device_id >= 0) {
|
||||
config->transport_config.shm.mempool_size[NV_IPC_MEMPOOL_CUDA_DATA].pool_len = 128;
|
||||
config->transport_config.shm.mempool_size[NV_IPC_MEMPOOL_CPU_DATA].pool_len = 1024;
|
||||
config->transport_config.shm.mempool_size[NV_IPC_MEMPOOL_CPU_MSG].pool_len = 4096;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nvIPC_Init() {
|
||||
// Want to use transport SHM, type epoll, module secondary (reads the created shm from cuphycontroller)
|
||||
load_hard_code_config(&nv_ipc_config, NV_IPC_MODULE_SECONDARY, NV_IPC_TRANSPORT_SHM);
|
||||
// Create nv_ipc_t instance
|
||||
if ((ipc = create_nv_ipc_interface(&nv_ipc_config)) == NULL) {
|
||||
LOG_E(NFAPI_VNF, "%s: create IPC interface failed\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
LOG_I(NFAPI_VNF, "%s: create IPC interface successful\n", __func__);
|
||||
sleep(1);
|
||||
create_recv_thread();
|
||||
while(!recv_task_running){usleep(100000);}
|
||||
aerial_pnf_nr_connection_indication_cb(vnf_config, 1);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
61
nfapi/oai_integration/aerial/fapi_nvIPC.h
Normal file
61
nfapi/oai_integration/aerial/fapi_nvIPC.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*! \file fapi/oai-integration/fapi_nvIPC.h
|
||||
* \brief Header file for fapi_nvIPC.c
|
||||
* \author Ruben S. Silva
|
||||
* \date 2023
|
||||
* \version 0.1
|
||||
* \company OpenAirInterface Software Alliance
|
||||
* \email: contact@openairinterface.org, rsilva@allbesmart.pt
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#ifdef ENABLE_AERIAL
|
||||
#ifndef OPENAIRINTERFACE_FAPI_NVIPC_H
|
||||
#define OPENAIRINTERFACE_FAPI_NVIPC_H
|
||||
|
||||
#include "nv_ipc.h"
|
||||
#include "nv_ipc_utils.h"
|
||||
#include "nvlog.h"
|
||||
#include "nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h"
|
||||
#include "openair1/PHY/defs_gNB.h"
|
||||
#include "debug.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t num_msg;
|
||||
uint8_t opaque_handle;
|
||||
uint16_t message_id;
|
||||
uint32_t message_length;
|
||||
} fapi_phy_api_msg;
|
||||
|
||||
int aerial_send_P5_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p4_p5_message_header_t *header);
|
||||
int aerial_send_P7_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p7_message_header_t *header);
|
||||
int aerial_send_P7_msg_with_data(void *packedBuf,
|
||||
uint32_t packedMsgLength,
|
||||
void *dataBuf,
|
||||
uint32_t dataLength,
|
||||
nfapi_p7_message_header_t *header);
|
||||
void set_config(nfapi_vnf_config_t *conf);
|
||||
int nvIPC_Init();
|
||||
|
||||
#endif // OPENAIRINTERFACE_FAPI_NVIPC_H
|
||||
#endif
|
||||
765
nfapi/oai_integration/aerial/fapi_vnf_p5.c
Normal file
765
nfapi/oai_integration/aerial/fapi_vnf_p5.c
Normal file
@@ -0,0 +1,765 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*! \file fapi/oai-integration/fapi_vnf_p5.c
|
||||
* \brief OAI FAPI VNF P5 message handler procedures
|
||||
* \author Ruben S. Silva
|
||||
* \date 2023
|
||||
* \version 0.1
|
||||
* \company OpenAirInterface Software Alliance
|
||||
* \email: contact@openairinterface.org, rsilva@allbesmart.pt
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#ifdef ENABLE_AERIAL
|
||||
#include "fapi_vnf_p5.h"
|
||||
#include "fapi_vnf_p7.h"
|
||||
#include "nfapi/open-nFAPI/nfapi/src/nfapi_p5.c"
|
||||
#include "nfapi/open-nFAPI/vnf/inc/vnf_p7.h"
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
extern UL_RCC_IND_t UL_RCC_INFO;
|
||||
extern int single_thread_flag;
|
||||
extern uint16_t sf_ahead;
|
||||
extern uint16_t slot_ahead;
|
||||
|
||||
|
||||
static pthread_t vnf_aerial_p7_start_pthread;
|
||||
void *aerial_vnf_nr_aerial_p7_start_thread(void *ptr)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__);
|
||||
pthread_setname_np(pthread_self(), "VNF_P7_AERIAL");
|
||||
nfapi_vnf_p7_config_t *config = (nfapi_vnf_p7_config_t *)ptr;
|
||||
aerial_nfapi_nr_vnf_p7_start(config);
|
||||
return config;
|
||||
}
|
||||
|
||||
void *aerial_vnf_nr_p7_thread_start(void *ptr)
|
||||
{
|
||||
// set_thread_priority(79);
|
||||
int s;
|
||||
cpu_set_t cpuset;
|
||||
|
||||
CPU_SET(8, &cpuset);
|
||||
s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
|
||||
if (s != 0)
|
||||
printf("failed to set afinity\n");
|
||||
|
||||
set_priority(79);
|
||||
|
||||
pthread_attr_t ptAttr;
|
||||
if (pthread_attr_setschedpolicy(&ptAttr, SCHED_RR) != 0) {
|
||||
printf("Failed to set pthread sched policy SCHED_RR\n");
|
||||
}
|
||||
|
||||
pthread_attr_setinheritsched(&ptAttr, PTHREAD_EXPLICIT_SCHED);
|
||||
struct sched_param thread_params;
|
||||
thread_params.sched_priority = 20;
|
||||
|
||||
if (pthread_attr_setschedparam(&ptAttr, &thread_params) != 0) {
|
||||
printf("failed to set sched param\n");
|
||||
}
|
||||
|
||||
init_queue(&gnb_rach_ind_queue);
|
||||
init_queue(&gnb_rx_ind_queue);
|
||||
init_queue(&gnb_crc_ind_queue);
|
||||
init_queue(&gnb_uci_ind_queue);
|
||||
init_queue(&gnb_slot_ind_queue);
|
||||
|
||||
vnf_p7_info *p7_vnf = (vnf_p7_info *)ptr;
|
||||
p7_vnf->config->port = p7_vnf->local_port;
|
||||
p7_vnf->config->sync_indication = &aerial_phy_sync_indication;
|
||||
p7_vnf->config->slot_indication = &aerial_phy_slot_indication;
|
||||
p7_vnf->config->harq_indication = &aerial_phy_harq_indication;
|
||||
p7_vnf->config->nr_crc_indication = &aerial_phy_nr_crc_indication;
|
||||
p7_vnf->config->nr_rx_data_indication = &aerial_phy_nr_rx_data_indication;
|
||||
p7_vnf->config->nr_rach_indication = &aerial_phy_nr_rach_indication;
|
||||
p7_vnf->config->nr_uci_indication = &aerial_phy_nr_uci_indication;
|
||||
p7_vnf->config->srs_indication = &aerial_phy_srs_indication;
|
||||
p7_vnf->config->sr_indication = &aerial_phy_sr_indication;
|
||||
p7_vnf->config->cqi_indication = &aerial_phy_cqi_indication;
|
||||
p7_vnf->config->lbt_dl_indication = &aerial_phy_lbt_dl_indication;
|
||||
p7_vnf->config->nb_harq_indication = &aerial_phy_nb_harq_indication;
|
||||
p7_vnf->config->nrach_indication = &aerial_phy_nrach_indication;
|
||||
p7_vnf->config->nr_slot_indication = &aerial_phy_nr_slot_indication;
|
||||
p7_vnf->config->nr_srs_indication = &aerial_phy_nr_srs_indication;
|
||||
p7_vnf->config->malloc = &aerial_vnf_allocate;
|
||||
p7_vnf->config->free = &aerial_vnf_deallocate;
|
||||
p7_vnf->config->vendor_ext = &aerial_phy_vendor_ext;
|
||||
p7_vnf->config->user_data = p7_vnf;
|
||||
p7_vnf->mac->user_data = p7_vnf;
|
||||
p7_vnf->config->codec_config.unpack_p7_vendor_extension = &aerial_phy_unpack_p7_vendor_extension;
|
||||
p7_vnf->config->codec_config.pack_p7_vendor_extension = &aerial_phy_pack_p7_vendor_extension;
|
||||
p7_vnf->config->codec_config.unpack_vendor_extension_tlv = &aerial_phy_unpack_vendor_extension_tlv;
|
||||
p7_vnf->config->codec_config.pack_vendor_extension_tlv = &aerial_phy_pack_vendor_extension_tlv;
|
||||
p7_vnf->config->codec_config.allocate = &aerial_vnf_allocate;
|
||||
p7_vnf->config->codec_config.deallocate = &aerial_vnf_deallocate;
|
||||
p7_vnf->config->allocate_p7_vendor_ext = &aerial_phy_allocate_p7_vendor_ext;
|
||||
p7_vnf->config->deallocate_p7_vendor_ext = &aerial_phy_deallocate_p7_vendor_ext;
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI P7 start thread %s\n", __FUNCTION__);
|
||||
pthread_create(&vnf_aerial_p7_start_pthread, NULL, &aerial_vnf_nr_aerial_p7_start_thread, p7_vnf->config);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int aerial_pnf_nr_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx)
|
||||
{
|
||||
printf("[VNF] pnf connection indication idx:%d\n", p5_idx);
|
||||
// in aerial, send first CONFIG.request, not PARAM.request
|
||||
nfapi_nr_config_request_scf_t conf_req;
|
||||
memset(&conf_req, 0, sizeof(conf_req));
|
||||
conf_req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST;
|
||||
printf("Try to send first CONFIG.request\n");
|
||||
aerial_nr_send_config_request(config, p5_idx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_pnf_disconnection_indication_cb(nfapi_vnf_config_t *config, int p5_idx)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] pnf disconnection indication idx:%d\n", p5_idx);
|
||||
vnf_info *vnf = (vnf_info *)(config->user_data);
|
||||
pnf_info *pnf = vnf->pnfs;
|
||||
phy_info *phy = pnf->phys;
|
||||
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
|
||||
nfapi_vnf_p7_del_pnf((p7_vnf->config), phy->id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_pnf_nr_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_param_response_t *resp)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] pnf param response idx:%d error:%d\n", p5_idx, resp->error_code);
|
||||
vnf_info *vnf = (vnf_info *)(config->user_data);
|
||||
pnf_info *pnf = vnf->pnfs;
|
||||
|
||||
for (int i = 0; i < resp->pnf_phy.number_of_phys; ++i) {
|
||||
phy_info phy;
|
||||
memset(&phy, 0, sizeof(phy));
|
||||
phy.index = resp->pnf_phy.phy[i].phy_config_index;
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] (PHY:%d) phy_config_idx:%d\n", i, resp->pnf_phy.phy[i].phy_config_index);
|
||||
nfapi_vnf_allocate_phy(config, p5_idx, &(phy.id));
|
||||
|
||||
for (int j = 0; j < resp->pnf_phy.phy[i].number_of_rfs; ++j) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] (PHY:%d) (RF%d) %d\n", i, j, resp->pnf_phy.phy[i].rf_config[j].rf_config_index);
|
||||
phy.rfs[0] = resp->pnf_phy.phy[i].rf_config[j].rf_config_index;
|
||||
}
|
||||
|
||||
pnf->phys[0] = phy;
|
||||
}
|
||||
nfapi_nr_pnf_config_request_t req;
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.header.message_id = NFAPI_PNF_CONFIG_REQUEST;
|
||||
req.pnf_phy_rf_config.tl.tag = NFAPI_PNF_PHY_RF_TAG;
|
||||
req.pnf_phy_rf_config.number_phy_rf_config_info = 2; // DJP pnf.phys.size();
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "DJP:Hard coded num phy rf to 2\n");
|
||||
|
||||
for (unsigned i = 0; i < 2; ++i) {
|
||||
req.pnf_phy_rf_config.phy_rf_config[i].phy_id = pnf->phys[i].id;
|
||||
req.pnf_phy_rf_config.phy_rf_config[i].phy_config_index = pnf->phys[i].index;
|
||||
req.pnf_phy_rf_config.phy_rf_config[i].rf_config_index = pnf->phys[i].rfs[0];
|
||||
}
|
||||
|
||||
nfapi_nr_vnf_pnf_config_req(config, p5_idx, &req);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_pnf_nr_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_config_response_t *resp)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO,
|
||||
"[VNF] pnf config response idx:%d resp[header[phy_id:%u message_id:%02x message_length:%u]]\n",
|
||||
p5_idx,
|
||||
resp->header.phy_id,
|
||||
resp->header.message_id,
|
||||
resp->header.message_length);
|
||||
|
||||
if (1) {
|
||||
nfapi_nr_pnf_start_request_t req;
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.header.phy_id = resp->header.phy_id;
|
||||
req.header.message_id = NFAPI_PNF_START_REQUEST;
|
||||
nfapi_nr_vnf_pnf_start_req(config, p5_idx, &req);
|
||||
} else {
|
||||
// Rather than send the pnf_start_request we will demonstrate
|
||||
// sending a vendor extention message. The start request will be
|
||||
// send when the vendor extension response is received
|
||||
// vnf_info* vnf = (vnf_info*)(config->user_data);
|
||||
vendor_ext_p5_req req;
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.header.message_id = P5_VENDOR_EXT_REQ;
|
||||
req.dummy1 = 45;
|
||||
req.dummy2 = 1977;
|
||||
nfapi_vnf_vendor_extension(config, p5_idx, &req.header);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_pnf_nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_start_response_t *resp)
|
||||
{
|
||||
vnf_info *vnf = (vnf_info *)(config->user_data);
|
||||
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
|
||||
pnf_info *pnf = vnf->pnfs;
|
||||
nfapi_nr_param_request_scf_t req;
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO,
|
||||
"[VNF] pnf start response idx:%d config:%p user_data:%p p7_vnf[config:%p thread_started:%d]\n",
|
||||
p5_idx,
|
||||
config,
|
||||
config->user_data,
|
||||
vnf->p7_vnfs[0].config,
|
||||
vnf->p7_vnfs[0].thread_started);
|
||||
|
||||
if (p7_vnf->thread_started == 0) {
|
||||
pthread_t vnf_p7_thread;
|
||||
pthread_create(&vnf_p7_thread, NULL, &aerial_vnf_nr_p7_thread_start, p7_vnf);
|
||||
p7_vnf->thread_started = 1;
|
||||
} else {
|
||||
// P7 thread already running.
|
||||
}
|
||||
|
||||
// start all the phys in the pnf.
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Sending NFAPI_VNF_PARAM_REQUEST phy_id:%d\n", pnf->phys[0].id);
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST;
|
||||
req.header.phy_id = pnf->phys[0].id;
|
||||
nfapi_nr_vnf_param_req(config, p5_idx, &req);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_nr_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_param_response_scf_t *resp)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Received NFAPI_PARAM_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
|
||||
vnf_info *vnf = (vnf_info *)(config->user_data);
|
||||
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
|
||||
pnf_info *pnf = vnf->pnfs;
|
||||
phy_info *phy = pnf->phys;
|
||||
struct sockaddr_in pnf_p7_sockaddr;
|
||||
nfapi_nr_config_request_scf_t *req = &RC.nrmac[0]->config[0]; // check
|
||||
phy->remote_port = resp->nfapi_config.p7_pnf_port.value;
|
||||
// phy->remote_port = 32123;//resp->nfapi_config.p7_pnf_port.value;
|
||||
memcpy(&pnf_p7_sockaddr.sin_addr.s_addr, &(resp->nfapi_config.p7_pnf_address_ipv4.address[0]), 4);
|
||||
phy->remote_addr = inet_ntoa(pnf_p7_sockaddr.sin_addr);
|
||||
// for now just 1
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO,
|
||||
"[VNF] %d.%d pnf p7 %s:%d timing %u %u %u %u\n",
|
||||
p5_idx,
|
||||
phy->id,
|
||||
phy->remote_addr,
|
||||
phy->remote_port,
|
||||
p7_vnf->timing_window,
|
||||
p7_vnf->periodic_timing_period,
|
||||
p7_vnf->aperiodic_timing_enabled,
|
||||
p7_vnf->periodic_timing_period);
|
||||
req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST;
|
||||
req->header.phy_id = phy->id;
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Send NFAPI_CONFIG_REQUEST\n");
|
||||
// NFAPI_TRACE(NFAPI_TRACE_INFO, "\n NR bandP =%d\n",req->nfapi_config.rf_bands.rf_band[0]);
|
||||
|
||||
req->nfapi_config.p7_vnf_port.tl.tag = NFAPI_NR_NFAPI_P7_VNF_PORT_TAG;
|
||||
req->nfapi_config.p7_vnf_port.value = p7_vnf->local_port;
|
||||
req->num_tlv++;
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] DJP local_port:%d\n", ntohs(p7_vnf->local_port));
|
||||
req->nfapi_config.p7_vnf_address_ipv4.tl.tag = NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG;
|
||||
struct sockaddr_in vnf_p7_sockaddr;
|
||||
vnf_p7_sockaddr.sin_addr.s_addr = inet_addr(p7_vnf->local_addr);
|
||||
memcpy(&(req->nfapi_config.p7_vnf_address_ipv4.address[0]), &vnf_p7_sockaddr.sin_addr.s_addr, 4);
|
||||
req->num_tlv++;
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] DJP local_addr:%s\n", p7_vnf->local_addr);
|
||||
req->nfapi_config.timing_window.tl.tag = NFAPI_NR_NFAPI_TIMING_WINDOW_TAG;
|
||||
req->nfapi_config.timing_window.value = p7_vnf->timing_window;
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO,
|
||||
"\n[VNF]Timing window tag : %d Timing window:%u\n",
|
||||
NFAPI_NR_NFAPI_TIMING_WINDOW_TAG,
|
||||
p7_vnf->timing_window);
|
||||
req->num_tlv++;
|
||||
|
||||
if (p7_vnf->periodic_timing_enabled || p7_vnf->aperiodic_timing_enabled) {
|
||||
req->nfapi_config.timing_info_mode.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG;
|
||||
req->nfapi_config.timing_info_mode.value = (p7_vnf->aperiodic_timing_enabled << 1) | (p7_vnf->periodic_timing_enabled);
|
||||
req->num_tlv++;
|
||||
|
||||
if (p7_vnf->periodic_timing_enabled) {
|
||||
req->nfapi_config.timing_info_period.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG;
|
||||
req->nfapi_config.timing_info_period.value = p7_vnf->periodic_timing_period;
|
||||
req->num_tlv++;
|
||||
}
|
||||
}
|
||||
// TODO: Assign tag and value for P7 message offsets
|
||||
req->nfapi_config.dl_tti_timing_offset.tl.tag = NFAPI_NR_NFAPI_DL_TTI_TIMING_OFFSET;
|
||||
req->nfapi_config.ul_tti_timing_offset.tl.tag = NFAPI_NR_NFAPI_UL_TTI_TIMING_OFFSET;
|
||||
req->nfapi_config.ul_dci_timing_offset.tl.tag = NFAPI_NR_NFAPI_UL_DCI_TIMING_OFFSET;
|
||||
req->nfapi_config.tx_data_timing_offset.tl.tag = NFAPI_NR_NFAPI_TX_DATA_TIMING_OFFSET;
|
||||
|
||||
vendor_ext_tlv_2 ve2;
|
||||
memset(&ve2, 0, sizeof(ve2));
|
||||
ve2.tl.tag = VENDOR_EXT_TLV_2_TAG;
|
||||
ve2.dummy = 2016;
|
||||
req->vendor_extension = &ve2.tl;
|
||||
nfapi_nr_vnf_config_req(config, p5_idx, req);
|
||||
printf("[VNF] Sent NFAPI_VNF_CONFIG_REQ num_tlv:%u\n", req->num_tlv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_nr_send_config_request(nfapi_vnf_config_t *config, int p5_idx)
|
||||
{
|
||||
vnf_info *vnf = (vnf_info *)(config->user_data);
|
||||
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
|
||||
pnf_info *pnf = vnf->pnfs;
|
||||
phy_info *phy = pnf->phys;
|
||||
|
||||
nfapi_nr_config_request_scf_t *req = &RC.nrmac[0]->config[0]; //&RC.gNB[0]->gNB_config; // check
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO,
|
||||
"[VNF] %d.%d pnf p7 %s:%d timing %u %u %u %u\n",
|
||||
p5_idx,
|
||||
phy->id,
|
||||
phy->remote_addr,
|
||||
phy->remote_port,
|
||||
p7_vnf->timing_window,
|
||||
p7_vnf->periodic_timing_period,
|
||||
p7_vnf->aperiodic_timing_enabled,
|
||||
p7_vnf->periodic_timing_period);
|
||||
req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST;
|
||||
req->header.phy_id = phy->id;
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Send NFAPI_CONFIG_REQUEST\n");
|
||||
|
||||
|
||||
vnf_t *_this = (vnf_t *)(config);
|
||||
|
||||
nfapi_vnf_phy_info_t *vnf_phy = nfapi_vnf_phy_info_list_find(config, req->header.phy_id);
|
||||
|
||||
if (vnf_phy == NULL) {
|
||||
printf("%s failed to find phy information phy_id:%d\n", __FUNCTION__, req->header.phy_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
nfapi_p4_p5_message_header_t *msg = &req->header;
|
||||
uint16_t msg_len = sizeof(nfapi_nr_config_request_scf_t);
|
||||
nfapi_p4_p5_message_header_t *msgFAPI = calloc(1, msg_len);
|
||||
memcpy(msgFAPI, &req->header, msg_len);
|
||||
uint8_t tx_messagebufferFAPI[sizeof(_this->tx_message_buffer)];
|
||||
int packedMessageLengthFAPI = -1;
|
||||
packedMessageLengthFAPI =
|
||||
fapi_nr_p5_message_pack(msgFAPI, msg_len, tx_messagebufferFAPI, sizeof(tx_messagebufferFAPI), &_this->_public.codec_config);
|
||||
|
||||
aerial_send_P5_msg(tx_messagebufferFAPI, packedMessageLengthFAPI, msg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_nr_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_config_response_scf_t *resp)
|
||||
{
|
||||
nfapi_nr_start_request_scf_t req;
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Received NFAPI_CONFIG_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
|
||||
LOG_I(NFAPI_VNF, "Received CONFIG.response, gNB is ready! \n");
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_START_REQUEST;
|
||||
req.header.phy_id = resp->header.phy_id;
|
||||
nfapi_nr_vnf_start_req(config, p5_idx, &req);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_start_response_scf_t *resp)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Received NFAPI_START_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
|
||||
vnf_info *vnf = (vnf_info *)(config->user_data);
|
||||
pnf_info *pnf = vnf->pnfs;
|
||||
phy_info *phy = pnf->phys;
|
||||
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
|
||||
|
||||
nfapi_vnf_p7_add_pnf((p7_vnf->config), phy->remote_addr, phy->remote_port, phy->id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_vendor_ext_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_p4_p5_message_header_t *msg)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s\n", __FUNCTION__);
|
||||
|
||||
switch (msg->message_id) {
|
||||
case P5_VENDOR_EXT_RSP: {
|
||||
vendor_ext_p5_rsp *rsp = (vendor_ext_p5_rsp *)msg;
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] P5_VENDOR_EXT_RSP error_code:%d\n", rsp->error_code);
|
||||
// send the start request
|
||||
nfapi_pnf_start_request_t req;
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.header.message_id = NFAPI_PNF_START_REQUEST;
|
||||
nfapi_vnf_pnf_start_req(config, p5_idx, &req);
|
||||
} break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_vnf_unpack_vendor_extension_tlv(nfapi_tl_t *tl,
|
||||
uint8_t **ppReadPackedMessage,
|
||||
uint8_t *end,
|
||||
void **ve,
|
||||
nfapi_p4_p5_codec_config_t *codec)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int aerial_vnf_pack_vendor_extension_tlv(void *vext, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *codec)
|
||||
{
|
||||
nfapi_tl_t *tlv = (nfapi_tl_t *)vext;
|
||||
|
||||
switch (tlv->tag) {
|
||||
case VENDOR_EXT_TLV_2_TAG: {
|
||||
vendor_ext_tlv_2 *ve = (vendor_ext_tlv_2 *)tlv;
|
||||
|
||||
if (!push32(ve->dummy, ppWritePackedMsg, end))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
} break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int aerial_vnf_unpack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header,
|
||||
uint8_t **ppReadPackedMessage,
|
||||
uint8_t *end,
|
||||
nfapi_p4_p5_codec_config_t *codec)
|
||||
{
|
||||
if (header->message_id == P5_VENDOR_EXT_RSP) {
|
||||
vendor_ext_p5_rsp *req = (vendor_ext_p5_rsp *)(header);
|
||||
return (!pull16(ppReadPackedMessage, &req->error_code, end));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_vnf_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header,
|
||||
uint8_t **ppWritePackedMsg,
|
||||
uint8_t *end,
|
||||
nfapi_p4_p5_codec_config_t *codec)
|
||||
{
|
||||
if (header->message_id == P5_VENDOR_EXT_REQ) {
|
||||
vendor_ext_p5_req *req = (vendor_ext_p5_req *)(header);
|
||||
return (!(push16(req->dummy1, ppWritePackedMsg, end) && push16(req->dummy2, ppWritePackedMsg, end)));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
nfapi_p4_p5_message_header_t *aerial_vnf_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t *msg_size)
|
||||
{
|
||||
if (message_id == P5_VENDOR_EXT_RSP) {
|
||||
*msg_size = sizeof(vendor_ext_p5_rsp);
|
||||
return (nfapi_p4_p5_message_header_t *)malloc(sizeof(vendor_ext_p5_rsp));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aerial_vnf_deallocate_p4_p5_vendor_ext(nfapi_p4_p5_message_header_t *header)
|
||||
{
|
||||
free(header);
|
||||
}
|
||||
|
||||
void *aerial_vnf_p5_allocate(size_t size)
|
||||
{
|
||||
// return (void*)memory_pool::allocate(size);
|
||||
return (void *)malloc(size);
|
||||
}
|
||||
|
||||
void aerial_vnf_p5_deallocate(void *ptr)
|
||||
{
|
||||
// memory_pool::deallocate((uint8_t*)ptr);
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
static vnf_info aerial_vnf;
|
||||
void aerial_configure_nr_fapi_vnf()
|
||||
{
|
||||
// TODO: Implement for FAPI
|
||||
// nfapi_setmode(NFAPI_MODE_VNF);
|
||||
memset(&aerial_vnf, 0, sizeof(aerial_vnf));
|
||||
memset(aerial_vnf.p7_vnfs, 0, sizeof(aerial_vnf.p7_vnfs));
|
||||
aerial_vnf.p7_vnfs[0].timing_window = 30;
|
||||
aerial_vnf.p7_vnfs[0].periodic_timing_enabled = 0;
|
||||
aerial_vnf.p7_vnfs[0].aperiodic_timing_enabled = 0;
|
||||
aerial_vnf.p7_vnfs[0].periodic_timing_period = 10;
|
||||
aerial_vnf.p7_vnfs[0].config = nfapi_vnf_p7_config_create();
|
||||
aerial_vnf.p7_vnfs[0].mac = (mac_t *)malloc(sizeof(mac_t));
|
||||
nfapi_vnf_config_t *config = nfapi_vnf_config_create();
|
||||
config->malloc = malloc;
|
||||
config->free = free;
|
||||
config->vnf_ipv4 = 1;
|
||||
config->vnf_ipv6 = 0;
|
||||
config->pnf_list = 0;
|
||||
config->phy_list = 0;
|
||||
|
||||
config->pnf_nr_connection_indication = &aerial_pnf_nr_connection_indication_cb;
|
||||
config->pnf_disconnect_indication = &aerial_pnf_disconnection_indication_cb;
|
||||
|
||||
config->pnf_nr_param_resp = &aerial_pnf_nr_param_resp_cb;
|
||||
config->pnf_nr_config_resp = &aerial_pnf_nr_config_resp_cb;
|
||||
config->pnf_nr_start_resp = &aerial_pnf_nr_start_resp_cb;
|
||||
config->nr_param_resp = &aerial_nr_param_resp_cb;
|
||||
config->nr_config_resp = &aerial_nr_config_resp_cb;
|
||||
config->nr_start_resp = &aerial_nr_start_resp_cb;
|
||||
config->vendor_ext = &aerial_vendor_ext_cb;
|
||||
config->user_data = &aerial_vnf;
|
||||
// To allow custom vendor extentions to be added to nfapi
|
||||
config->codec_config.unpack_vendor_extension_tlv = &aerial_vnf_unpack_vendor_extension_tlv;
|
||||
config->codec_config.pack_vendor_extension_tlv = &aerial_vnf_pack_vendor_extension_tlv;
|
||||
config->codec_config.unpack_p4_p5_vendor_extension = &aerial_vnf_unpack_p4_p5_vendor_extension;
|
||||
config->codec_config.pack_p4_p5_vendor_extension = &aerial_vnf_pack_p4_p5_vendor_extension;
|
||||
config->allocate_p4_p5_vendor_ext = &aerial_vnf_allocate_p4_p5_vendor_ext;
|
||||
config->deallocate_p4_p5_vendor_ext = &aerial_vnf_deallocate_p4_p5_vendor_ext;
|
||||
config->codec_config.allocate = &aerial_vnf_allocate;
|
||||
config->codec_config.deallocate = &aerial_vnf_deallocate;
|
||||
memset(&UL_RCC_INFO, 0, sizeof(UL_RCC_IND_t));
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI start thread %s\n", __FUNCTION__);
|
||||
set_config(config);
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Created VNF NFAPI start thread %s\n", __FUNCTION__);
|
||||
nfapi_vnf_pnf_info_t *pnf = (nfapi_vnf_pnf_info_t *)malloc(sizeof(nfapi_vnf_pnf_info_t));
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "MALLOC nfapi_vnf_pnf_info_t for pnf_list pnf:%p\n", pnf);
|
||||
memset(pnf, 0, sizeof(nfapi_vnf_pnf_info_t));
|
||||
pnf->p5_idx = 1;
|
||||
pnf->connected = 1;
|
||||
// Add needed parameters
|
||||
|
||||
vnf_info *vnf = (vnf_info *)(config->user_data);
|
||||
pnf_info *pnf_info = vnf->pnfs;
|
||||
|
||||
for (int i = 0; i < 1; ++i) {
|
||||
phy_info phy;
|
||||
memset(&phy, 0, sizeof(phy));
|
||||
phy.index = 0;
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] (PHY:%d) phy_config_idx:%d\n", i, 0);
|
||||
nfapi_vnf_allocate_phy(config, 1, &(phy.id));
|
||||
|
||||
for (int j = 0; j < 1; ++j) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] (PHY:%d) (RF%d) %d\n", i, j, 0);
|
||||
phy.rfs[0] = 0;
|
||||
}
|
||||
|
||||
pnf_info->phys[0] = phy;
|
||||
}
|
||||
|
||||
|
||||
nfapi_vnf_pnf_list_add(config, pnf);
|
||||
|
||||
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO,
|
||||
"[VNF] pnf start response idx:%d config:%p user_data:%p p7_vnf[config:%p thread_started:%d]\n",
|
||||
1,
|
||||
config,
|
||||
config->user_data,
|
||||
vnf->p7_vnfs[0].config,
|
||||
vnf->p7_vnfs[0].thread_started);
|
||||
|
||||
if (p7_vnf->thread_started == 0) {
|
||||
pthread_t vnf_p7_thread;
|
||||
pthread_create(&vnf_p7_thread, NULL, &aerial_vnf_nr_p7_thread_start, p7_vnf);
|
||||
p7_vnf->thread_started = 1;
|
||||
} else {
|
||||
// P7 thread already running.
|
||||
}
|
||||
}
|
||||
uint8_t aerial_unpack_nr_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config)
|
||||
{
|
||||
return unpack_nr_param_response(ppReadPackedMsg, end, msg, config);
|
||||
}
|
||||
uint8_t aerial_unpack_nr_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config)
|
||||
{
|
||||
return unpack_nr_config_response(ppReadPackedMsg, end, msg, config);
|
||||
}
|
||||
|
||||
// monitor the p7 endpoints and the timing loop and
|
||||
// send indications to mac
|
||||
int aerial_nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t *config)
|
||||
{
|
||||
if (config == 0)
|
||||
return -1;
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__);
|
||||
|
||||
vnf_p7_t *vnf_p7 = (vnf_p7_t *)config;
|
||||
|
||||
// Create p7 receive udp port
|
||||
// todo : this needs updating for Ipv6
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "Initialising VNF P7 port:%u\n", config->port);
|
||||
|
||||
|
||||
struct timespec ref_time;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ref_time);
|
||||
uint8_t setup_done = 0;
|
||||
while (vnf_p7->terminate == 0) {
|
||||
if (setup_done == 0) {
|
||||
struct timespec curr_time;
|
||||
clock_gettime(CLOCK_MONOTONIC, &curr_time);
|
||||
uint8_t setup_time = curr_time.tv_sec - ref_time.tv_sec;
|
||||
if (setup_time > 3) {
|
||||
setup_done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p7 socket\n");
|
||||
close(vnf_p7->socket);
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() returning\n", __FUNCTION__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fapi_nr_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t *config){
|
||||
|
||||
nfapi_p4_p5_message_header_t *pMessageHeader = pMessageBuf;
|
||||
uint8_t *pWritePackedMessage = pPackedBuf;
|
||||
|
||||
uint32_t packedMsgLen;
|
||||
//uint16_t packedMsgLen16;
|
||||
|
||||
if (pMessageBuf == NULL || pPackedBuf == NULL) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 Pack supplied pointers are null\n");
|
||||
return -1;
|
||||
}
|
||||
uint8_t *pPackMessageEnd = pPackedBuf + packedBufLen;
|
||||
uint8_t *pPackedLengthField = &pWritePackedMessage[4];
|
||||
uint8_t *pPacketBodyField = &pWritePackedMessage[8];
|
||||
uint8_t *pPacketBodyFieldStart = &pWritePackedMessage[8];
|
||||
|
||||
pack_nr_p5_message_body(pMessageHeader, &pPacketBodyField, pPackMessageEnd, config);
|
||||
|
||||
// PHY API message header
|
||||
push8(1, &pWritePackedMessage, pPackMessageEnd); // Number of messages
|
||||
push8(0, &pWritePackedMessage, pPackMessageEnd); // Opaque handle
|
||||
|
||||
// PHY API Message structure
|
||||
push16(pMessageHeader->message_id, &pWritePackedMessage, pPackMessageEnd); // Message type ID
|
||||
|
||||
if(1==1) {
|
||||
// check for a valid message length
|
||||
packedMsgLen = get_packed_msg_len((uintptr_t)pPacketBodyFieldStart, (uintptr_t)pPacketBodyField);
|
||||
packedMsgLen-=1;
|
||||
if(pMessageHeader->message_id == NFAPI_NR_PHY_MSG_TYPE_START_REQUEST){
|
||||
//START.request doesn't have a body, length is 0
|
||||
packedMsgLen = 0;
|
||||
}else if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message 0x%02x length error %d, buffer supplied %d\n",pMessageHeader->message_id, packedMsgLen, packedBufLen);
|
||||
return -1;
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
// Update the message length in the header
|
||||
if(!push32(packedMsgLen, &pPackedLengthField, pPackMessageEnd))
|
||||
return -1;
|
||||
|
||||
// return the packed length
|
||||
return (packedMsgLen);
|
||||
} else {
|
||||
// Failed to pack the meassage
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 Failed to pack message\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int oai_fapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req)
|
||||
{
|
||||
nfapi_vnf_p7_config_t *p7_config = aerial_vnf.p7_vnfs[0].config;
|
||||
|
||||
ul_tti_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
|
||||
ul_tti_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST;
|
||||
|
||||
// int retval = nfapi_vnf_p7_ul_tti_req(p7_config, ul_tti_req);
|
||||
int retval = fapi_nr_pack_and_send_p7_message((vnf_p7_t *)p7_config, &ul_tti_req->header);
|
||||
|
||||
if (retval != 0) {
|
||||
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
|
||||
} else {
|
||||
// Reset number of PDUs so that it is not resent
|
||||
ul_tti_req->n_pdus = 0;
|
||||
ul_tti_req->n_group = 0;
|
||||
ul_tti_req->n_ulcch = 0;
|
||||
ul_tti_req->n_ulsch = 0;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int oai_fapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req)
|
||||
{
|
||||
nfapi_vnf_p7_config_t *p7_config = aerial_vnf.p7_vnfs[0].config;
|
||||
ul_dci_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
|
||||
ul_dci_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST;
|
||||
// int retval = nfapi_vnf_p7_ul_dci_req(p7_config, ul_dci_req);
|
||||
int retval = fapi_nr_pack_and_send_p7_message((vnf_p7_t *)p7_config, &ul_dci_req->header);
|
||||
if (retval != 0) {
|
||||
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
|
||||
} else {
|
||||
ul_dci_req->numPdus = 0;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int oai_fapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req)
|
||||
{
|
||||
nfapi_vnf_p7_config_t *p7_config = aerial_vnf.p7_vnfs[0].config;
|
||||
tx_data_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
|
||||
tx_data_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST;
|
||||
// LOG_D(PHY, "[VNF] %s() TX_REQ sfn_sf:%d number_of_pdus:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(tx_data_req->SFN),
|
||||
// tx_data_req->Number_of_PDUs); int retval = nfapi_vnf_p7_tx_data_req(p7_config, tx_data_req);
|
||||
int retval = fapi_nr_pack_and_send_p7_message((vnf_p7_t *)p7_config, &tx_data_req->header);
|
||||
if (retval != 0) {
|
||||
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
|
||||
} else {
|
||||
tx_data_req->Number_of_PDUs = 0;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int oai_fapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req)
|
||||
{
|
||||
nfapi_vnf_p7_config_t *p7_config = aerial_vnf.p7_vnfs[0].config;
|
||||
dl_config_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST;
|
||||
dl_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
|
||||
int retval = fapi_nr_pack_and_send_p7_message((vnf_p7_t *)p7_config, &dl_config_req->header);
|
||||
dl_config_req->dl_tti_request_body.nPDUs = 0;
|
||||
dl_config_req->dl_tti_request_body.nGroup = 0;
|
||||
|
||||
if (retval != 0) {
|
||||
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int oai_fapi_send_end_request(int cell, uint32_t frame, uint32_t slot){
|
||||
nfapi_vnf_p7_config_t *p7_config = aerial_vnf.p7_vnfs[0].config;
|
||||
nfapi_nr_slot_indication_scf_t *nr_slot_resp = CALLOC(1, sizeof(*nr_slot_resp));
|
||||
nr_slot_resp->header.message_id = 0x8F;
|
||||
nr_slot_resp->sfn = frame;
|
||||
nr_slot_resp->slot = slot;
|
||||
int retval = fapi_nr_pack_and_send_p7_message((vnf_p7_t *)p7_config, &nr_slot_resp->header);
|
||||
if (retval != 0) {
|
||||
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
75
nfapi/oai_integration/aerial/fapi_vnf_p5.h
Normal file
75
nfapi/oai_integration/aerial/fapi_vnf_p5.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*! \file fapi/oai-integration/fapi_vnf_p5.h
|
||||
* \brief Header file for fapi_vnf_p5.c
|
||||
* \author Ruben S. Silva
|
||||
* \date 2023
|
||||
* \version 0.1
|
||||
* \company OpenAirInterface Software Alliance
|
||||
* \email: contact@openairinterface.org, rsilva@allbesmart.pt
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#ifdef ENABLE_AERIAL
|
||||
#ifndef OPENAIRINTERFACE_FAPI_VNF_P5_H
|
||||
#define OPENAIRINTERFACE_FAPI_VNF_P5_H
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
#include "nfapi_vnf_interface.h"
|
||||
#include "nfapi_vnf.h"
|
||||
#include "nfapi.h"
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
#include "fapi_nvIPC.h"
|
||||
|
||||
#include "PHY/defs_eNB.h"
|
||||
#include "PHY/LTE_TRANSPORT/transport_proto.h"
|
||||
|
||||
#include "common/ran_context.h"
|
||||
#include "openair2/PHY_INTERFACE/queue_t.h"
|
||||
#include "gnb_ind_vars.h"
|
||||
#include "nfapi/open-nFAPI/vnf/inc/vnf.h"
|
||||
|
||||
void aerial_configure_nr_fapi_vnf();
|
||||
int aerial_nr_send_config_request(nfapi_vnf_config_t *config, int p5_idx);
|
||||
int oai_fapi_send_end_request(int cell_id, uint32_t frame, uint32_t slot);
|
||||
uint8_t aerial_unpack_nr_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config);
|
||||
uint8_t aerial_unpack_nr_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config);
|
||||
int aerial_pnf_nr_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx);
|
||||
int aerial_nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t *config);
|
||||
int fapi_nr_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t* config);
|
||||
|
||||
int oai_fapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req);
|
||||
int oai_fapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req);
|
||||
int oai_fapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req);
|
||||
int oai_fapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req);
|
||||
#endif //OPENAIRINTERFACE_FAPI_VNF_P5_H
|
||||
#endif
|
||||
1315
nfapi/oai_integration/aerial/fapi_vnf_p7.c
Normal file
1315
nfapi/oai_integration/aerial/fapi_vnf_p7.c
Normal file
File diff suppressed because it is too large
Load Diff
243
nfapi/oai_integration/aerial/fapi_vnf_p7.h
Normal file
243
nfapi/oai_integration/aerial/fapi_vnf_p7.h
Normal file
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*! \file fapi/oai-integration/fapi_vnf_p7.h
|
||||
* \brief Header file for fapi_vnf_p7.c
|
||||
* \author Ruben S. Silva
|
||||
* \date 2023
|
||||
* \version 0.1
|
||||
* \company OpenAirInterface Software Alliance
|
||||
* \email: contact@openairinterface.org, rsilva@allbesmart.pt
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#ifdef ENABLE_AERIAL
|
||||
#ifndef OPENAIRINTERFACE_FAPI_VNF_P7_H
|
||||
#define OPENAIRINTERFACE_FAPI_VNF_P7_H
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
#include "nfapi_vnf_interface.h"
|
||||
#include "nfapi_vnf.h"
|
||||
#include "nfapi.h"
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
#include "fapi_nvIPC.h"
|
||||
|
||||
#include "PHY/defs_eNB.h"
|
||||
#include "PHY/LTE_TRANSPORT/transport_proto.h"
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
|
||||
#include "lte-softmodem.h"
|
||||
|
||||
#include "common/ran_context.h"
|
||||
#include "openair2/PHY_INTERFACE/queue_t.h"
|
||||
#include "gnb_ind_vars.h"
|
||||
#include "nfapi/open-nFAPI/vnf/inc/vnf.h"
|
||||
#include "nfapi/open-nFAPI/vnf/inc/vnf_p7.h"
|
||||
typedef struct {
|
||||
uint8_t enabled;
|
||||
uint32_t rx_port;
|
||||
uint32_t tx_port;
|
||||
char tx_addr[80];
|
||||
} udp_data;
|
||||
|
||||
typedef struct {
|
||||
uint16_t index;
|
||||
uint16_t id;
|
||||
uint8_t rfs[2];
|
||||
uint8_t excluded_rfs[2];
|
||||
|
||||
udp_data udp;
|
||||
|
||||
char local_addr[80];
|
||||
int local_port;
|
||||
|
||||
char *remote_addr;
|
||||
int remote_port;
|
||||
|
||||
uint8_t duplex_mode;
|
||||
uint16_t dl_channel_bw_support;
|
||||
uint16_t ul_channel_bw_support;
|
||||
uint8_t num_dl_layers_supported;
|
||||
uint8_t num_ul_layers_supported;
|
||||
uint16_t release_supported;
|
||||
uint8_t nmm_modes_supported;
|
||||
|
||||
uint8_t dl_ues_per_subframe;
|
||||
uint8_t ul_ues_per_subframe;
|
||||
|
||||
uint8_t first_subframe_ind;
|
||||
|
||||
// timing information recevied from the vnf
|
||||
uint8_t timing_window;
|
||||
uint8_t timing_info_mode;
|
||||
uint8_t timing_info_period;
|
||||
|
||||
} phy_info;
|
||||
|
||||
typedef struct {
|
||||
uint16_t index;
|
||||
uint16_t band;
|
||||
int16_t max_transmit_power;
|
||||
int16_t min_transmit_power;
|
||||
uint8_t num_antennas_supported;
|
||||
uint32_t min_downlink_frequency;
|
||||
uint32_t max_downlink_frequency;
|
||||
uint32_t max_uplink_frequency;
|
||||
uint32_t min_uplink_frequency;
|
||||
} rf_info;
|
||||
|
||||
typedef struct {
|
||||
int release;
|
||||
phy_info phys[2];
|
||||
rf_info rfs[2];
|
||||
|
||||
uint8_t sync_mode;
|
||||
uint8_t location_mode;
|
||||
uint8_t location_coordinates[6];
|
||||
uint32_t dl_config_timing;
|
||||
uint32_t ul_config_timing;
|
||||
uint32_t tx_timing;
|
||||
uint32_t hi_dci0_timing;
|
||||
|
||||
uint16_t max_phys;
|
||||
uint16_t max_total_bw;
|
||||
uint16_t max_total_dl_layers;
|
||||
uint16_t max_total_ul_layers;
|
||||
uint8_t shared_bands;
|
||||
uint8_t shared_pa;
|
||||
int16_t max_total_power;
|
||||
uint8_t oui;
|
||||
|
||||
uint8_t wireshark_test_mode;
|
||||
|
||||
} pnf_info;
|
||||
|
||||
typedef struct mac mac_t;
|
||||
typedef struct mac {
|
||||
void *user_data;
|
||||
|
||||
void (*dl_config_req)(mac_t *mac, nfapi_dl_config_request_t *req);
|
||||
void (*ul_config_req)(mac_t *mac, nfapi_ul_config_request_t *req);
|
||||
void (*hi_dci0_req)(mac_t *mac, nfapi_hi_dci0_request_t *req);
|
||||
void (*tx_req)(mac_t *mac, nfapi_tx_request_t *req);
|
||||
} mac_t;
|
||||
|
||||
typedef struct {
|
||||
int local_port;
|
||||
char local_addr[80];
|
||||
|
||||
unsigned timing_window;
|
||||
unsigned periodic_timing_enabled;
|
||||
unsigned aperiodic_timing_enabled;
|
||||
unsigned periodic_timing_period;
|
||||
|
||||
// This is not really the right place if we have multiple PHY,
|
||||
// should be part of the phy struct
|
||||
udp_data udp;
|
||||
|
||||
uint8_t thread_started;
|
||||
|
||||
nfapi_vnf_p7_config_t *config;
|
||||
|
||||
mac_t *mac;
|
||||
|
||||
} vnf_p7_info;
|
||||
|
||||
typedef struct {
|
||||
uint8_t wireshark_test_mode;
|
||||
pnf_info pnfs[2];
|
||||
vnf_p7_info p7_vnfs[2];
|
||||
|
||||
} vnf_info;
|
||||
|
||||
int aerial_wake_gNB_rxtx(PHY_VARS_gNB *gNB, uint16_t sfn, uint16_t slot);
|
||||
int aerial_wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf);
|
||||
int aerial_phy_sync_indication(struct nfapi_vnf_p7_config *config, uint8_t sync);
|
||||
int aerial_phy_slot_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, uint16_t sfn, uint16_t slot);
|
||||
int aerial_phy_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_harq_indication_t *ind);
|
||||
int aerial_phy_nr_crc_indication(nfapi_nr_crc_indication_t *ind);
|
||||
int aerial_phy_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind);
|
||||
int aerial_phy_nr_rach_indication(nfapi_nr_rach_indication_t *ind);
|
||||
int aerial_phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind);
|
||||
int aerial_phy_srs_indication(struct nfapi_vnf_p7_config *config, nfapi_srs_indication_t *ind);
|
||||
int aerial_phy_sr_indication(struct nfapi_vnf_p7_config *config, nfapi_sr_indication_t *ind);
|
||||
int aerial_phy_cqi_indication(struct nfapi_vnf_p7_config *config, nfapi_cqi_indication_t *ind);
|
||||
int aerial_phy_lbt_dl_indication(struct nfapi_vnf_p7_config *config, nfapi_lbt_dl_indication_t *ind);
|
||||
int aerial_phy_nb_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_nb_harq_indication_t *ind);
|
||||
int aerial_phy_nrach_indication(struct nfapi_vnf_p7_config *config, nfapi_nrach_indication_t *ind);
|
||||
int aerial_phy_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind);
|
||||
int aerial_phy_nr_srs_indication(nfapi_nr_srs_indication_t *ind);
|
||||
void *aerial_vnf_allocate(size_t size);
|
||||
void aerial_vnf_deallocate(void *ptr);
|
||||
int aerial_phy_vendor_ext(struct nfapi_vnf_p7_config *config, nfapi_p7_message_header_t *msg);
|
||||
int aerial_phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t *header,
|
||||
uint8_t **ppReadPackedMessage,
|
||||
uint8_t *end,
|
||||
nfapi_p7_codec_config_t *config);
|
||||
int aerial_phy_pack_p7_vendor_extension(nfapi_p7_message_header_t *header,
|
||||
uint8_t **ppWritePackedMsg,
|
||||
uint8_t *end,
|
||||
nfapi_p7_codec_config_t *config);
|
||||
int aerial_phy_unpack_vendor_extension_tlv(nfapi_tl_t *tl,
|
||||
uint8_t **ppReadPackedMessage,
|
||||
uint8_t *end,
|
||||
void **ve,
|
||||
nfapi_p7_codec_config_t *codec);
|
||||
int aerial_phy_pack_vendor_extension_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *codec);
|
||||
nfapi_p7_message_header_t *aerial_phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t *msg_size);
|
||||
void aerial_phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t *header);
|
||||
|
||||
uint8_t aerial_unpack_nr_slot_indication(uint8_t **ppReadPackedMsg,
|
||||
uint8_t *end,
|
||||
nfapi_nr_slot_indication_scf_t *msg,
|
||||
nfapi_p7_codec_config_t *config);
|
||||
uint8_t aerial_unpack_nr_rx_data_indication(uint8_t **ppReadPackedMsg,
|
||||
uint8_t *end,
|
||||
uint8_t **pDataMsg,
|
||||
uint8_t *data_end,
|
||||
nfapi_nr_rx_data_indication_t *msg,
|
||||
nfapi_p7_codec_config_t *config);
|
||||
uint8_t aerial_unpack_nr_crc_indication(uint8_t **ppReadPackedMsg,
|
||||
uint8_t *end,
|
||||
nfapi_nr_crc_indication_t *msg,
|
||||
nfapi_p7_codec_config_t *config);
|
||||
uint8_t aerial_unpack_nr_uci_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
|
||||
uint8_t aerial_unpack_nr_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
|
||||
uint8_t aerial_unpack_nr_rach_indication(uint8_t **ppReadPackedMsg,
|
||||
uint8_t *end,
|
||||
nfapi_nr_rach_indication_t *msg,
|
||||
nfapi_p7_codec_config_t *config);
|
||||
|
||||
// int fapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config);
|
||||
int fapi_nr_pack_and_send_p7_message(vnf_p7_t *vnf_p7, nfapi_p7_message_header_t *header);
|
||||
#endif // OPENAIRINTERFACE_FAPI_VNF_P7_H
|
||||
#endif
|
||||
@@ -27,6 +27,7 @@ static const char *const nfapi_str_mode[] = {
|
||||
"MONOLITHIC",
|
||||
"PNF",
|
||||
"VNF",
|
||||
"AERIAL",
|
||||
"UE_STUB_PNF",
|
||||
"UE_STUB_OFFNET",
|
||||
"STANDALONE_PNF",
|
||||
@@ -64,7 +65,7 @@ const char *nfapi_get_strmode(void) {
|
||||
}
|
||||
|
||||
void nfapi_logmode() {
|
||||
LOG_I(ENB_APP,"nfapi running mode: %s\n",nfapi_get_strmode());
|
||||
LOG_I(ENB_APP,"nfapi (%d) running mode: %s\n",nfapi_params.nfapi_mode,nfapi_get_strmode());
|
||||
}
|
||||
|
||||
nfapi_mode_t nfapi_getmode(void) {
|
||||
|
||||
@@ -68,6 +68,7 @@ typedef enum {
|
||||
NFAPI_MONOLITHIC=0,
|
||||
NFAPI_MODE_PNF,
|
||||
NFAPI_MODE_VNF,
|
||||
NFAPI_MODE_AERIAL,
|
||||
NFAPI_UE_STUB_PNF,
|
||||
NFAPI_UE_STUB_OFFNET,
|
||||
NFAPI_MODE_STANDALONE_PNF,
|
||||
|
||||
@@ -328,6 +328,7 @@ typedef struct
|
||||
#define NFAPI_NR_CONFIG_SLOT_CONFIG_TAG 0x1027
|
||||
|
||||
#define NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG 0x1028
|
||||
#define NFAPI_NR_CONFIG_TDD_TABLE 0x1035
|
||||
|
||||
//table 3-21
|
||||
typedef struct
|
||||
@@ -1467,11 +1468,9 @@ typedef enum {
|
||||
|
||||
//table 3-58
|
||||
#define NFAPI_NR_MAX_TX_REQUEST_TLV 2
|
||||
typedef struct {
|
||||
uint16_t PDU_length; // SCF 222.10.02 The total length (in bytes) of the PDU description and PDU data, without the padding bytes.
|
||||
// (2 bytes PDU_Length + 2 bytes PDU_Index + 4 bytes num_TLV + TLV size ( 2 bytes tag + 2 bytes length +
|
||||
// value size without padding))
|
||||
// TBS + 12
|
||||
typedef struct
|
||||
{
|
||||
uint32_t PDU_length;
|
||||
uint16_t PDU_index;
|
||||
uint32_t num_TLV;
|
||||
nfapi_nr_tx_data_request_tlv_t TLVs[NFAPI_NR_MAX_TX_REQUEST_TLV];
|
||||
@@ -1505,7 +1504,7 @@ typedef struct
|
||||
uint32_t handle;
|
||||
uint16_t rnti;
|
||||
uint8_t harq_id;
|
||||
uint16_t pdu_length;
|
||||
uint32_t pdu_length;// For Aerial, RX_DATA.indication PDULength is changed to 32 bit field
|
||||
uint8_t ul_cqi;
|
||||
uint16_t timing_advance;//Timing advance 𝑇𝐴 measured for the UE [TS 38.213, Section 4.2] NTA_new = NTA_old + (TA − 31) ⋅ 16 ⋅ 64⁄2μ Value: 0 → 63 0xffff should be set if this field is invalid
|
||||
uint16_t rssi;
|
||||
|
||||
@@ -102,8 +102,13 @@ uint8_t push16(uint16_t in, uint8_t **out, uint8_t *end) {
|
||||
uint8_t *pOut = *out;
|
||||
|
||||
if((end - pOut) >= 2) {
|
||||
#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN
|
||||
pOut[1] = (in & 0xFF00) >> 8;
|
||||
pOut[0] = (in & 0xFF);
|
||||
#else
|
||||
pOut[0] = (in & 0xFF00) >> 8;
|
||||
pOut[1] = (in & 0xFF);
|
||||
#endif
|
||||
(*out)+=2;
|
||||
return 2;
|
||||
} else {
|
||||
@@ -117,8 +122,13 @@ uint8_t pushs16(int16_t in, uint8_t **out, uint8_t *end) {
|
||||
uint8_t *pOut = *out;
|
||||
|
||||
if((end - pOut) >= 2) {
|
||||
#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN
|
||||
pOut[1] = (in & 0xFF00) >> 8;
|
||||
pOut[0] = (in & 0xFF);
|
||||
#else
|
||||
pOut[0] = (in & 0xFF00) >> 8;
|
||||
pOut[1] = (in & 0xFF);
|
||||
#endif
|
||||
(*out)+=2;
|
||||
return 2;
|
||||
} else {
|
||||
@@ -132,10 +142,17 @@ uint8_t push32(uint32_t in, uint8_t **out, uint8_t *end) {
|
||||
uint8_t *pOut = *out;
|
||||
|
||||
if((end - pOut) >= 4) {
|
||||
#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN
|
||||
pOut[3] = (in & 0xFF000000) >> 24;
|
||||
pOut[2] = (in & 0xFF0000) >> 16;
|
||||
pOut[1] = (in & 0xFF00) >> 8;
|
||||
pOut[0] = (in & 0xFF);
|
||||
#else
|
||||
pOut[0] = (in & 0xFF000000) >> 24;
|
||||
pOut[1] = (in & 0xFF0000) >> 16;
|
||||
pOut[2] = (in & 0xFF00) >> 8;
|
||||
pOut[3] = (in & 0xFF);
|
||||
#endif
|
||||
(*out)+=4;
|
||||
return 4;
|
||||
} else {
|
||||
@@ -149,10 +166,17 @@ uint8_t pushs32(int32_t in, uint8_t **out, uint8_t *end) {
|
||||
uint8_t *pOut = *out;
|
||||
|
||||
if((end - pOut) >= 4) {
|
||||
#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN
|
||||
pOut[3] = (in & 0xFF000000) >> 24;
|
||||
pOut[2] = (in & 0xFF0000) >> 16;
|
||||
pOut[1] = (in & 0xFF00) >> 8;
|
||||
pOut[0] = (in & 0xFF);
|
||||
#else
|
||||
pOut[0] = (in & 0xFF000000) >> 24;
|
||||
pOut[1] = (in & 0xFF0000) >> 16;
|
||||
pOut[2] = (in & 0xFF00) >> 8;
|
||||
pOut[3] = (in & 0xFF);
|
||||
#endif
|
||||
(*out)+=4;
|
||||
return 4;
|
||||
} else {
|
||||
@@ -194,7 +218,11 @@ uint8_t pull16(uint8_t **in, uint16_t *out, uint8_t *end) {
|
||||
uint8_t *pIn = *in;
|
||||
|
||||
if((end - pIn) >=2 ) {
|
||||
#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN
|
||||
*out = ((pIn[1]) << 8) | pIn[0];
|
||||
#else
|
||||
*out = ((pIn[0]) << 8) | pIn[1];
|
||||
#endif
|
||||
(*in)+=2;
|
||||
return 2;
|
||||
} else {
|
||||
@@ -208,7 +236,11 @@ uint8_t pulls16(uint8_t **in, int16_t *out, uint8_t *end) {
|
||||
uint8_t *pIn = *in;
|
||||
|
||||
if((end - pIn) >=2 ) {
|
||||
#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN
|
||||
*out = ((pIn[1]) << 8) | pIn[0];
|
||||
#else
|
||||
*out = ((pIn[0]) << 8) | pIn[1];
|
||||
#endif
|
||||
(*in)+=2;
|
||||
return 2;
|
||||
} else {
|
||||
@@ -222,7 +254,11 @@ uint8_t pull32(uint8_t **in, uint32_t *out, uint8_t *end) {
|
||||
uint8_t *pIn = *in;
|
||||
|
||||
if((end - pIn) >= 4) {
|
||||
#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN
|
||||
*out = ((uint32_t)pIn[3] << 24) | (pIn[2] << 16) | (pIn[1] << 8) | pIn[0];
|
||||
#else
|
||||
*out = ((uint32_t)pIn[0] << 24) | (pIn[1] << 16) | (pIn[2] << 8) | pIn[3];
|
||||
#endif
|
||||
(*in) += 4;
|
||||
return 4;
|
||||
} else {
|
||||
@@ -236,7 +272,11 @@ uint8_t pulls32(uint8_t **in, int32_t *out, uint8_t *end) {
|
||||
uint8_t *pIn = *in;
|
||||
|
||||
if((end - pIn) >=4 ) {
|
||||
#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN
|
||||
*out = (pIn[3] << 24) | (pIn[2] << 16) | (pIn[1] << 8) | pIn[0];
|
||||
#else
|
||||
*out = (pIn[0] << 24) | (pIn[1] << 16) | (pIn[2] << 8) | pIn[3];
|
||||
#endif
|
||||
(*in)+=4;
|
||||
return 4;
|
||||
} else {
|
||||
@@ -839,7 +879,6 @@ int unpack_nr_tlv_list(unpack_tlv_t unpack_fns[],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <nfapi.h>
|
||||
#include "nfapi_nr_interface.h"
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
@@ -1670,6 +1671,16 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin
|
||||
end,
|
||||
&pack_uint16_tlv_value);
|
||||
numTLVs++;
|
||||
|
||||
if (NFAPI_MODE != NFAPI_MODE_AERIAL) {
|
||||
// TLV not supported by Aerial L1
|
||||
pack_nr_tlv(NFAPI_NR_CONFIG_FREQUENCY_SHIFT_7P5KHZ_TAG,
|
||||
&(pNfapiMsg->carrier_config.frequency_shift_7p5khz),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
}
|
||||
// END Carrier Configuration
|
||||
|
||||
// START Cell Configuration
|
||||
@@ -1695,13 +1706,15 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin
|
||||
end,
|
||||
&pack_uint32_tlv_value);
|
||||
numTLVs++;
|
||||
|
||||
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_BCH_PAYLOAD_TAG,
|
||||
&(pNfapiMsg->ssb_config.bch_payload),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
if (NFAPI_MODE != NFAPI_MODE_AERIAL) {
|
||||
// TLV not supported by Aerial L1
|
||||
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_BCH_PAYLOAD_TAG,
|
||||
&(pNfapiMsg->ssb_config.bch_payload),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
}
|
||||
|
||||
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SCS_COMMON_TAG,
|
||||
&(pNfapiMsg->ssb_config.scs_common),
|
||||
@@ -1780,6 +1793,16 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin
|
||||
end,
|
||||
&pack_uint16_tlv_value);
|
||||
numTLVs++;
|
||||
for (int k = 0; k < prach_fd_occasion.num_unused_root_sequences.value; k++) {
|
||||
prach_fd_occasion.unused_root_sequences_list[k].tl.tag = NFAPI_NR_CONFIG_UNUSED_ROOT_SEQUENCES_TAG;
|
||||
prach_fd_occasion.unused_root_sequences_list[k].value = 0;
|
||||
pack_nr_tlv(NFAPI_NR_CONFIG_UNUSED_ROOT_SEQUENCES_TAG,
|
||||
&(prach_fd_occasion.unused_root_sequences_list[k]),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint16_tlv_value);
|
||||
numTLVs++;
|
||||
}
|
||||
}
|
||||
|
||||
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SSB_PER_RACH_TAG,
|
||||
@@ -1788,15 +1811,25 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
pNfapiMsg->prach_config.prach_multiple_carriers_in_a_band.tl.tag = NFAPI_NR_CONFIG_PRACH_MULTIPLE_CARRIERS_IN_A_BAND_TAG;
|
||||
pNfapiMsg->prach_config.prach_multiple_carriers_in_a_band.value = 0;
|
||||
pack_nr_tlv(NFAPI_NR_CONFIG_PRACH_MULTIPLE_CARRIERS_IN_A_BAND_TAG,
|
||||
&(pNfapiMsg->prach_config.prach_multiple_carriers_in_a_band),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
// END PRACH Configuration
|
||||
// START SSB Table
|
||||
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG,
|
||||
&(pNfapiMsg->ssb_table.ssb_offset_point_a),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint16_tlv_value);
|
||||
numTLVs++;
|
||||
|
||||
if (NFAPI_MODE != NFAPI_MODE_AERIAL) {
|
||||
// TLV not supported by Aerial L1
|
||||
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG,
|
||||
&(pNfapiMsg->ssb_table.ssb_offset_point_a),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint16_tlv_value);
|
||||
numTLVs++;
|
||||
}
|
||||
retval &=
|
||||
pack_nr_tlv(NFAPI_NR_CONFIG_SSB_PERIOD_TAG, &(pNfapiMsg->ssb_table.ssb_period), ppWritePackedMsg, end, &pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
@@ -1807,7 +1840,10 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
|
||||
/* was unused */
|
||||
pNfapiMsg->ssb_table.MIB.tl.tag = NFAPI_NR_CONFIG_MIB_TAG;
|
||||
pack_nr_tlv(NFAPI_NR_CONFIG_MIB_TAG, &(pNfapiMsg->ssb_table.MIB), ppWritePackedMsg, end, &pack_uint32_tlv_value);
|
||||
numTLVs++;
|
||||
// SCF222.10.02 Table 3-25 : If included there must be two instances of this TLV
|
||||
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SSB_MASK_TAG,
|
||||
&(pNfapiMsg->ssb_table.ssb_mask_list[0].ssb_mask),
|
||||
@@ -1822,26 +1858,48 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin
|
||||
end,
|
||||
&pack_uint32_tlv_value);
|
||||
numTLVs++;
|
||||
if (NFAPI_MODE != NFAPI_MODE_AERIAL) {
|
||||
// TLV not supported by Aerial L1
|
||||
for (int i = 0; i < 64; i++) {
|
||||
// SCF222.10.02 Table 3-25 : If included there must be 64 instances of this TLV
|
||||
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_BEAM_ID_TAG,
|
||||
&(pNfapiMsg->ssb_table.ssb_beam_id_list[i].beam_id),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 64; i++) {
|
||||
// SCF222.10.02 Table 3-25 : If included there must be 64 instances of this TLV
|
||||
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_BEAM_ID_TAG,
|
||||
&(pNfapiMsg->ssb_table.ssb_beam_id_list[i].beam_id),
|
||||
// END SSB Table
|
||||
// START TDD Table
|
||||
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_TDD_PERIOD_TAG,
|
||||
&(pNfapiMsg->tdd_table.tdd_period),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
// END TDD Table
|
||||
for (int i = 0; i < 40; i++) {
|
||||
for (int k = 0; k < 14; k++) {
|
||||
pack_nr_tlv(NFAPI_NR_CONFIG_SLOT_CONFIG_TAG,
|
||||
&(pNfapiMsg->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// END SSB Table
|
||||
// START TDD Table
|
||||
retval &=
|
||||
pack_nr_tlv(NFAPI_NR_CONFIG_TDD_PERIOD_TAG, &(pNfapiMsg->tdd_table.tdd_period), ppWritePackedMsg, end, &pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
// END TDD Table
|
||||
|
||||
// START Measurement Config
|
||||
// SCF222.10.02 Table 3-27 : Contains only one TLV and is currently unused
|
||||
pNfapiMsg->measurement_config.rssi_measurement.tl.tag = NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG;
|
||||
pNfapiMsg->measurement_config.rssi_measurement.value = 1;
|
||||
pack_nr_tlv(NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG,
|
||||
&(pNfapiMsg->measurement_config.rssi_measurement),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
// END Measurement Config
|
||||
|
||||
// START Digital Beam Table (DBT) PDU
|
||||
@@ -1851,57 +1909,57 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin
|
||||
// START Precoding Matrix (PM) PDU
|
||||
// Struct in nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h nfapi_nr_pm_pdu_t, currently unused, tag to use for AERIAL
|
||||
// is 0xA011 END Precoding Matrix (PM) PDU
|
||||
|
||||
// START nFAPI TLVs included in CONFIG.request for IDLE and CONFIGURED states
|
||||
retval &= pack_nr_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG,
|
||||
&(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_ipv4_address_value);
|
||||
numTLVs++;
|
||||
|
||||
retval &= pack_nr_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG,
|
||||
&(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_ipv6_address_value);
|
||||
numTLVs++;
|
||||
|
||||
retval &= pack_nr_tlv(NFAPI_NR_NFAPI_P7_VNF_PORT_TAG,
|
||||
&(pNfapiMsg->nfapi_config.p7_vnf_port),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint16_tlv_value);
|
||||
numTLVs++;
|
||||
|
||||
retval &= pack_nr_tlv(NFAPI_NR_NFAPI_TIMING_WINDOW_TAG,
|
||||
&(pNfapiMsg->nfapi_config.timing_window),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
|
||||
retval &= pack_nr_tlv(NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG,
|
||||
&(pNfapiMsg->nfapi_config.timing_info_mode),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
|
||||
retval &= pack_nr_tlv(NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG,
|
||||
&(pNfapiMsg->nfapi_config.timing_info_period),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
// END nFAPI TLVs included in CONFIG.request for IDLE and CONFIGURED states
|
||||
|
||||
if (pNfapiMsg->vendor_extension != 0 && config != 0) {
|
||||
retval &= pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
|
||||
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Packing CONFIG.request vendor_extension_tlv %d\n", pNfapiMsg->vendor_extension->tag);
|
||||
if(NFAPI_MODE != NFAPI_MODE_AERIAL){
|
||||
// START nFAPI TLVs included in CONFIG.request for IDLE and CONFIGURED states
|
||||
retval &= pack_nr_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG,
|
||||
&(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_ipv4_address_value);
|
||||
numTLVs++;
|
||||
}
|
||||
|
||||
retval &= pack_nr_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG,
|
||||
&(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_ipv6_address_value);
|
||||
numTLVs++;
|
||||
|
||||
retval &= pack_nr_tlv(NFAPI_NR_NFAPI_P7_VNF_PORT_TAG,
|
||||
&(pNfapiMsg->nfapi_config.p7_vnf_port),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint16_tlv_value);
|
||||
numTLVs++;
|
||||
|
||||
retval &= pack_nr_tlv(NFAPI_NR_NFAPI_TIMING_WINDOW_TAG,
|
||||
&(pNfapiMsg->nfapi_config.timing_window),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
|
||||
retval &= pack_nr_tlv(NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG,
|
||||
&(pNfapiMsg->nfapi_config.timing_info_mode),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
|
||||
retval &= pack_nr_tlv(NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG,
|
||||
&(pNfapiMsg->nfapi_config.timing_info_period),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
// END nFAPI TLVs included in CONFIG.request for IDLE and CONFIGURED states
|
||||
|
||||
if (pNfapiMsg->vendor_extension != 0 && config != 0) {
|
||||
retval &= pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
|
||||
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Packing CONFIG.request vendor_extension_tlv %d\n", pNfapiMsg->vendor_extension->tag);
|
||||
numTLVs++;
|
||||
}
|
||||
}
|
||||
pNfapiMsg->num_tlv = numTLVs;
|
||||
retval &= push8(pNfapiMsg->num_tlv, &pNumTLVFields, end);
|
||||
return retval;
|
||||
@@ -2170,7 +2228,7 @@ static uint8_t pack_p5_message_body(nfapi_p4_p5_message_header_t *header, uint8_
|
||||
|
||||
static uint32_t get_packed_msg_len(uintptr_t msgHead, uintptr_t msgEnd) {
|
||||
if (msgEnd < msgHead) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "get_packed_msg_len: Error in pointers supplied %lu, %lu\n", msgHead, msgEnd);
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "get_packed_msg_len: Error in pointers supplied %p, %p\n", &msgHead, &msgEnd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2178,6 +2236,7 @@ static uint32_t get_packed_msg_len(uintptr_t msgHead, uintptr_t msgEnd) {
|
||||
}
|
||||
|
||||
// Main pack function - public
|
||||
|
||||
int nfapi_nr_p5_message_pack(void *pMessageBuf,
|
||||
uint32_t messageBufLen,
|
||||
void *pPackedBuf,
|
||||
|
||||
@@ -328,8 +328,8 @@ static uint8_t pack_dl_tti_pdsch_pdu_rel15_value(void *tlv, uint8_t **ppWritePac
|
||||
}
|
||||
// TODO Add TX power info
|
||||
// Hardcoded values that represent 0db
|
||||
if (!(push8(8, ppWritePackedMsg, end) && // powerControlOffset
|
||||
push8(1, ppWritePackedMsg, end))) { // powerControlOffsetSS
|
||||
if (!(push8(0, ppWritePackedMsg, end) && // powerControlOffset
|
||||
push8(0, ppWritePackedMsg, end))) { // powerControlOffsetSS
|
||||
return 0;
|
||||
}
|
||||
// TODO Add CBG Fields
|
||||
@@ -346,9 +346,8 @@ static uint8_t pack_dl_tti_ssb_pdu_rel15_value(void *tlv, uint8_t **ppWritePacke
|
||||
&& push16(value->ssbOffsetPointA, ppWritePackedMsg, end) && push8(value->bchPayloadFlag, ppWritePackedMsg, end)
|
||||
&& push8((value->bchPayload >> 16) & 0xff, ppWritePackedMsg, end)
|
||||
&& push8((value->bchPayload >> 8) & 0xff, ppWritePackedMsg, end) && push8(value->bchPayload & 0xff, ppWritePackedMsg, end)
|
||||
&& push8(0, ppWritePackedMsg, end) &&
|
||||
&& push8(0, ppWritePackedMsg, end)
|
||||
// TODO add Tx Power Info
|
||||
push8(0, ppWritePackedMsg, end) && push8(0, ppWritePackedMsg, end)
|
||||
&& push16(value->precoding_and_beamforming.num_prgs, ppWritePackedMsg, end)
|
||||
&& push16(value->precoding_and_beamforming.prg_size, ppWritePackedMsg, end)
|
||||
&& push8(value->precoding_and_beamforming.dig_bf_interfaces, ppWritePackedMsg, end))) {
|
||||
@@ -1092,7 +1091,7 @@ static uint8_t pack_ul_tti_request_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, ui
|
||||
}
|
||||
|
||||
static uint8_t pack_ul_tti_request_srs_pdu(nfapi_nr_srs_pdu_t *srs_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) {
|
||||
return(
|
||||
if(!(
|
||||
push16(srs_pdu->rnti, ppWritePackedMsg, end) &&
|
||||
push32(srs_pdu->handle, ppWritePackedMsg, end) &&
|
||||
push16(srs_pdu->bwp_size, ppWritePackedMsg, end) &&
|
||||
@@ -1117,7 +1116,23 @@ static uint8_t pack_ul_tti_request_srs_pdu(nfapi_nr_srs_pdu_t *srs_pdu, uint8_t
|
||||
push16(srs_pdu->t_srs, ppWritePackedMsg, end) &&
|
||||
push16(srs_pdu->t_offset, ppWritePackedMsg, end)
|
||||
// TODO: ignoring beamforming tlv for now
|
||||
);
|
||||
)){
|
||||
return 0;
|
||||
}
|
||||
// Rx Beamforming PDU
|
||||
if(!(push16(srs_pdu->beamforming.num_prgs,ppWritePackedMsg,end) &&
|
||||
push16(srs_pdu->beamforming.prg_size,ppWritePackedMsg,end) &&
|
||||
push8(srs_pdu->beamforming.dig_bf_interface,ppWritePackedMsg,end))){
|
||||
return 0;
|
||||
}
|
||||
for(int prg = 0; prg < srs_pdu->beamforming.num_prgs; prg ++){
|
||||
for(int digInt = 0; digInt < srs_pdu->beamforming.dig_bf_interface; digInt++){
|
||||
if(!push16(srs_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx,ppWritePackedMsg,end)){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint8_t pack_ul_config_request_ulsch_pdu(nfapi_ul_config_ulsch_pdu *ulsch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) {
|
||||
@@ -2002,6 +2017,7 @@ static uint8_t pack_hi_dci0_request(void *msg, uint8_t **ppWritePackedMsg, uint8
|
||||
static uint8_t pack_tx_data_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
|
||||
{
|
||||
nfapi_nr_pdu_t *value = (nfapi_nr_pdu_t *)tlv;
|
||||
AssertFatal(value->PDU_length <= 0xFFFF,"TX_DATA.request PDU_Length should be within 16 bit, according to SCF222.10.02");
|
||||
if (!(push16(value->PDU_length, ppWritePackedMsg, end) && push16(value->PDU_index, ppWritePackedMsg, end)
|
||||
&& push32(value->num_TLV, ppWritePackedMsg, end)))
|
||||
return 0;
|
||||
@@ -3153,6 +3169,7 @@ return 1;
|
||||
|
||||
static uint8_t pack_nr_rx_data_indication_body(nfapi_nr_rx_data_pdu_t *value, uint8_t **ppWritePackedMsg, uint8_t *end)
|
||||
{
|
||||
AssertFatal(value->pdu_length <= 0xFFFF,"RX_DATA.indication PDU_Length should be within 16 bit, according to SCF222.10.02");
|
||||
if(!(push32(value->handle, ppWritePackedMsg, end) &&
|
||||
push16(value->rnti, ppWritePackedMsg, end) &&
|
||||
push8(value->harq_id, ppWritePackedMsg, end) &&
|
||||
@@ -5886,7 +5903,7 @@ static uint8_t unpack_hi_dci0_request(uint8_t **ppReadPackedMsg, uint8_t *end, v
|
||||
static uint8_t unpack_tx_data_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg) {
|
||||
nfapi_nr_pdu_t *pNfapiMsg = (nfapi_nr_pdu_t *)msg;
|
||||
|
||||
if(!(pull16(ppReadPackedMsg, &pNfapiMsg->PDU_length, end) &&
|
||||
if(!(pull16(ppReadPackedMsg, (uint16_t *)&pNfapiMsg->PDU_length, end) &&
|
||||
pull16(ppReadPackedMsg, &pNfapiMsg->PDU_index, end) &&
|
||||
pull32(ppReadPackedMsg, &pNfapiMsg->num_TLV, end)
|
||||
))
|
||||
@@ -5939,13 +5956,6 @@ static uint8_t unpack_tx_data_request(uint8_t **ppReadPackedMsg, uint8_t *end, v
|
||||
|
||||
for (int i = 0; i < pNfapiMsg->Number_of_PDUs; i++) {
|
||||
if (!unpack_tx_data_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->pdu_list[i])) {
|
||||
printf("%s():%d. Error packing TX_DATA.request PDU #%d, PDU length = %d PDU IDX = %d\n",
|
||||
__FUNCTION__,
|
||||
__LINE__,
|
||||
i,
|
||||
pNfapiMsg->pdu_list[i].PDU_length,
|
||||
pNfapiMsg->pdu_list[i].PDU_index);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -6065,7 +6075,7 @@ static uint8_t unpack_nr_rx_data_indication_body(nfapi_nr_rx_data_pdu_t *value,
|
||||
nfapi_p7_codec_config_t *config)
|
||||
{
|
||||
if (!(pull32(ppReadPackedMsg, &value->handle, end) && pull16(ppReadPackedMsg, &value->rnti, end)
|
||||
&& pull8(ppReadPackedMsg, &value->harq_id, end) && pull16(ppReadPackedMsg, &value->pdu_length, end)
|
||||
&& pull8(ppReadPackedMsg, &value->harq_id, end) && pull16(ppReadPackedMsg, (uint16_t *)&value->pdu_length, end)
|
||||
&& pull8(ppReadPackedMsg, &value->ul_cqi, end) && pull16(ppReadPackedMsg, &value->timing_advance, end)
|
||||
&& pull16(ppReadPackedMsg, &value->rssi, end)))
|
||||
return 0;
|
||||
|
||||
@@ -2040,8 +2040,10 @@ int pnf_read_dispatch_message(pnf_t* pnf)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Failed to unpack p5 message header\n");
|
||||
return 0;
|
||||
}
|
||||
message_size = header.message_length;
|
||||
}else{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Unpack p5 message header success\n");
|
||||
}
|
||||
message_size = header.message_length+header_buffer_size;
|
||||
|
||||
// now have the size of the mesage
|
||||
}
|
||||
@@ -2206,7 +2208,7 @@ int pnf_nr_read_dispatch_message(pnf_t* pnf)
|
||||
// print the received message
|
||||
printf("\n MESSAGE RECEIVED: \n");
|
||||
for(int i=0; i<message_size; i++){
|
||||
printf("%d", read_buffer[i]);
|
||||
printf("read_buffer[%d] = 0x%02x\n",i, read_buffer[i]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
@@ -27,7 +27,11 @@
|
||||
#include "vnf.h"
|
||||
#include "nfapi_nr_interface.h"
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
|
||||
#ifdef ENABLE_AERIAL
|
||||
#include "nfapi/oai_integration/aerial/fapi_nvIPC.h"
|
||||
#include "nfapi/oai_integration/aerial/fapi_vnf_p5.h"
|
||||
#endif
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
|
||||
void* vnf_malloc(nfapi_vnf_config_t* config, size_t size)
|
||||
{
|
||||
@@ -1520,20 +1524,45 @@ int vnf_nr_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_mes
|
||||
if(pnf)
|
||||
{
|
||||
// pack the message for transmission
|
||||
int packedMessageLength = nfapi_nr_p5_message_pack(msg, msg_len, vnf->tx_message_buffer, sizeof(vnf->tx_message_buffer), &vnf->_public.codec_config);
|
||||
int packedMessageLength = 0;
|
||||
if (NFAPI_MODE == NFAPI_MODE_AERIAL) {
|
||||
#ifdef ENABLE_AERIAL
|
||||
// In case it is a FAPI message, create 2 messages, one with nFAPI header for OAI PNF and one with no nFAPI header for Aerial
|
||||
// L1
|
||||
nfapi_p4_p5_message_header_t *msgFAPI = calloc(1, msg_len);
|
||||
memcpy(msgFAPI, msg, msg_len);
|
||||
// create FAPI tx_buffer
|
||||
uint8_t tx_messagebufferFAPI[sizeof(vnf->tx_message_buffer)];
|
||||
int packedMessageLengthFAPI = -1;
|
||||
packedMessageLengthFAPI =
|
||||
fapi_nr_p5_message_pack(msgFAPI, msg_len, tx_messagebufferFAPI, sizeof(tx_messagebufferFAPI), &vnf->_public.codec_config);
|
||||
return aerial_send_P5_msg(tx_messagebufferFAPI, packedMessageLengthFAPI, msg);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
} else {
|
||||
packedMessageLength = nfapi_nr_p5_message_pack(msg,
|
||||
msg_len,
|
||||
vnf->tx_message_buffer,
|
||||
sizeof(vnf->tx_message_buffer),
|
||||
&vnf->_public.codec_config);
|
||||
|
||||
if (packedMessageLength < 0) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p5_message_pack failed with return %d\n", packedMessageLength);
|
||||
return -1;
|
||||
}
|
||||
// printf("msg id = 0x%02x, entire message length: %d\n", msg->message_id, packedMessageLength);
|
||||
// for (int i = 0; i < packedMessageLength; i++) {
|
||||
// printf(" msg->msg_buf[%d] = 0x%02x\n", i, ((uint8_t *) vnf->tx_message_buffer)[i]);
|
||||
// }
|
||||
|
||||
return vnf_send_p5_msg(pnf, vnf->tx_message_buffer, packedMessageLength, 0);
|
||||
}
|
||||
} else {
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() cannot find pnf info for p5_idx:%d\n", __FUNCTION__, p5_idx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (packedMessageLength < 0)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p5_message_pack failed with return %d\n", packedMessageLength);
|
||||
return -1;
|
||||
}
|
||||
return vnf_send_p5_msg(pnf, vnf->tx_message_buffer, packedMessageLength, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() cannot find pnf info for p5_idx:%d\n", __FUNCTION__, p5_idx);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -25,7 +25,9 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef ENABLE_AERIAL
|
||||
#include "nfapi/oai_integration/aerial/fapi_nvIPC.h"
|
||||
#endif
|
||||
#include "vnf_p7.h"
|
||||
|
||||
#ifdef NDEBUG
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#ifdef ENABLE_AERIAL
|
||||
#include "nfapi/oai_integration/aerial/fapi_vnf_p5.h"
|
||||
#endif
|
||||
#include "fapi_nr_l1.h"
|
||||
#include "common/ran_context.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
|
||||
@@ -37,7 +40,6 @@
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
#include "openair2/NR_PHY_INTERFACE/nr_sched_response.h"
|
||||
|
||||
|
||||
extern int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req);
|
||||
extern int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req);
|
||||
extern int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req);
|
||||
@@ -237,19 +239,43 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO)
|
||||
}
|
||||
}
|
||||
|
||||
if (NFAPI_MODE == NFAPI_MODE_VNF) { //If VNF, oai_nfapi functions send respective p7 msgs to PNF for which nPDUs is greater than 0
|
||||
if (NFAPI_MODE == NFAPI_MODE_VNF) { // If VNF, oai_nfapi functions send respective p7 msgs to PNF for which nPDUs > 0
|
||||
|
||||
if(number_ul_tti_pdu>0)
|
||||
if (number_ul_tti_pdu > 0)
|
||||
oai_nfapi_ul_tti_req(UL_tti_req);
|
||||
|
||||
if (number_ul_dci_pdu>0)
|
||||
if (number_ul_dci_pdu > 0)
|
||||
oai_nfapi_ul_dci_req(UL_dci_req);
|
||||
|
||||
if (number_tx_data_pdu>0)
|
||||
if (number_dl_pdu > 0)
|
||||
oai_nfapi_dl_tti_req(DL_req);
|
||||
|
||||
if (number_tx_data_pdu > 0)
|
||||
oai_nfapi_tx_data_req(TX_req);
|
||||
|
||||
if (number_dl_pdu>0)
|
||||
oai_nfapi_dl_tti_req(DL_req);
|
||||
} else if (NFAPI_MODE == NFAPI_MODE_AERIAL) {
|
||||
#ifdef ENABLE_AERIAL
|
||||
bool send_slt_resp = false;
|
||||
if (number_dl_pdu > 0) {
|
||||
oai_fapi_dl_tti_req(DL_req);
|
||||
send_slt_resp = true;
|
||||
}
|
||||
if (number_ul_tti_pdu > 0) {
|
||||
oai_fapi_ul_tti_req(UL_tti_req);
|
||||
send_slt_resp = true;
|
||||
}
|
||||
if (number_tx_data_pdu > 0) {
|
||||
oai_fapi_tx_data_req(TX_req);
|
||||
send_slt_resp = true;
|
||||
}
|
||||
if (number_ul_dci_pdu > 0) {
|
||||
oai_fapi_ul_dci_req(UL_dci_req);
|
||||
send_slt_resp = true;
|
||||
}
|
||||
if (send_slt_resp) {
|
||||
oai_fapi_send_end_request(0,frame,slot);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* this thread is done with the sched_info, decrease the reference counter */
|
||||
|
||||
@@ -91,6 +91,9 @@
|
||||
#include "RRC/NR/nr_rrc_extern.h"
|
||||
#include "openair2/LAYER2/nr_pdcp/nr_pdcp.h"
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
#ifdef ENABLE_AERIAL
|
||||
#include "nfapi/oai_integration/aerial/fapi_vnf_p5.h"
|
||||
#endif
|
||||
|
||||
extern uint16_t sf_ahead;
|
||||
|
||||
@@ -1303,6 +1306,11 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
|
||||
configure_nr_nfapi_vnf(
|
||||
RC.nrmac[j]->eth_params_s.my_addr, RC.nrmac[j]->eth_params_s.my_portc, RC.nrmac[j]->eth_params_s.remote_addr, RC.nrmac[j]->eth_params_s.remote_portd, RC.nrmac[j]->eth_params_s.my_portd);
|
||||
printf("**************** RETURNED FROM configure_nfapi_vnf() vnf_port:%d\n", RC.nrmac[j]->eth_params_s.my_portc);
|
||||
} else if(strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr), "aerial") == 0){
|
||||
#ifdef ENABLE_AERIAL
|
||||
printf("Configuring VNF for Aerial connection\n");
|
||||
aerial_configure_nr_fapi_vnf();
|
||||
#endif
|
||||
} else { // other midhaul
|
||||
AssertFatal(1 == 0, "MACRLC %d: %s unknown southbound midhaul\n", j, *(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr));
|
||||
}
|
||||
|
||||
@@ -708,6 +708,12 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant
|
||||
cfg->ssb_table.ssb_subcarrier_offset.tl.tag = NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG;
|
||||
cfg->num_tlv++;
|
||||
|
||||
uint8_t *mib_payload = nrmac->common_channels[0].MIB_pdu;
|
||||
uint32_t mib = (mib_payload[2] << 16) | (mib_payload[1] << 8) | mib_payload[0];
|
||||
cfg->ssb_table.MIB.tl.tag = NFAPI_NR_CONFIG_MIB_TAG;
|
||||
cfg->ssb_table.MIB.value = mib;
|
||||
cfg->num_tlv++;
|
||||
|
||||
nrmac->ssb_SubcarrierOffset = cfg->ssb_table.ssb_subcarrier_offset.value;
|
||||
nrmac->ssb_OffsetPointA = cfg->ssb_table.ssb_offset_point_a.value;
|
||||
LOG_I(NR_MAC,
|
||||
@@ -837,11 +843,8 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, c
|
||||
|
||||
config_common(nrmac, config->pdsch_AntennaPorts, config->pusch_AntennaPorts, scc);
|
||||
|
||||
if (NFAPI_MODE == NFAPI_MODE_PNF || NFAPI_MODE == NFAPI_MODE_VNF) {
|
||||
// fake that the gNB is configured in nFAPI mode, which would normally be
|
||||
// done in a NR_PHY_config_req, but in this mode, there is no PHY
|
||||
RC.gNB[0]->configured = 1;
|
||||
} else {
|
||||
if (NFAPI_MODE == NFAPI_MONOLITHIC) {
|
||||
// nothing to be sent in the other cases
|
||||
NR_PHY_Config_t phycfg = {.Mod_id = 0, .CC_id = 0, .cfg = &nrmac->config[0]};
|
||||
DevAssert(nrmac->if_inst->NR_PHY_config_req);
|
||||
nrmac->if_inst->NR_PHY_config_req(&phycfg);
|
||||
|
||||
@@ -91,6 +91,53 @@ void clear_nr_nfapi_information(gNB_MAC_INST *gNB,
|
||||
future_ul_tti_req->SFN = (prev_slot / num_slots) % 1024;
|
||||
LOG_D(NR_MAC, "%d.%d UL_tti_req_ahead SFN.slot = %d.%d for index %d \n", frameP, slotP, future_ul_tti_req->SFN, future_ul_tti_req->Slot, prev_slot % size);
|
||||
/* future_ul_tti_req->Slot is fixed! */
|
||||
for (int i = 0; i < future_ul_tti_req->n_pdus; i++) {
|
||||
switch(future_ul_tti_req->pdus_list[i].pdu_type){
|
||||
case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE:
|
||||
if(future_ul_tti_req->pdus_list[i].prach_pdu.beamforming.prgs_list){
|
||||
for (int j = 0; j < future_ul_tti_req->pdus_list[i].prach_pdu.beamforming.num_prgs; ++j) {
|
||||
if(future_ul_tti_req->pdus_list[i].prach_pdu.beamforming.prgs_list[j].dig_bf_interface_list){
|
||||
free(future_ul_tti_req->pdus_list[i].prach_pdu.beamforming.prgs_list[j].dig_bf_interface_list);
|
||||
}
|
||||
}
|
||||
free(future_ul_tti_req->pdus_list[i].prach_pdu.beamforming.prgs_list);
|
||||
}
|
||||
break;
|
||||
case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE:
|
||||
if(future_ul_tti_req->pdus_list[i].pusch_pdu.beamforming.prgs_list){
|
||||
for (int j = 0; j < future_ul_tti_req->pdus_list[i].pusch_pdu.beamforming.num_prgs; ++j) {
|
||||
if(future_ul_tti_req->pdus_list[i].pusch_pdu.beamforming.prgs_list[j].dig_bf_interface_list){
|
||||
free(future_ul_tti_req->pdus_list[i].pusch_pdu.beamforming.prgs_list[j].dig_bf_interface_list);
|
||||
}
|
||||
}
|
||||
free(future_ul_tti_req->pdus_list[i].pusch_pdu.beamforming.prgs_list);
|
||||
}
|
||||
break;
|
||||
case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE:
|
||||
if(future_ul_tti_req->pdus_list[i].pucch_pdu.beamforming.prgs_list){
|
||||
for (int j = 0; j < future_ul_tti_req->pdus_list[i].pucch_pdu.beamforming.num_prgs; ++j) {
|
||||
if(future_ul_tti_req->pdus_list[i].pucch_pdu.beamforming.prgs_list[j].dig_bf_interface_list){
|
||||
free(future_ul_tti_req->pdus_list[i].pucch_pdu.beamforming.prgs_list[j].dig_bf_interface_list);
|
||||
}
|
||||
}
|
||||
free(future_ul_tti_req->pdus_list[i].pucch_pdu.beamforming.prgs_list);
|
||||
}
|
||||
break;
|
||||
case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE:
|
||||
if(future_ul_tti_req->pdus_list[i].srs_pdu.beamforming.prgs_list){
|
||||
for (int j = 0; j < future_ul_tti_req->pdus_list[i].srs_pdu.beamforming.num_prgs; ++j) {
|
||||
if(future_ul_tti_req->pdus_list[i].srs_pdu.beamforming.prgs_list[j].dig_bf_interface_list){
|
||||
free(future_ul_tti_req->pdus_list[i].srs_pdu.beamforming.prgs_list[j].dig_bf_interface_list);
|
||||
}
|
||||
}
|
||||
free(future_ul_tti_req->pdus_list[i].srs_pdu.beamforming.prgs_list);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
future_ul_tti_req->pdus_list[i].pdu_type = 0;
|
||||
future_ul_tti_req->pdus_list[i].pdu_size = 0;
|
||||
}
|
||||
future_ul_tti_req->n_pdus = 0;
|
||||
future_ul_tti_req->n_ulsch = 0;
|
||||
future_ul_tti_req->n_ulcch = 0;
|
||||
|
||||
@@ -317,6 +317,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
|
||||
|
||||
UL_tti_req->SFN = frameP;
|
||||
UL_tti_req->Slot = slotP;
|
||||
UL_tti_req->rach_present = 1;
|
||||
for (int fdm_index=0; fdm_index < fdm; fdm_index++) { // one structure per frequency domain occasion
|
||||
for (int td_index=0; td_index<N_t_slot; td_index++) {
|
||||
|
||||
@@ -498,7 +499,11 @@ static void nr_schedule_msg2(uint16_t rach_frame,
|
||||
while ((eff_slot-rach_slot)<=sl_ahead) {
|
||||
eff_slot += tdd_period_slot;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_AERIAL
|
||||
if (nfapi_mode > 0) { // Aerial needs slot_ahead = 0, requiring addition of another TDD period
|
||||
eff_slot += tdd_period_slot;
|
||||
}
|
||||
#endif
|
||||
int FR = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] >= 257 ? nr_FR2 : nr_FR1;
|
||||
if (FR==nr_FR2) {
|
||||
int num_tdd_period = (eff_slot%nr_slots_per_frame[mu])/tdd_period_slot;
|
||||
@@ -1052,10 +1057,12 @@ static void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu,
|
||||
LOG_D(NR_MAC, "MSG3 start_sym:%d NR Symb:%d mappingtype:%d, ul_dmrs_symb_pos:%x\n", start_symbol_index, nr_of_symbols, mappingtype, pusch_pdu->ul_dmrs_symb_pos);
|
||||
pusch_pdu->dmrs_config_type = 0;
|
||||
pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId; //If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id.
|
||||
pusch_pdu->pusch_identity = *scc->physCellId; //If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id.
|
||||
pusch_pdu->scid = 0; //DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]. Should match what is sent in DCI 0_1, otherwise set to 0.
|
||||
pusch_pdu->dmrs_ports = 1; // 6.2.2 in 38.214 only port 0 to be used
|
||||
pusch_pdu->num_dmrs_cdm_grps_no_data = 2; // no data in dmrs symbols as in 6.2.2 in 38.214
|
||||
pusch_pdu->resource_alloc = 1; //type 1
|
||||
memset(pusch_pdu->rb_bitmap, 0, sizeof(pusch_pdu->rb_bitmap));
|
||||
pusch_pdu->rb_start = msg3_first_rb;
|
||||
if (msg3_nb_rb > pusch_pdu->bwp_size)
|
||||
AssertFatal(1==0,"MSG3 allocated number of RBs exceed the BWP size\n");
|
||||
@@ -1077,6 +1084,23 @@ static void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu,
|
||||
pusch_pdu->pusch_data.harq_process_id = 0;
|
||||
pusch_pdu->pusch_data.new_data_indicator = (round == 0) ? 1 : 0;;
|
||||
pusch_pdu->pusch_data.num_cb = 0;
|
||||
|
||||
// Beamforming
|
||||
pusch_pdu->beamforming.num_prgs = 0;
|
||||
pusch_pdu->beamforming.prg_size = 0; // bwp_size;
|
||||
pusch_pdu->beamforming.dig_bf_interface = 0;
|
||||
if (pusch_pdu->beamforming.num_prgs > 0) {
|
||||
if (pusch_pdu->beamforming.prgs_list == NULL) {
|
||||
pusch_pdu->beamforming.prgs_list = calloc(pusch_pdu->beamforming.num_prgs, sizeof(*pusch_pdu->beamforming.prgs_list));
|
||||
}
|
||||
if (pusch_pdu->beamforming.dig_bf_interface > 0) {
|
||||
if (pusch_pdu->beamforming.prgs_list[0].dig_bf_interface_list == NULL) {
|
||||
pusch_pdu->beamforming.prgs_list[0].dig_bf_interface_list =
|
||||
calloc(pusch_pdu->beamforming.dig_bf_interface, sizeof(*pusch_pdu->beamforming.prgs_list[0].dig_bf_interface_list));
|
||||
}
|
||||
}
|
||||
pusch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0;
|
||||
}
|
||||
int num_dmrs_symb = 0;
|
||||
for(int i = start_symbol_index; i < start_symbol_index+nr_of_symbols; i++)
|
||||
num_dmrs_symb += (pusch_pdu->ul_dmrs_symb_pos >> i) & 1;
|
||||
@@ -1279,6 +1303,12 @@ static void nr_generate_Msg2(module_id_t module_idP,
|
||||
dl_req->nPDUs+=1;
|
||||
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
|
||||
|
||||
pdsch_pdu_rel15->precodingAndBeamforming.num_prgs = 0;
|
||||
pdsch_pdu_rel15->precodingAndBeamforming.prg_size = 0;
|
||||
pdsch_pdu_rel15->precodingAndBeamforming.dig_bf_interfaces = 0;
|
||||
pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].pm_idx = 0;
|
||||
pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0;
|
||||
|
||||
LOG_A(NR_MAC,"[gNB %d][RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg2 DCI, rnti 0x%x, state %d, CoreSetType %d\n",
|
||||
module_idP, CC_id, frameP, slotP, ra->RA_rnti, ra->state,pdcch_pdu_rel15->CoreSetType);
|
||||
|
||||
|
||||
@@ -426,6 +426,12 @@ static void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
|
||||
dl_req->nPDUs += 1;
|
||||
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
|
||||
|
||||
pdsch_pdu_rel15->precodingAndBeamforming.num_prgs=0;
|
||||
pdsch_pdu_rel15->precodingAndBeamforming.prg_size=0;
|
||||
pdsch_pdu_rel15->precodingAndBeamforming.dig_bf_interfaces=0;
|
||||
pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].pm_idx = 0;
|
||||
pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0;
|
||||
|
||||
pdcch_pdu_rel15->CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1;
|
||||
|
||||
pdsch_pdu_rel15->pduBitmap = 0;
|
||||
|
||||
@@ -1066,6 +1066,10 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
pdsch_pdu->qamModOrder[0] = Qm;
|
||||
pdsch_pdu->mcsIndex[0] = sched_pdsch->mcs;
|
||||
pdsch_pdu->mcsTable[0] = current_BWP->mcsTableIdx;
|
||||
// NVIDIA: Workaround for MCSTableIdx mismatch error
|
||||
if (nr_get_code_rate_dl(sched_pdsch->mcs, current_BWP->mcsTableIdx) != R) {
|
||||
pdsch_pdu->mcsTable[0] = 0;
|
||||
}
|
||||
AssertFatal(harq!=NULL,"harq is null\n");
|
||||
AssertFatal(harq->round<gNB_mac->dl_bler.harq_round_max,"%d",harq->round);
|
||||
pdsch_pdu->rvIndex[0] = nr_rv_round_map[harq->round%4];
|
||||
@@ -1090,8 +1094,11 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
pdsch_pdu->StartSymbolIndex = tda_info->startSymbolIndex;
|
||||
pdsch_pdu->NrOfSymbols = tda_info->nrOfSymbols;
|
||||
// Precoding
|
||||
pdsch_pdu->precodingAndBeamforming.num_prgs = 0;
|
||||
pdsch_pdu->precodingAndBeamforming.prg_size = pdsch_pdu->rbSize;
|
||||
pdsch_pdu->precodingAndBeamforming.dig_bf_interfaces = 0;
|
||||
pdsch_pdu->precodingAndBeamforming.prgs_list[0].pm_idx = sched_pdsch->pm_index;
|
||||
pdsch_pdu->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0;
|
||||
// TBS_LBRM according to section 5.4.2.1 of 38.212
|
||||
// TODO: verify the case where maxMIMO_Layers is NULL, in which case
|
||||
// in principle maxMIMO_layers should be given by the maximum number of layers
|
||||
@@ -1146,6 +1153,13 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
dci_pdu->CceIndex = sched_ctrl->cce_index;
|
||||
dci_pdu->beta_PDCCH_1_0 = 0;
|
||||
dci_pdu->powerControlOffsetSS = 1;
|
||||
|
||||
dci_pdu->precodingAndBeamforming.num_prgs = 0;
|
||||
dci_pdu->precodingAndBeamforming.prg_size = 0;
|
||||
dci_pdu->precodingAndBeamforming.dig_bf_interfaces = 0;
|
||||
dci_pdu->precodingAndBeamforming.prgs_list[0].pm_idx = 0;
|
||||
dci_pdu->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0;
|
||||
|
||||
/* DCI payload */
|
||||
dci_pdu_rel15_t dci_payload;
|
||||
memset(&dci_payload, 0, sizeof(dci_pdu_rel15_t));
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
#define DEBUG_gNB_SCHEDULER 1
|
||||
|
||||
#include "common/ran_context.h"
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
|
||||
//#define DEBUG_DCI
|
||||
|
||||
@@ -227,13 +228,23 @@ NR_pdsch_dmrs_t get_dl_dmrs_params(const NR_ServingCellConfigCommon_t *scc,
|
||||
|
||||
switch (Layers) {
|
||||
case 1:
|
||||
#ifdef ENABLE_AERIAL
|
||||
dmrs.dmrs_ports_id = 3;
|
||||
dmrs.numDmrsCdmGrpsNoData = 2;
|
||||
#else
|
||||
dmrs.dmrs_ports_id = 0;
|
||||
dmrs.numDmrsCdmGrpsNoData = 1;
|
||||
#endif
|
||||
frontloaded_symb = 1;
|
||||
break;
|
||||
case 2:
|
||||
#ifdef ENABLE_AERIAL
|
||||
dmrs.dmrs_ports_id = 7;
|
||||
dmrs.numDmrsCdmGrpsNoData = 2;
|
||||
#else
|
||||
dmrs.dmrs_ports_id = 2;
|
||||
dmrs.numDmrsCdmGrpsNoData = 1;
|
||||
#endif
|
||||
frontloaded_symb = 1;
|
||||
break;
|
||||
case 3:
|
||||
@@ -606,10 +617,14 @@ NR_pusch_dmrs_t get_ul_dmrs_params(const NR_ServingCellConfigCommon_t *scc,
|
||||
|
||||
NR_pusch_dmrs_t dmrs = {0};
|
||||
// TODO setting of cdm groups with no data to be redone for MIMO
|
||||
if (ul_bwp->transform_precoding && Layers < 3)
|
||||
dmrs.num_dmrs_cdm_grps_no_data = ul_bwp->dci_format == NR_UL_DCI_FORMAT_0_1 || tda_info->nrOfSymbols == 2 ? 1 : 2;
|
||||
else
|
||||
if(NFAPI_MODE == NFAPI_MODE_AERIAL) {
|
||||
dmrs.num_dmrs_cdm_grps_no_data = 2;
|
||||
} else {
|
||||
if (ul_bwp->transform_precoding && Layers < 3)
|
||||
dmrs.num_dmrs_cdm_grps_no_data = ul_bwp->dci_format == NR_UL_DCI_FORMAT_0_1 || tda_info->nrOfSymbols == 2 ? 1 : 2;
|
||||
else
|
||||
dmrs.num_dmrs_cdm_grps_no_data = 2;
|
||||
}
|
||||
|
||||
NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig = ul_bwp->pusch_Config ?
|
||||
(tda_info->mapping_type == typeA ?
|
||||
@@ -738,7 +753,8 @@ void config_uldci(const NR_UE_ServingCell_Info_t *sc_info,
|
||||
|
||||
// antenna_ports.val = 0 for transform precoder is disabled, dmrs-Type=1, maxLength=1, Rank=1/2/3/4
|
||||
// Antenna Ports
|
||||
dci_pdu_rel15->antenna_ports.val = 0;
|
||||
|
||||
dci_pdu_rel15->antenna_ports.val = NFAPI_MODE == NFAPI_MODE_AERIAL ? 2 : 0;
|
||||
|
||||
// DMRS sequence initialization
|
||||
dci_pdu_rel15->dmrs_sequence_initialization.val = pusch_pdu->scid;
|
||||
@@ -1031,6 +1047,22 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t *pucch_pdu,
|
||||
pucch_pdu->sr_flag = O_sr;
|
||||
pucch_pdu->prb_size=1;
|
||||
}
|
||||
// Beamforming
|
||||
pucch_pdu->beamforming.num_prgs = 0;
|
||||
pucch_pdu->beamforming.prg_size = 0; // pucch_pdu->prb_size;
|
||||
pucch_pdu->beamforming.dig_bf_interface = 0;
|
||||
if (pucch_pdu->beamforming.num_prgs > 0) {
|
||||
if (pucch_pdu->beamforming.prgs_list == NULL) {
|
||||
pucch_pdu->beamforming.prgs_list = calloc(pucch_pdu->beamforming.num_prgs, sizeof(*pucch_pdu->beamforming.prgs_list));
|
||||
}
|
||||
if (pucch_pdu->beamforming.dig_bf_interface > 0) {
|
||||
if (pucch_pdu->beamforming.prgs_list[0].dig_bf_interface_list == NULL) {
|
||||
pucch_pdu->beamforming.prgs_list[0].dig_bf_interface_list =
|
||||
calloc(pucch_pdu->beamforming.dig_bf_interface, sizeof(*pucch_pdu->beamforming.prgs_list[0].dig_bf_interface_list));
|
||||
}
|
||||
}
|
||||
pucch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void set_r_pucch_parms(int rsetindex,
|
||||
@@ -2580,9 +2612,9 @@ void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti)
|
||||
delete_nr_ue_data(UE, nr_mac->common_channels, &UE_info->uid_allocator);
|
||||
}
|
||||
|
||||
uint8_t nr_get_tpc(int target, uint8_t cqi, int incr) {
|
||||
// al values passed to this function are x10
|
||||
int snrx10 = (cqi*5) - 640;
|
||||
uint8_t nr_get_tpc(int target, int snrx10, int incr)
|
||||
{
|
||||
// all values passed to this function are in dB x10
|
||||
if (snrx10 > target + incr) return 0; // decrease 1dB
|
||||
if (snrx10 < target - (3*incr)) return 3; // increase 3dB
|
||||
if (snrx10 < target - incr) return 2; // increase 1dB
|
||||
|
||||
@@ -1042,11 +1042,11 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
|
||||
}
|
||||
|
||||
// tpc (power control) only if we received AckNack
|
||||
if (uci_01->harq.harq_confidence_level==0)
|
||||
sched_ctrl->tpc1 = nr_get_tpc(nrmac->pucch_target_snrx10, uci_01->ul_cqi, 30);
|
||||
else
|
||||
sched_ctrl->tpc1 = 3;
|
||||
sched_ctrl->pucch_snrx10 = uci_01->ul_cqi * 5 - 640;
|
||||
if (uci_01->harq.harq_confidence_level == 0 && uci_01->ul_cqi != 0xff) {
|
||||
sched_ctrl->pucch_snrx10 = uci_01->ul_cqi * 5 - 640;
|
||||
sched_ctrl->tpc1 = nr_get_tpc(nrmac->pucch_target_snrx10, sched_ctrl->pucch_snrx10, 30);
|
||||
} else
|
||||
sched_ctrl->tpc1 = 1;
|
||||
}
|
||||
|
||||
// check scheduling request result, confidence_level == 0 is good
|
||||
@@ -1085,10 +1085,10 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
|
||||
|
||||
// tpc (power control)
|
||||
// TODO PUCCH2 SNR computation is not correct -> ignore the following
|
||||
//sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10,
|
||||
// uci_234->ul_cqi,
|
||||
// 30);
|
||||
//sched_ctrl->pucch_snrx10 = uci_234->ul_cqi * 5 - 640;
|
||||
if (uci_234->ul_cqi != 0xff) {
|
||||
sched_ctrl->pucch_snrx10 = uci_234->ul_cqi * 5 - 640;
|
||||
sched_ctrl->tpc1 = nr_get_tpc(nrmac->pucch_target_snrx10, sched_ctrl->pucch_snrx10, 30);
|
||||
}
|
||||
|
||||
// TODO: handle SR
|
||||
if (uci_234->pduBitmap & 0x1) {
|
||||
|
||||
@@ -625,11 +625,13 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
|
||||
// if not missed detection (10dB threshold for now)
|
||||
if (rssi>0) {
|
||||
UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10,ul_cqi,30);
|
||||
UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640;
|
||||
if (ul_cqi != 0xff) {
|
||||
UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10, UE_scheduling_control->pusch_snrx10, 30);
|
||||
}
|
||||
if (timing_advance != 0xffff)
|
||||
UE_scheduling_control->ta_update = timing_advance;
|
||||
UE_scheduling_control->raw_rssi = rssi;
|
||||
UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640;
|
||||
|
||||
LOG_D(NR_MAC, "[UE %04x] PUSCH TPC %d and TA %d\n",UE->rnti,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update);
|
||||
}
|
||||
@@ -670,7 +672,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
if (UE_scheduling_control->sched_ul_bytes < 0)
|
||||
UE_scheduling_control->sched_ul_bytes = 0;
|
||||
}
|
||||
if (ul_cqi <= 128) {
|
||||
if (ul_cqi == 0xff || ul_cqi <= 128) {
|
||||
UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt++;
|
||||
UE->mac_stats.ulsch_DTX++;
|
||||
}
|
||||
@@ -756,11 +758,13 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
|
||||
NR_UE_sched_ctrl_t *UE_scheduling_control = &UE_msg3_stage->UE_sched_ctrl;
|
||||
|
||||
UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10, ul_cqi, 30);
|
||||
if (ul_cqi != 0xff) {
|
||||
UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640;
|
||||
UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10, UE_scheduling_control->pusch_snrx10, 30);
|
||||
}
|
||||
if (timing_advance != 0xffff)
|
||||
UE_scheduling_control->ta_update = timing_advance;
|
||||
UE_scheduling_control->raw_rssi = rssi;
|
||||
UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640;
|
||||
LOG_D(NR_MAC, "[UE %04x] PUSCH TPC %d and TA %d\n", UE_msg3_stage->rnti, UE_scheduling_control->tpc0, UE_scheduling_control->ta_update);
|
||||
if (ra->cfra) {
|
||||
LOG_A(NR_MAC, "(rnti 0x%04x) CFRA procedure succeeded!\n", ra->rnti);
|
||||
@@ -2245,11 +2249,15 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n
|
||||
pusch_pdu->num_dmrs_cdm_grps_no_data = sched_pusch->dmrs_info.num_dmrs_cdm_grps_no_data;
|
||||
|
||||
/* FAPI: DMRS */
|
||||
pusch_pdu->num_dmrs_cdm_grps_no_data = sched_pusch->dmrs_info.num_dmrs_cdm_grps_no_data;
|
||||
pusch_pdu->dmrs_ports = ((1<<sched_pusch->nrOfLayers) - 1);
|
||||
pusch_pdu->ul_dmrs_symb_pos = sched_pusch->dmrs_info.ul_dmrs_symb_pos;
|
||||
pusch_pdu->dmrs_config_type = sched_pusch->dmrs_info.dmrs_config_type;
|
||||
pusch_pdu->scid = 0; // DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]
|
||||
const NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig = get_DMRS_UplinkConfig(current_BWP->pusch_Config, &sched_pusch->tda_info);
|
||||
if (pusch_pdu->transform_precoding) { // transform precoding disabled
|
||||
long *scramblingid=NULL;
|
||||
pusch_pdu->pusch_identity = *scc->physCellId;
|
||||
if (NR_DMRS_UplinkConfig && pusch_pdu->scid == 0)
|
||||
scramblingid = NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID0;
|
||||
else if (NR_DMRS_UplinkConfig)
|
||||
@@ -2356,7 +2364,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n
|
||||
nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu = &ul_dci_req->ul_dci_pdu_list[ul_dci_req->numPdus];
|
||||
memset(ul_dci_request_pdu, 0, sizeof(nfapi_nr_ul_dci_request_pdus_t));
|
||||
ul_dci_request_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
|
||||
ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
|
||||
ul_dci_request_pdu->PDUSize = (uint8_t)(4+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
|
||||
pdcch_pdu = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15;
|
||||
ul_dci_req->numPdus += 1;
|
||||
nr_configure_pdcch(pdcch_pdu, coreset, &sched_ctrl->sched_pdcch);
|
||||
|
||||
@@ -272,7 +272,7 @@ NR_pusch_dmrs_t get_ul_dmrs_params(const NR_ServingCellConfigCommon_t *scc,
|
||||
const NR_tda_info_t *tda_info,
|
||||
const int Layers);
|
||||
|
||||
uint8_t nr_get_tpc(int target, uint8_t cqi, int incr);
|
||||
uint8_t nr_get_tpc(int target, int snrx10, int incr);
|
||||
|
||||
int get_spf(nfapi_nr_config_request_scf_t *cfg);
|
||||
|
||||
|
||||
@@ -202,12 +202,12 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info)
|
||||
UL_info->CC_id,
|
||||
UL_info->rx_ind.sfn,
|
||||
UL_info->rx_ind.slot,
|
||||
rx->rnti,
|
||||
crc->rnti,
|
||||
crc->tb_crc_status ? NULL : rx->pdu,
|
||||
rx->pdu_length,
|
||||
rx->timing_advance,
|
||||
rx->ul_cqi,
|
||||
rx->rssi);
|
||||
crc->timing_advance,
|
||||
crc->ul_cqi,
|
||||
crc->rssi);
|
||||
handle_nr_ul_harq(UL_info->CC_id, UL_info->module_id, UL_info->frame, UL_info->slot, crc);
|
||||
}
|
||||
}
|
||||
@@ -440,7 +440,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
|
||||
nfapi_nr_uci_indication_t *uci_ind = NULL;
|
||||
nfapi_nr_rx_data_indication_t *rx_ind = NULL;
|
||||
nfapi_nr_crc_indication_t *crc_ind = NULL;
|
||||
if (get_softmodem_params()->emulate_l1)
|
||||
if (get_softmodem_params()->emulate_l1 || NFAPI_MODE == NFAPI_MODE_AERIAL)
|
||||
{
|
||||
if (gnb_rach_ind_queue.num_items > 0) {
|
||||
LOG_D(NR_MAC, "gnb_rach_ind_queue size = %zu\n", gnb_rach_ind_queue.num_items);
|
||||
@@ -483,7 +483,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
|
||||
handle_nr_ulsch(UL_info);
|
||||
handle_nr_srs(UL_info);
|
||||
|
||||
if (get_softmodem_params()->emulate_l1) {
|
||||
if (get_softmodem_params()->emulate_l1 || NFAPI_MODE == NFAPI_MODE_AERIAL) {
|
||||
free_unqueued_nfapi_indications(rach_ind, uci_ind, rx_ind, crc_ind);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ void handle_rach(UL_IND_t *UL_info) {
|
||||
int i;
|
||||
int j = UL_info->subframe;
|
||||
AssertFatal(j < sizeof(UL_RCC_INFO.rach_ind) / sizeof(UL_RCC_INFO.rach_ind[0]), "j index out of range of index of rach_ind\n");
|
||||
if (NFAPI_MODE == NFAPI_MODE_VNF)
|
||||
if (NFAPI_MODE == NFAPI_MODE_VNF || NFAPI_MODE == NFAPI_MODE_AERIAL)
|
||||
{
|
||||
if (UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles > 0)
|
||||
{
|
||||
@@ -97,7 +97,7 @@ void handle_sr(UL_IND_t *UL_info) {
|
||||
if (UL_info->sr_ind.sr_indication_body.number_of_srs>0) {
|
||||
oai_nfapi_sr_indication(&UL_info->sr_ind);
|
||||
}
|
||||
} else if(NFAPI_MODE == NFAPI_MODE_VNF) {
|
||||
} else if(NFAPI_MODE == NFAPI_MODE_VNF || NFAPI_MODE == NFAPI_MODE_AERIAL) {
|
||||
for(uint8_t j = 0; j < NUM_NFAPI_SUBFRAME; j++) {
|
||||
if(UL_RCC_INFO.sr_ind[j].sr_indication_body.number_of_srs > 0) {
|
||||
assert(UL_RCC_INFO.sr_ind[j].sr_indication_body.number_of_srs <= NFAPI_SR_IND_MAX_PDU);
|
||||
@@ -140,7 +140,7 @@ void handle_cqi(UL_IND_t *UL_info) {
|
||||
oai_nfapi_cqi_indication(&UL_info->cqi_ind);
|
||||
UL_info->cqi_ind.cqi_indication_body.number_of_cqis=0;
|
||||
}
|
||||
} else if (NFAPI_MODE == NFAPI_MODE_VNF) {
|
||||
} else if (NFAPI_MODE == NFAPI_MODE_VNF || NFAPI_MODE == NFAPI_MODE_AERIAL) {
|
||||
for(uint8_t j = 0; j < NUM_NFAPI_SUBFRAME; j++) {
|
||||
if(UL_RCC_INFO.cqi_ind[j].cqi_indication_body.number_of_cqis > 0) {
|
||||
assert(UL_RCC_INFO.cqi_ind[j].cqi_indication_body.number_of_cqis <= NFAPI_CQI_IND_MAX_PDU);
|
||||
@@ -187,7 +187,7 @@ void handle_harq(UL_IND_t *UL_info) {
|
||||
}
|
||||
|
||||
UL_info->harq_ind.harq_indication_body.number_of_harqs = 0;
|
||||
} else if(NFAPI_MODE == NFAPI_MODE_VNF) {
|
||||
} else if(NFAPI_MODE == NFAPI_MODE_VNF || NFAPI_MODE == NFAPI_MODE_AERIAL) {
|
||||
for(uint8_t j = 0; j < NUM_NFAPI_SUBFRAME; j++) {
|
||||
if(UL_RCC_INFO.harq_ind[j].harq_indication_body.number_of_harqs > 0) {
|
||||
assert(UL_RCC_INFO.harq_ind[j].harq_indication_body.number_of_harqs <= NFAPI_HARQ_IND_MAX_PDU);
|
||||
@@ -232,7 +232,7 @@ void handle_ulsch(UL_IND_t *UL_info) {
|
||||
oai_nfapi_rx_ind(&UL_info->rx_ind);
|
||||
UL_info->rx_ind.rx_indication_body.number_of_pdus = 0;
|
||||
}
|
||||
} else if(NFAPI_MODE == NFAPI_MODE_VNF) {
|
||||
} else if(NFAPI_MODE == NFAPI_MODE_VNF || NFAPI_MODE == NFAPI_MODE_AERIAL) {
|
||||
for(uint8_t k = 0; k < NUM_NFAPI_SUBFRAME; k++) {
|
||||
if((UL_RCC_INFO.rx_ind[k].rx_indication_body.number_of_pdus>0) && (UL_RCC_INFO.crc_ind[k].crc_indication_body.number_of_crcs>0)) {
|
||||
assert(UL_RCC_INFO.rx_ind[k].rx_indication_body.number_of_pdus <= NFAPI_RX_IND_MAX_PDU);
|
||||
|
||||
@@ -0,0 +1,262 @@
|
||||
Active_gNBs = ( "gNB-OAI");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
|
||||
sa = 1;
|
||||
nfapi = "AERIAL";
|
||||
|
||||
gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_ID = 0xe00;
|
||||
gNB_name = "gNB-OAI";
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1;
|
||||
plmn_list = ({
|
||||
mcc = 001;
|
||||
mnc = 01;
|
||||
mnc_length = 2;
|
||||
snssaiList = (
|
||||
{
|
||||
sst = 1;
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
nr_cellid = 12345678L;
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
pdsch_AntennaPorts_XP = 2;
|
||||
pusch_AntennaPorts = 2;
|
||||
do_CSIRS = 1;
|
||||
do_SRS = 0;
|
||||
min_rxtxtime = 2;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
controlResourceSetZero = 12;
|
||||
searchSpaceZero = 0;
|
||||
}
|
||||
);
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
|
||||
physCellId = 0;
|
||||
|
||||
# downlinkConfigCommon
|
||||
#frequencyInfoDL
|
||||
# this is 3300.24 + 134*12*30e3 = 3348.48 MHz (5G NR GSCN: 7741)
|
||||
absoluteFrequencySSB = 649920;
|
||||
#652860; #should be 649920
|
||||
#647520;
|
||||
#647540;
|
||||
#649920;
|
||||
#650208;
|
||||
#647540;
|
||||
dl_frequencyBand = 78;
|
||||
# this is 3300.24 MHz
|
||||
dl_absoluteFrequencyPointA = 646724;
|
||||
#649104;
|
||||
#646724;
|
||||
#scs-SpecificCarrierList
|
||||
dl_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
dl_subcarrierSpacing = 1;
|
||||
dl_carrierBandwidth = 273;
|
||||
#initialDownlinkBWP
|
||||
#genericParameters
|
||||
# this is RBstart=0,L=162 (275*(275-L+1))+(274-RBstart))
|
||||
initialDLBWPlocationAndBandwidth = 1099;
|
||||
#
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialDLBWPsubcarrierSpacing = 1;
|
||||
#pdcch-ConfigCommon
|
||||
initialDLBWPcontrolResourceSetZero = 12;
|
||||
initialDLBWPsearchSpaceZero = 0;
|
||||
|
||||
#uplinkConfigCommon
|
||||
#frequencyInfoUL
|
||||
ul_frequencyBand = 78;
|
||||
#scs-SpecificCarrierList
|
||||
ul_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
ul_subcarrierSpacing = 1;
|
||||
ul_carrierBandwidth = 273;
|
||||
pMax = 20;
|
||||
#initialUplinkBWP
|
||||
#genericParameters
|
||||
initialULBWPlocationAndBandwidth = 1099;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialULBWPsubcarrierSpacing = 1;
|
||||
#rach-ConfigCommon
|
||||
#rach-ConfigGeneric
|
||||
prach_ConfigurationIndex = 159;# testMAC 158; OAI gNB 98
|
||||
#prach_msg1_FDM
|
||||
#0 = one, 1=two, 2=four, 3=eight
|
||||
prach_msg1_FDM = 0;
|
||||
prach_msg1_FrequencyStart = 0;
|
||||
zeroCorrelationZoneConfig = 12;
|
||||
preambleReceivedTargetPower = -96;
|
||||
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
|
||||
preambleTransMax = 6;
|
||||
#powerRampingStep
|
||||
# 0=dB0,1=dB2,2=dB4,3=dB6
|
||||
powerRampingStep = 1;
|
||||
#ra_ReponseWindow
|
||||
#1,2,4,8,10,20,40,80
|
||||
ra_ResponseWindow = 5;
|
||||
#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 = 3;
|
||||
#oneHalf (0..15) 4,8,12,16,...60,64
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
|
||||
#ra_ContentionResolutionTimer
|
||||
#(0..7) 8,16,24,32,40,48,56,64
|
||||
ra_ContentionResolutionTimer = 7;
|
||||
rsrp_ThresholdSSB = 19;
|
||||
#prach-RootSequenceIndex_PR
|
||||
#1 = 839, 2 = 139
|
||||
prach_RootSequenceIndex_PR = 2;
|
||||
prach_RootSequenceIndex = 1;
|
||||
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
|
||||
#
|
||||
msg1_SubcarrierSpacing = 1,
|
||||
# restrictedSetConfig
|
||||
# 0=unrestricted, 1=restricted type A, 2=restricted type B
|
||||
restrictedSetConfig = 0,
|
||||
|
||||
msg3_DeltaPreamble = 1;
|
||||
p0_NominalWithGrant = -90;
|
||||
|
||||
# pucch-ConfigCommon setup :
|
||||
# pucchGroupHopping
|
||||
# 0 = neither, 1= group hopping, 2=sequence hopping
|
||||
pucchGroupHopping = 0;
|
||||
hoppingId = 40;
|
||||
p0_nominal = -90;
|
||||
# ssb_PositionsInBurs_BitmapPR
|
||||
# 1=short, 2=medium, 3=long
|
||||
ssb_PositionsInBurst_PR = 2;
|
||||
ssb_PositionsInBurst_Bitmap = 1;
|
||||
|
||||
# ssb_periodicityServingCell
|
||||
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
|
||||
ssb_periodicityServingCell = 2;
|
||||
|
||||
# dmrs_TypeA_position
|
||||
# 0 = pos2, 1 = pos3
|
||||
dmrs_TypeA_Position = 0;
|
||||
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
subcarrierSpacing = 1;
|
||||
|
||||
|
||||
#tdd-UL-DL-ConfigurationCommon
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
referenceSubcarrierSpacing = 1;
|
||||
# pattern1
|
||||
# dl_UL_TransmissionPeriodicity
|
||||
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
|
||||
dl_UL_TransmissionPeriodicity = 5; #6;
|
||||
nrofDownlinkSlots = 3; #7;
|
||||
nrofDownlinkSymbols = 6;
|
||||
nrofUplinkSlots = 1; #2;
|
||||
nrofUplinkSymbols = 0;
|
||||
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
|
||||
# ------- SCTP definitions
|
||||
SCTP :
|
||||
{
|
||||
# Number of streams to use in input/output
|
||||
SCTP_INSTREAMS = 2;
|
||||
SCTP_OUTSTREAMS = 2;
|
||||
};
|
||||
|
||||
|
||||
////////// AMF parameters:
|
||||
amf_ip_address = ( { ipv4 = "192.168.70.132";
|
||||
ipv6 = "192:168:30::17";
|
||||
active = "yes";
|
||||
preference = "ipv4";
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai";
|
||||
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.70.129";
|
||||
GNB_INTERFACE_NAME_FOR_NGU = "demo-oai";
|
||||
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.70.129";
|
||||
GNB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||
};
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
MACRLCs = (
|
||||
{
|
||||
num_cc = 1;
|
||||
local_s_if_name = "lo:";
|
||||
remote_s_address = "127.0.0.1"; // pnf addr [!]
|
||||
local_s_address = "127.0.0.2"; // vnf addr
|
||||
local_s_portc = 50001; // vnf p5 port
|
||||
remote_s_portc = 50000; // pnf p5 port [!]
|
||||
local_s_portd = 50011; // vnf p7 port [!]
|
||||
remote_s_portd = 50010; // pnf p7 port [!]
|
||||
tr_s_preference = "aerial";
|
||||
tr_n_preference = "local_RRC";
|
||||
pusch_TargetSNRx10 = 200; #150;
|
||||
pucch_TargetSNRx10 = 200; #200;
|
||||
ulsch_max_frame_inactivity = 10;
|
||||
dl_max_mcs = 28;
|
||||
ul_max_mcs = 28;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
security = {
|
||||
# preferred ciphering algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nea0, nea1, nea2, nea3
|
||||
ciphering_algorithms = ( "nea0" );
|
||||
|
||||
# preferred integrity algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nia0, nia1, nia2, nia3
|
||||
integrity_algorithms = ( "nia2", "nia0" );
|
||||
|
||||
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
|
||||
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
|
||||
drb_ciphering = "yes";
|
||||
drb_integrity = "no";
|
||||
};
|
||||
|
||||
log_config :
|
||||
{
|
||||
global_log_level ="info";
|
||||
hw_log_level ="info";
|
||||
phy_log_level ="info";
|
||||
mac_log_level ="info";
|
||||
rlc_log_level ="info";
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
ngap_log_level ="debug";
|
||||
f1ap_log_level ="debug";
|
||||
};
|
||||
Reference in New Issue
Block a user