Merge branch 'integration_2024_w10' into 'develop'
Integration: `2024.w10` See merge request oai/openairinterface5g!2608 * !2427 Scan build: Result of operation is garbage or undefined * !2477 cleanup of nfapi_nr_interface.h and more * !2523 CI: AW2S pipeline - test with 16 UEs including RAN code fixes * !2530 Rework of MAC UE handling of DAI * !2583 Small-bug-from- cdb18d38bfa6aee288a68d9e8881615a48addd83-and-one-gcc-warning * !2592 NR DMRS RX comments * !2599 Log module small cleaning * CI: mark as failed if UE log analysis fails * !2465 NVIDIA Aerial Integration * !2409 Ue rework keep sync in frame * !2603 tx_timestamp computation doesnt count slots from rx timestamp, and a small... * !2607 preventing negative RX absolute slot in NR softmodem * !2606 Instructions on how to debug using container images and core dump of CI * !2609 Upgrade Open Cells Project UICC/SIM programming tool and rename FR2 SA configuration file * fixup after merge of Aerial
This commit is contained in:
+2
-1
@@ -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
|
||||
|
||||
@@ -562,6 +562,29 @@ pipeline {
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ("SA-AERIAL-CN5G") {
|
||||
when { expression {do5Gtest} }
|
||||
steps {
|
||||
script {
|
||||
triggerSlaveJob ('RAN-SA-AERIAL-CN5G', 'SA-AERIAL-CN5G')
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
// Using a unique variable name for each test stage to avoid overwriting on a global variable
|
||||
// due to parallel-time concurrency
|
||||
saAERIALStatus = finalizeSlaveJob('RAN-SA-AERIAL-CN5G')
|
||||
}
|
||||
}
|
||||
failure {
|
||||
script {
|
||||
currentBuild.result = 'FAILURE'
|
||||
failingStages += saAERIALStatus
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ("SA-OAIUE-CN5G") {
|
||||
when { expression {do5Gtest} }
|
||||
steps {
|
||||
|
||||
@@ -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
|
||||
@@ -119,6 +130,48 @@ amarisoft_ue_10:
|
||||
NetworkScript: ip netns exec ue10 ip a show dev pdn0
|
||||
CmdPrefix: ip netns exec ue10
|
||||
MTU: 1500
|
||||
amarisoft_ue_11:
|
||||
Host: amariue
|
||||
AttachScript: /root/2023-10-27/libs/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":11}'
|
||||
DetachScript: /root/2023-10-27/libs/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":11}'
|
||||
NetworkScript: ip netns exec ue11 ip a show dev pdn0
|
||||
CmdPrefix: ip netns exec ue11
|
||||
MTU: 1500
|
||||
amarisoft_ue_12:
|
||||
Host: amariue
|
||||
AttachScript: /root/2023-10-27/libs/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":12}'
|
||||
DetachScript: /root/2023-10-27/libs/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":12}'
|
||||
NetworkScript: ip netns exec ue12 ip a show dev pdn0
|
||||
CmdPrefix: ip netns exec ue12
|
||||
MTU: 1500
|
||||
amarisoft_ue_13:
|
||||
Host: amariue
|
||||
AttachScript: /root/2023-10-27/libs/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":13}'
|
||||
DetachScript: /root/2023-10-27/libs/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":13}'
|
||||
NetworkScript: ip netns exec ue13 ip a show dev pdn0
|
||||
CmdPrefix: ip netns exec ue13
|
||||
MTU: 1500
|
||||
amarisoft_ue_14:
|
||||
Host: amariue
|
||||
AttachScript: /root/2023-10-27/libs/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":14}'
|
||||
DetachScript: /root/2023-10-27/libs/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":14}'
|
||||
NetworkScript: ip netns exec ue14 ip a show dev pdn0
|
||||
CmdPrefix: ip netns exec ue14
|
||||
MTU: 1500
|
||||
amarisoft_ue_15:
|
||||
Host: amariue
|
||||
AttachScript: /root/2023-10-27/libs/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":15}'
|
||||
DetachScript: /root/2023-10-27/libs/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":15}'
|
||||
NetworkScript: ip netns exec ue15 ip a show dev pdn0
|
||||
CmdPrefix: ip netns exec ue15
|
||||
MTU: 1500
|
||||
amarisoft_ue_16:
|
||||
Host: amariue
|
||||
AttachScript: /root/2023-10-27/libs/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":16}'
|
||||
DetachScript: /root/2023-10-27/libs/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":16}'
|
||||
NetworkScript: ip netns exec ue16 ip a show dev pdn0
|
||||
CmdPrefix: ip netns exec ue16
|
||||
MTU: 1500
|
||||
|
||||
oai_ue_caracal:
|
||||
Host: caracal
|
||||
|
||||
@@ -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|cuPHYController initialized|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')
|
||||
|
||||
@@ -1113,20 +1115,24 @@ class Containerize():
|
||||
logging.debug(f'Analyzing UE logfile {filename}')
|
||||
logStatus = cls_oaicitest.OaiCiTest().AnalyzeLogFile_UE(f'{filename}', HTML, RAN)
|
||||
if (logStatus < 0):
|
||||
fullStatus = False
|
||||
HTML.CreateHtmlTestRow('UE log Analysis', 'KO', logStatus)
|
||||
self.exitStatus = 1
|
||||
else:
|
||||
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
|
||||
if svcName == 'nv-cubb':
|
||||
msg = 'Undeploy PNF/Nvidia CUBB'
|
||||
HTML.CreateHtmlTestRow(msg, 'OK', CONST.ALL_PROCESSES_OK)
|
||||
else:
|
||||
HTML.CreateHtmlTestRow(RAN.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
|
||||
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)
|
||||
@@ -1385,6 +1391,7 @@ class Containerize():
|
||||
logStatus = UE.AnalyzeLogFile_UE(f'{logPath}/{filename}', HTML, RAN)
|
||||
if (logStatus < 0):
|
||||
fullStatus = False
|
||||
self.exitStatus = 1
|
||||
HTML.CreateHtmlTestRow('UE log Analysis', 'KO', logStatus)
|
||||
else:
|
||||
HTML.CreateHtmlTestRow('UE log Analysis', 'OK', CONST.ALL_PROCESSES_OK)
|
||||
|
||||
@@ -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";
|
||||
};
|
||||
+4
-2
@@ -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)
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -40,9 +40,15 @@
|
||||
002008
|
||||
002009
|
||||
002010
|
||||
002011
|
||||
002012
|
||||
002013
|
||||
002014
|
||||
002015
|
||||
000100
|
||||
000010
|
||||
000020
|
||||
002016
|
||||
000200
|
||||
003000
|
||||
004000
|
||||
@@ -132,12 +138,42 @@
|
||||
<id>amarisoft_ue_10</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="002011">
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach UE</desc>
|
||||
<id>amarisoft_ue_11</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="002012">
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach UE</desc>
|
||||
<id>amarisoft_ue_12</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="002013">
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach UE</desc>
|
||||
<id>amarisoft_ue_13</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="002014">
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach UE</desc>
|
||||
<id>amarisoft_ue_14</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="002015">
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach UE</desc>
|
||||
<id>amarisoft_ue_15</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000010">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (DL/7Mbps/UDP)(30 sec)(multi-ue profile)</desc>
|
||||
<iperf_args>-u -b 70M -t 30 -i 1 -R</iperf_args>
|
||||
<direction>IPERF3</direction>
|
||||
<id>amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10</id>
|
||||
<id>amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15</id>
|
||||
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
|
||||
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
|
||||
<iperf_profile>balanced</iperf_profile>
|
||||
@@ -148,7 +184,7 @@
|
||||
<desc>iperf (UL/3.6Mbps/UDP)(30 sec)(multi-ue profile)</desc>
|
||||
<iperf_args>-u -b 36M -t 30 -i 1 </iperf_args>
|
||||
<direction>IPERF3</direction>
|
||||
<id>amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10</id>
|
||||
<id>amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15</id>
|
||||
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
|
||||
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
|
||||
<iperf_profile>balanced</iperf_profile>
|
||||
@@ -157,17 +193,23 @@
|
||||
<testCase id="000100">
|
||||
<class>Ping</class>
|
||||
<desc>Ping: 20pings in 20sec, multi-ue</desc>
|
||||
<id>amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10</id>
|
||||
<id>amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15</id>
|
||||
<ping_args>-c 20 %cn_ip%</ping_args>
|
||||
<ping_packetloss_threshold>1</ping_packetloss_threshold>
|
||||
<ping_rttavg_threshold>25</ping_rttavg_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="002016">
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach UE</desc>
|
||||
<id>amarisoft_ue_16</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000200">
|
||||
<class>Ping</class>
|
||||
<desc>Ping: 100pings in 20sec, multi-ue</desc>
|
||||
<id>amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10</id>
|
||||
<ping_args>-c 100 -i 0.2 %cn_ip%</ping_args>
|
||||
<desc>Ping: 50pings in 10sec, multi-ue</desc>
|
||||
<id>amarisoft_ue_16</id>
|
||||
<ping_args>-c 50 -i 0.2 %cn_ip%</ping_args>
|
||||
<ping_packetloss_threshold>1</ping_packetloss_threshold>
|
||||
<ping_rttavg_threshold>30</ping_rttavg_threshold>
|
||||
</testCase>
|
||||
@@ -175,7 +217,7 @@
|
||||
<testCase id="003000">
|
||||
<class>Detach_UE</class>
|
||||
<desc>Detach UE</desc>
|
||||
<id>amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10</id>
|
||||
<id>amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 amarisoft_ue_16</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="004000">
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#!/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
|
||||
|
||||
"$cuBB_Path"/build/cuPHY-CP/cuphycontroller/examples/cuphycontroller_scf "$argument"
|
||||
@@ -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
|
||||
- ../../../cmake_targets/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")
|
||||
;;
|
||||
*)
|
||||
@@ -521,7 +525,7 @@ function main() {
|
||||
mkdir -p $DIR/nas_sim_tools/build
|
||||
cd $DIR/nas_sim_tools/build
|
||||
|
||||
eval $CMAKE_CMD ..
|
||||
${CMAKE_CMD% *} ..
|
||||
compilations nas_sim_tools usim.txt usim
|
||||
compilations nas_sim_tools nvram.txt nvram
|
||||
compilations nas_sim_tools conf2uedata.txt conf2uedata
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
project(NAS_SIM_TOOLS)
|
||||
|
||||
@@ -6,6 +6,7 @@ include(FindPkgConfig)
|
||||
pkg_search_module(CONFIG libconfig REQUIRED)
|
||||
include_directories(${CONFIG_INCLUDE_DIRS})
|
||||
add_definitions(-std=gnu99)
|
||||
include("../macros.cmake")
|
||||
|
||||
ENABLE_LANGUAGE(C)
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -12,8 +12,6 @@
|
||||
# define NUMBER_OF_SRS_MAX 16
|
||||
# define NUMBER_OF_SCH_STATS_MAX 16
|
||||
|
||||
#define NUMBER_FRAMES_PHY_UE_INACTIVE 10
|
||||
|
||||
#define MAX_MANAGED_ENB_PER_MOBILE 2
|
||||
#define MAX_MANAGED_GNB_PER_MOBILE 2
|
||||
|
||||
|
||||
+132
-162
@@ -46,7 +46,9 @@
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdatomic.h>
|
||||
#include "common/utils/LOG/log_extern.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
|
||||
#define LOG_MEM_SIZE 100*1024*1024
|
||||
|
||||
// main log variables
|
||||
|
||||
@@ -58,53 +60,105 @@ void read_cpu_hardware (void) __attribute__ ((constructor));
|
||||
void read_cpu_hardware (void) {}
|
||||
#endif
|
||||
|
||||
log_mem_cnt_t log_mem_d[2];
|
||||
int log_mem_flag = 0;
|
||||
|
||||
typedef struct {
|
||||
char* buf_p;
|
||||
int buf_index;
|
||||
int enable_flag;
|
||||
} log_mem_cnt_t;
|
||||
|
||||
static log_mem_cnt_t log_mem_d[2];
|
||||
static int log_mem_flag = 0;
|
||||
volatile int log_mem_side=0;
|
||||
pthread_mutex_t log_mem_lock;
|
||||
pthread_cond_t log_mem_notify;
|
||||
pthread_t log_mem_thread;
|
||||
int log_mem_file_cnt=0;
|
||||
static pthread_mutex_t log_mem_lock;
|
||||
static pthread_cond_t log_mem_notify;
|
||||
static pthread_t log_mem_thread;
|
||||
static int log_mem_file_cnt=0;
|
||||
volatile int log_mem_write_flag=0;
|
||||
volatile int log_mem_write_side=0;
|
||||
char __log_mem_filename[1024]={0};
|
||||
char * log_mem_filename = &__log_mem_filename[0];
|
||||
char logmem_filename[1024] = {0};
|
||||
static char * log_mem_filename;
|
||||
|
||||
const mapping log_level_names[] = {{"error", OAILOG_ERR},
|
||||
static mapping log_level_names[] = {{"error", OAILOG_ERR},
|
||||
{"warn", OAILOG_WARNING},
|
||||
{"analysis", OAILOG_ANALYSIS},
|
||||
{"info", OAILOG_INFO},
|
||||
{"debug", OAILOG_DEBUG},
|
||||
{"trace", OAILOG_TRACE},
|
||||
{NULL, -1}};
|
||||
mapping * log_level_names_ptr(void)
|
||||
{
|
||||
return log_level_names;
|
||||
}
|
||||
|
||||
const mapping log_options[] = {{"nocolor", FLAG_NOCOLOR},
|
||||
{"level", FLAG_LEVEL},
|
||||
{"thread", FLAG_THREAD},
|
||||
{"line_num", FLAG_FILE_LINE},
|
||||
{"function", FLAG_FUNCT},
|
||||
{"time", FLAG_TIME},
|
||||
{"thread_id", FLAG_THREAD_ID},
|
||||
{"wall_clock", FLAG_REAL_TIME},
|
||||
|
||||
/** @defgroup _log_format Defined log format
|
||||
* @ingroup _macro
|
||||
* @brief Macro of log formats defined by LOG
|
||||
* @{*/
|
||||
static const unsigned int FLAG_NOCOLOR = 1; /*!< \brief use colors in log messages, depending on level */
|
||||
static const unsigned int FLAG_THREAD = 1 << 1; /*!< \brief display thread name in log messages */
|
||||
static const unsigned int FLAG_LEVEL = 1 << 2; /*!< \brief display log level in log messages */
|
||||
static const unsigned int FLAG_FUNCT = 1 << 3;
|
||||
static const unsigned int FLAG_FILE_LINE = 1 << 4;
|
||||
static const unsigned int FLAG_TIME = 1 << 5;
|
||||
static const unsigned int FLAG_THREAD_ID = 1 << 6;
|
||||
static const unsigned int FLAG_REAL_TIME = 1 << 7;
|
||||
static const unsigned int FLAG_INITIALIZED = 1 << 8;
|
||||
|
||||
/** @}*/
|
||||
static mapping log_options[] = {{"nocolor", FLAG_NOCOLOR},
|
||||
{"level", FLAG_LEVEL},
|
||||
{"thread", FLAG_THREAD},
|
||||
{"line_num", FLAG_FILE_LINE},
|
||||
{"function", FLAG_FUNCT},
|
||||
{"time", FLAG_TIME},
|
||||
{"thread_id", FLAG_THREAD_ID},
|
||||
{"wall_clock", FLAG_REAL_TIME},
|
||||
{NULL, -1}};
|
||||
mapping * log_option_names_ptr(void)
|
||||
{
|
||||
return log_options;
|
||||
}
|
||||
|
||||
static mapping log_maskmap[] = {{"PRACH", DEBUG_PRACH},
|
||||
{"RU", DEBUG_RU},
|
||||
{"UE_PHYPROC", DEBUG_UE_PHYPROC},
|
||||
{"LTEESTIM", DEBUG_LTEESTIM},
|
||||
{"DLCELLSPEC", DEBUG_DLCELLSPEC},
|
||||
{"ULSCH", DEBUG_ULSCH},
|
||||
{"RRC", DEBUG_RRC},
|
||||
{"PDCP", DEBUG_PDCP},
|
||||
{"DFT", DEBUG_DFT},
|
||||
{"ASN1", DEBUG_ASN1},
|
||||
{"CTRLSOCKET", DEBUG_CTRLSOCKET},
|
||||
{"SECURITY", DEBUG_SECURITY},
|
||||
{"NAS", DEBUG_NAS},
|
||||
{"RLC", DEBUG_RLC},
|
||||
{"DLSCH_DECOD", DEBUG_DLSCH_DECOD},
|
||||
{"UE_TIMING", UE_TIMING},
|
||||
{NULL, -1}};
|
||||
mapping * log_maskmap_ptr(void)
|
||||
{
|
||||
return log_maskmap;
|
||||
}
|
||||
|
||||
const mapping log_maskmap[] = LOG_MASKMAP_INIT;
|
||||
|
||||
/* .log_format = 0x13 uncolored standard messages
|
||||
* .log_format = 0x93 colored standard messages */
|
||||
/* keep white space in first position; switching it to 0 allows colors to be disabled*/
|
||||
static const char *const LOG_RED = "\033[1;31m"; /*!< \brief VT100 sequence for bold red foreground */
|
||||
static const char *const LOG_GREEN = "\033[32m"; /*!< \brief VT100 sequence for green foreground */
|
||||
static const char *const LOG_ORANGE = "\033[93m"; /*!< \brief VT100 sequence for orange foreground */
|
||||
static const char *const LOG_BLUE = "\033[34m"; /*!< \brief VT100 sequence for blue foreground */
|
||||
static const char *const LOG_CYBL = "\033[40;36m"; /*!< \brief VT100 sequence for cyan foreground on black background */
|
||||
static const char *const LOG_RESET = "\033[0m"; /*!< \brief VT100 sequence for reset (black) foreground */
|
||||
static const char *const log_level_highlight_start[] =
|
||||
{LOG_RED, LOG_ORANGE, LOG_GREEN, "", LOG_BLUE, LOG_CYBL}; /*!< \brief Optional start-format strings for highlighting */
|
||||
|
||||
static const char *const log_level_highlight_end[] =
|
||||
{LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET}; /*!< \brief Optional end-format strings for highlighting */
|
||||
static void log_output_memory(log_component_t *c, const char *file, const char *func, int line, int comp, int level, const char* format,va_list args);
|
||||
|
||||
|
||||
int write_file_matlab(const char *fname,
|
||||
const char *vname,
|
||||
void *data,
|
||||
int length,
|
||||
int dec,
|
||||
unsigned int format,
|
||||
int multiVec)
|
||||
int write_file_matlab(const char *fname, const char *vname, void *data, int length, int dec, unsigned int format, int multiVec)
|
||||
{
|
||||
FILE *fp=NULL;
|
||||
int i;
|
||||
@@ -274,15 +328,15 @@ int write_file_matlab(const char *fname,
|
||||
}
|
||||
|
||||
/* get log parameters from configuration file */
|
||||
void log_getconfig(log_t *g_log)
|
||||
void log_getconfig(log_t *g_log)
|
||||
{
|
||||
char *gloglevel = NULL;
|
||||
int consolelog = 0;
|
||||
paramdef_t logparams_defaults[] = LOG_GLOBALPARAMS_DESC;
|
||||
paramdef_t logparams_level[MAX_LOG_PREDEF_COMPONENTS];
|
||||
paramdef_t logparams_logfile[MAX_LOG_PREDEF_COMPONENTS];
|
||||
paramdef_t logparams_debug[sizeof(log_maskmap)/sizeof(mapping)];
|
||||
paramdef_t logparams_dump[sizeof(log_maskmap)/sizeof(mapping)];
|
||||
paramdef_t logparams_debug[sizeofArray(log_maskmap)];
|
||||
paramdef_t logparams_dump[sizeofArray(log_maskmap)];
|
||||
int ret = config_get(config_get_if(), logparams_defaults, sizeofArray(logparams_defaults), CONFIG_STRING_LOG_PREFIX);
|
||||
|
||||
if (ret <0) {
|
||||
@@ -304,10 +358,10 @@ void log_getconfig(log_t *g_log)
|
||||
}
|
||||
|
||||
/* build the parameter array for setting per component log level and infile options */
|
||||
memset(logparams_level, 0, sizeof(paramdef_t)*MAX_LOG_PREDEF_COMPONENTS);
|
||||
memset(logparams_logfile, 0, sizeof(paramdef_t)*MAX_LOG_PREDEF_COMPONENTS);
|
||||
memset(logparams_level, 0, sizeof(logparams_level));
|
||||
memset(logparams_logfile, 0, sizeof(logparams_logfile));
|
||||
|
||||
for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_PREDEF_COMPONENTS; i++) {
|
||||
for (int i = 0; i < MAX_LOG_PREDEF_COMPONENTS; i++) {
|
||||
if(g_log->log_component[i].name == NULL) {
|
||||
g_log->log_component[i].name = malloc(17);
|
||||
sprintf((char *)g_log->log_component[i].name,"comp%i?",i);
|
||||
@@ -341,11 +395,11 @@ void log_getconfig(log_t *g_log)
|
||||
config_get(config_get_if(), logparams_logfile, MAX_LOG_PREDEF_COMPONENTS, CONFIG_STRING_LOG_PREFIX);
|
||||
|
||||
/* now set the log levels and infile option, according to what we read */
|
||||
for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_PREDEF_COMPONENTS; i++) {
|
||||
g_log->log_component[i].level = map_str_to_int(log_level_names, *(logparams_level[i].strptr));
|
||||
for (int i = 0; i < MAX_LOG_PREDEF_COMPONENTS; i++) {
|
||||
g_log->log_component[i].level = map_str_to_int(log_level_names, *logparams_level[i].strptr);
|
||||
set_log(i, g_log->log_component[i].level);
|
||||
|
||||
if (*(logparams_logfile[i].uptr) == 1)
|
||||
if (*logparams_logfile[i].uptr == 1)
|
||||
set_component_filelog(i);
|
||||
}
|
||||
|
||||
@@ -386,16 +440,10 @@ void log_getconfig(log_t *g_log)
|
||||
set_glog_onlinelog(consolelog);
|
||||
}
|
||||
|
||||
int register_log_component(char *name,
|
||||
char *fext,
|
||||
int compidx)
|
||||
int register_log_component(const char *name, const char *fext, int compidx)
|
||||
{
|
||||
int computed_compidx=compidx;
|
||||
|
||||
if (strlen(fext) > 3) {
|
||||
fext[3]=0; /* limit log file extension to 3 chars */
|
||||
}
|
||||
|
||||
if (compidx < 0) { /* this is not a pre-defined component */
|
||||
for (int i = MAX_LOG_PREDEF_COMPONENTS; i< MAX_LOG_COMPONENTS; i++) {
|
||||
if (g_log->log_component[i].name == NULL) {
|
||||
@@ -409,8 +457,9 @@ int register_log_component(char *name,
|
||||
g_log->log_component[computed_compidx].name = strdup(name);
|
||||
g_log->log_component[computed_compidx].stream = stdout;
|
||||
g_log->log_component[computed_compidx].filelog = 0;
|
||||
g_log->log_component[computed_compidx].filelog_name = malloc(strlen(name)+16);/* /tmp/<name>.%s */
|
||||
sprintf(g_log->log_component[computed_compidx].filelog_name,"/tmp/%s.%s",name,fext);
|
||||
g_log->log_rarely_used[computed_compidx].filelog_name = calloc(1, strlen(name) + 16); /* /tmp/<name>.%s */
|
||||
sprintf(g_log->log_rarely_used[computed_compidx].filelog_name, "/tmp/%s.", name);
|
||||
strncat(g_log->log_rarely_used[computed_compidx].filelog_name, fext, 3);
|
||||
} else {
|
||||
fprintf(stderr,"{LOG} %s %d Couldn't register component %s\n",__FILE__,__LINE__,name);
|
||||
}
|
||||
@@ -420,11 +469,13 @@ int register_log_component(char *name,
|
||||
|
||||
static void unregister_all_log_components(void)
|
||||
{
|
||||
log_component_t* lc = &g_log->log_component[0];
|
||||
log_component_t *lc = g_log->log_component;
|
||||
log_component_back_t *lb = g_log->log_rarely_used;
|
||||
while (lc->name) {
|
||||
free((char *)lc->name); // defined as const, but assigned through strdup()
|
||||
free(lc->filelog_name);
|
||||
free(lb->filelog_name);
|
||||
lc++;
|
||||
lb++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -441,7 +492,6 @@ int isLogInitDone (void)
|
||||
|
||||
int logInit (void)
|
||||
{
|
||||
int i;
|
||||
g_log = calloc(1, sizeof(log_t));
|
||||
|
||||
if (g_log == NULL) {
|
||||
@@ -449,69 +499,17 @@ int logInit (void)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
memset(g_log,0,sizeof(log_t));
|
||||
register_log_component("PHY","log",PHY);
|
||||
register_log_component("MAC","log",MAC);
|
||||
register_log_component("OPT","log",OPT);
|
||||
register_log_component("RLC","log",RLC);
|
||||
register_log_component("PDCP","log",PDCP);
|
||||
register_log_component("RRC","log",RRC);
|
||||
register_log_component("OMG","csv",OMG);
|
||||
register_log_component("OTG","log",OTG);
|
||||
register_log_component("OTG_LATENCY","dat",OTG_LATENCY);
|
||||
register_log_component("OTG_LATENCY_BG","dat",OTG_LATENCY_BG);
|
||||
register_log_component("OTG_GP","dat",OTG_GP);
|
||||
register_log_component("OTG_GP_BG","dat",OTG_GP_BG);
|
||||
register_log_component("OTG_JITTER","dat",OTG_JITTER);
|
||||
register_log_component("PERF","",PERF);
|
||||
register_log_component("OIP","",OIP);
|
||||
register_log_component("OCM","log",OCM);
|
||||
register_log_component("HW","",HW);
|
||||
register_log_component("OSA","",OSA);
|
||||
register_log_component("eRAL","",RAL_ENB);
|
||||
register_log_component("mRAL","",RAL_UE);
|
||||
register_log_component("ENB_APP","log",ENB_APP);
|
||||
register_log_component("MCE_APP","log",MCE_APP);
|
||||
register_log_component("MME_APP","log",MME_APP);
|
||||
register_log_component("TMR","",TMR);
|
||||
register_log_component("EMU","log",EMU);
|
||||
register_log_component("USIM","txt",USIM);
|
||||
register_log_component("SIM","txt",SIM);
|
||||
/* following log component are used for the localization*/
|
||||
register_log_component("LOCALIZE","log",LOCALIZE);
|
||||
register_log_component("NAS","log",NAS);
|
||||
register_log_component("UDP","",UDP_);
|
||||
register_log_component("GTPU","",GTPU);
|
||||
register_log_component("SDAP","",SDAP);
|
||||
register_log_component("S1AP","",S1AP);
|
||||
register_log_component("F1AP","",F1AP);
|
||||
register_log_component("E1AP","",E1AP);
|
||||
register_log_component("M2AP","",M2AP);
|
||||
register_log_component("M3AP","",M3AP);
|
||||
register_log_component("SCTP","",SCTP);
|
||||
register_log_component("X2AP","",X2AP);
|
||||
register_log_component("LOADER","log",LOADER);
|
||||
register_log_component("ASN1","log",ASN1);
|
||||
register_log_component("NFAPI_VNF","log",NFAPI_VNF);
|
||||
register_log_component("NFAPI_PNF","log",NFAPI_PNF);
|
||||
register_log_component("GNB_APP","log",GNB_APP);
|
||||
register_log_component("NR_RRC","log",NR_RRC);
|
||||
register_log_component("NR_MAC","log",NR_MAC);
|
||||
register_log_component("NR_MAC_DCI", "log", NR_MAC_DCI);
|
||||
register_log_component("NR_PHY_DCI", "log", NR_PHY_DCI);
|
||||
register_log_component("NR_PHY","log",NR_PHY);
|
||||
register_log_component("NGAP","",NGAP);
|
||||
register_log_component("ITTI","log",ITTI);
|
||||
register_log_component("UTIL","log",UTIL);
|
||||
for (int i = 0; i < MAX_LOG_PREDEF_COMPONENTS; i++)
|
||||
register_log_component(comp_name[i], comp_extension[i], i);
|
||||
|
||||
for (int i=0 ; log_level_names[i].name != NULL ; i++)
|
||||
g_log->level2string[i] = toupper(log_level_names[i].name[0]); // uppercased first letter of level name
|
||||
|
||||
g_log->level2string[i] = toupper(log_level_names[i].name[0]); // uppercased first letter of level name
|
||||
|
||||
g_log->filelog_name = "/tmp/openair.log";
|
||||
log_getconfig(g_log);
|
||||
|
||||
// set all unused component items to 0, they are for non predefined components
|
||||
for (i=MAX_LOG_PREDEF_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
|
||||
for (int i=MAX_LOG_PREDEF_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
|
||||
memset(&(g_log->log_component[i]),0,sizeof(log_component_t));
|
||||
}
|
||||
|
||||
@@ -538,7 +536,7 @@ static inline int log_header(log_component_t *c,
|
||||
int line,
|
||||
int level)
|
||||
{
|
||||
int flag= g_log->flag | c->flag;
|
||||
int flag = g_log->flag;
|
||||
|
||||
char threadname[64];
|
||||
if (flag & FLAG_THREAD ) {
|
||||
@@ -628,8 +626,8 @@ void log_dump(int component,
|
||||
va_list args;
|
||||
char *wbuf;
|
||||
log_component_t *c = &g_log->log_component[component];
|
||||
int flag= g_log->flag | c->flag;
|
||||
|
||||
int flag = g_log->flag;
|
||||
|
||||
switch(datatype) {
|
||||
case LOG_DUMP_DOUBLE:
|
||||
wbuf=malloc((buffsize * 10) + 64 + MAX_LOG_TOTAL);
|
||||
@@ -672,20 +670,17 @@ int set_log(int component,
|
||||
int level)
|
||||
{
|
||||
/* Checking parameters */
|
||||
DevCheck((component >= MIN_LOG_COMPONENTS) && (component < MAX_LOG_COMPONENTS),
|
||||
component, MIN_LOG_COMPONENTS, MAX_LOG_COMPONENTS);
|
||||
DevCheck((component >= 0) && (component < MAX_LOG_COMPONENTS), component, 0, MAX_LOG_COMPONENTS);
|
||||
DevCheck((level < NUM_LOG_LEVEL) && (level >= OAILOG_DISABLE), level, NUM_LOG_LEVEL,
|
||||
OAILOG_ERR);
|
||||
|
||||
if ( g_log->log_component[component].level != OAILOG_DISABLE )
|
||||
g_log->log_component[component].savedlevel = g_log->log_component[component].level;
|
||||
g_log->log_rarely_used[component].savedlevel = g_log->log_component[component].level;
|
||||
|
||||
g_log->log_component[component].level = level;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void set_glog(int level)
|
||||
{
|
||||
for (int c=0; c< MAX_LOG_COMPONENTS; c++ ) {
|
||||
@@ -697,7 +692,7 @@ void set_glog_onlinelog(int enable)
|
||||
{
|
||||
for (int c=0; c< MAX_LOG_COMPONENTS; c++ ) {
|
||||
if ( enable ) {
|
||||
g_log->log_component[c].level = g_log->log_component[c].savedlevel;
|
||||
g_log->log_component[c].level = g_log->log_rarely_used[c].savedlevel;
|
||||
g_log->log_component[c].vprint = vfprintf;
|
||||
g_log->log_component[c].print = fprintf;
|
||||
g_log->log_component[c].stream = stdout;
|
||||
@@ -706,6 +701,7 @@ void set_glog_onlinelog(int enable)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void set_glog_filelog(int enable)
|
||||
{
|
||||
static FILE *fptr;
|
||||
@@ -734,13 +730,14 @@ void set_glog_filelog(int enable)
|
||||
void set_component_filelog(int comp)
|
||||
{
|
||||
if (g_log->log_component[comp].stream == NULL || g_log->log_component[comp].stream == stdout) {
|
||||
g_log->log_component[comp].stream = fopen(g_log->log_component[comp].filelog_name,"w");
|
||||
g_log->log_component[comp].stream = fopen(g_log->log_rarely_used[comp].filelog_name, "w");
|
||||
}
|
||||
|
||||
g_log->log_component[comp].vprint = vfprintf;
|
||||
g_log->log_component[comp].print = fprintf;
|
||||
g_log->log_component[comp].filelog = 1;
|
||||
}
|
||||
|
||||
void close_component_filelog(int comp)
|
||||
{
|
||||
g_log->log_component[comp].filelog = 0;
|
||||
@@ -777,40 +774,19 @@ int map_str_to_int(const mapping *map, const char *str)
|
||||
/* map an int to a string. Takes a mapping array and a value */
|
||||
char *map_int_to_str(const mapping *map, const int val)
|
||||
{
|
||||
while (1) {
|
||||
if (map->name == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (map->name) {
|
||||
if (map->value == val) {
|
||||
return map->name;
|
||||
}
|
||||
|
||||
map++;
|
||||
}
|
||||
}
|
||||
|
||||
int is_newline(char *str,
|
||||
int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < size; i++ ) {
|
||||
if ( str[i] == '\n' ) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we get all the way to here, there must not have been a newline! */
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void logClean (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(isLogInitDone()) {
|
||||
for (i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
|
||||
for (int i = 0; i < MAX_LOG_COMPONENTS; i++) {
|
||||
close_component_filelog(i);
|
||||
}
|
||||
}
|
||||
@@ -885,7 +861,7 @@ static void log_output_memory(log_component_t *c, const char *file, const char *
|
||||
len = MAX_LOG_TOTAL;
|
||||
}
|
||||
}
|
||||
if ( !((g_log->flag | c->flag) & FLAG_NOCOLOR) ) {
|
||||
if (!((g_log->flag) & FLAG_NOCOLOR)) {
|
||||
int n = snprintf(log_buffer+len, MAX_LOG_TOTAL-len, "%s", log_level_highlight_end[level]);
|
||||
if (n > 0) {
|
||||
len += n;
|
||||
@@ -935,28 +911,22 @@ static void log_output_memory(log_component_t *c, const char *file, const char *
|
||||
}
|
||||
}
|
||||
|
||||
int logInit_log_mem (void)
|
||||
int logInit_log_mem (char * filename)
|
||||
{
|
||||
if (log_mem_flag == 1) {
|
||||
log_mem_d[0].buf_p = malloc(LOG_MEM_SIZE);
|
||||
log_mem_d[0].buf_index = 0;
|
||||
log_mem_d[0].enable_flag = 1;
|
||||
log_mem_d[1].buf_p = malloc(LOG_MEM_SIZE);
|
||||
log_mem_d[1].buf_index = 0;
|
||||
log_mem_d[1].enable_flag = 1;
|
||||
log_mem_side = 0;
|
||||
if ((pthread_mutex_init(&log_mem_lock, NULL) != 0) || (pthread_cond_init(&log_mem_notify, NULL) != 0)) {
|
||||
log_mem_d[1].enable_flag=0;
|
||||
return -1;
|
||||
}
|
||||
pthread_create(&log_mem_thread, NULL, (void *(*)(void *))flush_mem_to_file, (void *)NULL);
|
||||
} else {
|
||||
log_mem_d[0].buf_p = NULL;
|
||||
log_mem_d[1].buf_p = NULL;
|
||||
log_mem_d[0].enable_flag = 0;
|
||||
log_mem_d[1].enable_flag = 0;
|
||||
log_mem_flag = 1;
|
||||
log_mem_filename = filename; // in present code, the parameter is safe permanent pointer
|
||||
for (log_mem_cnt_t *ptr = log_mem_d; ptr < log_mem_d + sizeofArray(log_mem_d); ptr++)
|
||||
*ptr = (log_mem_cnt_t){
|
||||
.buf_p = malloc(LOG_MEM_SIZE),
|
||||
.buf_index = 0,
|
||||
.enable_flag = 1,
|
||||
};
|
||||
log_mem_side = 0;
|
||||
if ((pthread_mutex_init(&log_mem_lock, NULL) != 0) || (pthread_cond_init(&log_mem_notify, NULL) != 0)) {
|
||||
log_mem_d[1].enable_flag=0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
pthread_create(&log_mem_thread, NULL, (void *(*)(void *))flush_mem_to_file, (void *)NULL);
|
||||
printf("log init done\n");
|
||||
|
||||
return 0;
|
||||
|
||||
+76
-129
@@ -57,8 +57,6 @@
|
||||
#ifdef NDEBUG
|
||||
#warning assert is disabled
|
||||
#endif
|
||||
#define NUM_ELEMENTS(ARRAY) (sizeof(ARRAY) / sizeof(ARRAY[0]))
|
||||
#define CHECK_INDEX(ARRAY, INDEX) assert((INDEX) < NUM_ELEMENTS(ARRAY))
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -87,31 +85,6 @@ extern "C" {
|
||||
#define NUM_LOG_LEVEL 6 /*!< \brief the number of message levels users have with LOG (OAILOG_DISABLE is not available to user as a level, so it is not included)*/
|
||||
/** @}*/
|
||||
|
||||
/** @defgroup _log_format Defined log format
|
||||
* @ingroup _macro
|
||||
* @brief Macro of log formats defined by LOG
|
||||
* @{*/
|
||||
|
||||
/* .log_format = 0x13 uncolored standard messages
|
||||
* .log_format = 0x93 colored standard messages */
|
||||
/* keep white space in first position; switching it to 0 allows colors to be disabled*/
|
||||
#define LOG_RED "\033[1;31m" /*!< \brief VT100 sequence for bold red foreground */
|
||||
#define LOG_GREEN "\033[32m" /*!< \brief VT100 sequence for green foreground */
|
||||
#define LOG_ORANGE "\033[93m" /*!< \brief VT100 sequence for orange foreground */
|
||||
#define LOG_BLUE "\033[34m" /*!< \brief VT100 sequence for blue foreground */
|
||||
#define LOG_CYBL "\033[40;36m" /*!< \brief VT100 sequence for cyan foreground on black background */
|
||||
#define LOG_RESET "\033[0m" /*!< \brief VT100 sequence for reset (black) foreground */
|
||||
#define FLAG_NOCOLOR 0x0001 /*!< \brief use colors in log messages, depending on level */
|
||||
#define FLAG_THREAD 0x0008 /*!< \brief display thread name in log messages */
|
||||
#define FLAG_LEVEL 0x0010 /*!< \brief display log level in log messages */
|
||||
#define FLAG_FUNCT 0x0020
|
||||
#define FLAG_FILE_LINE 0x0040
|
||||
#define FLAG_TIME 0x0100
|
||||
#define FLAG_THREAD_ID 0x0200
|
||||
#define FLAG_REAL_TIME 0x0400
|
||||
#define FLAG_INITIALIZED 0x8000
|
||||
/** @}*/
|
||||
|
||||
#define SET_LOG_OPTION(O) g_log->flag = (g_log->flag | O)
|
||||
#define CLEAR_LOG_OPTION(O) g_log->flag = (g_log->flag & (~O))
|
||||
|
||||
@@ -140,92 +113,73 @@ extern "C" {
|
||||
#define DEBUG_DLSCH_DECOD (1<<14)
|
||||
#define UE_TIMING (1<<20)
|
||||
|
||||
|
||||
#define LOG_MASKMAP_INIT {\
|
||||
{"PRACH", DEBUG_PRACH},\
|
||||
{"RU", DEBUG_RU},\
|
||||
{"UE_PHYPROC", DEBUG_UE_PHYPROC},\
|
||||
{"LTEESTIM", DEBUG_LTEESTIM},\
|
||||
{"DLCELLSPEC", DEBUG_DLCELLSPEC},\
|
||||
{"ULSCH", DEBUG_ULSCH},\
|
||||
{"RRC", DEBUG_RRC},\
|
||||
{"PDCP", DEBUG_PDCP},\
|
||||
{"DFT", DEBUG_DFT},\
|
||||
{"ASN1", DEBUG_ASN1},\
|
||||
{"CTRLSOCKET", DEBUG_CTRLSOCKET},\
|
||||
{"SECURITY", DEBUG_SECURITY},\
|
||||
{"NAS", DEBUG_NAS},\
|
||||
{"RLC", DEBUG_RLC},\
|
||||
{"DLSCH_DECOD", DEBUG_DLSCH_DECOD},\
|
||||
{"UE_TIMING", UE_TIMING},\
|
||||
{NULL,-1}\
|
||||
}
|
||||
|
||||
#define SET_LOG_DEBUG(B) g_log->debug_mask = (g_log->debug_mask | B)
|
||||
#define CLEAR_LOG_DEBUG(B) g_log->debug_mask = (g_log->debug_mask & (~B))
|
||||
|
||||
#define SET_LOG_DUMP(B) g_log->dump_mask = (g_log->dump_mask | B)
|
||||
#define CLEAR_LOG_DUMP(B) g_log->dump_mask = (g_log->dump_mask & (~B))
|
||||
|
||||
typedef enum {
|
||||
MIN_LOG_COMPONENTS = 0,
|
||||
PHY = MIN_LOG_COMPONENTS,
|
||||
MAC,
|
||||
EMU,
|
||||
SIM,
|
||||
OMG,
|
||||
OPT,
|
||||
OTG,
|
||||
OTG_LATENCY,
|
||||
OTG_LATENCY_BG,
|
||||
OTG_GP,
|
||||
OTG_GP_BG,
|
||||
OTG_JITTER,
|
||||
RLC,
|
||||
PDCP,
|
||||
RRC,
|
||||
NAS,
|
||||
PERF,
|
||||
OIP,
|
||||
CLI,
|
||||
OCM,
|
||||
UDP_,
|
||||
GTPU,
|
||||
SDAP,
|
||||
SPGW,
|
||||
S1AP,
|
||||
F1AP,
|
||||
E1AP,
|
||||
SCTP,
|
||||
HW,
|
||||
OSA,
|
||||
RAL_ENB,
|
||||
RAL_UE,
|
||||
ENB_APP,
|
||||
MCE_APP,
|
||||
MME_APP,
|
||||
TMR,
|
||||
USIM,
|
||||
LOCALIZE,
|
||||
F1U,
|
||||
X2AP,
|
||||
M2AP,
|
||||
M3AP,
|
||||
NGAP,
|
||||
GNB_APP,
|
||||
NR_RRC,
|
||||
NR_MAC,
|
||||
NR_MAC_DCI,
|
||||
NR_PHY_DCI,
|
||||
NR_PHY,
|
||||
LOADER,
|
||||
ASN1,
|
||||
NFAPI_VNF,
|
||||
NFAPI_PNF,
|
||||
ITTI,
|
||||
UTIL,
|
||||
MAX_LOG_PREDEF_COMPONENTS,
|
||||
} comp_name_t;
|
||||
#define FOREACH_COMP(COMP_DEF) \
|
||||
COMP_DEF(PHY, log) \
|
||||
COMP_DEF(MAC, log) \
|
||||
COMP_DEF(EMU, log) \
|
||||
COMP_DEF(SIM, txt) \
|
||||
COMP_DEF(OMG, csv) \
|
||||
COMP_DEF(OPT, log) \
|
||||
COMP_DEF(OTG, log) \
|
||||
COMP_DEF(OTG_LATENCY, dat) \
|
||||
COMP_DEF(OTG_LATENCY_BG, dat) \
|
||||
COMP_DEF(OTG_GP, dat) \
|
||||
COMP_DEF(OTG_GP_BG, dat) \
|
||||
COMP_DEF(OTG_JITTER, dat) \
|
||||
COMP_DEF(RLC, ) \
|
||||
COMP_DEF(PDCP, ) \
|
||||
COMP_DEF(RRC, ) \
|
||||
COMP_DEF(NAS, log) \
|
||||
COMP_DEF(OIP, ) \
|
||||
COMP_DEF(CLI, ) \
|
||||
COMP_DEF(OCM, ) \
|
||||
COMP_DEF(GTPU, ) \
|
||||
COMP_DEF(SDAP, ) \
|
||||
COMP_DEF(SPGW, ) \
|
||||
COMP_DEF(S1AP, ) \
|
||||
COMP_DEF(F1AP, ) \
|
||||
COMP_DEF(E1AP, ) \
|
||||
COMP_DEF(SCTP, ) \
|
||||
COMP_DEF(HW, ) \
|
||||
COMP_DEF(OSA, ) \
|
||||
COMP_DEF(ENB_APP, log) \
|
||||
COMP_DEF(MCE_APP, log) \
|
||||
COMP_DEF(MME_APP, log) \
|
||||
COMP_DEF(TMR, ) \
|
||||
COMP_DEF(USIM, log) \
|
||||
COMP_DEF(F1U, ) \
|
||||
COMP_DEF(X2AP, ) \
|
||||
COMP_DEF(M2AP, ) \
|
||||
COMP_DEF(M3AP, ) \
|
||||
COMP_DEF(NGAP, ) \
|
||||
COMP_DEF(GNB_APP, log) \
|
||||
COMP_DEF(NR_RRC, log) \
|
||||
COMP_DEF(NR_MAC, log) \
|
||||
COMP_DEF(NR_MAC_DCI, log) \
|
||||
COMP_DEF(NR_PHY_DCI, log) \
|
||||
COMP_DEF(NR_PHY, log) \
|
||||
COMP_DEF(LOADER, log) \
|
||||
COMP_DEF(ASN1, log) \
|
||||
COMP_DEF(NFAPI_VNF, log) \
|
||||
COMP_DEF(NFAPI_PNF, log) \
|
||||
COMP_DEF(ITTI, log) \
|
||||
COMP_DEF(UTIL, log) \
|
||||
COMP_DEF(MAX_LOG_PREDEF_COMPONENTS, )
|
||||
|
||||
#define COMP_ENUM(comp, file_extension) comp,
|
||||
typedef enum { FOREACH_COMP(COMP_ENUM) } comp_name_t;
|
||||
|
||||
#define COMP_TEXT(comp, file_extension) #comp,
|
||||
static const char *const comp_name[] = {FOREACH_COMP(COMP_TEXT)};
|
||||
|
||||
#define COMP_EXTENSION(comp, file_extension) #file_extension,
|
||||
static const char *const comp_extension[] = {FOREACH_COMP(COMP_EXTENSION)};
|
||||
|
||||
#define MAX_LOG_DYNALLOC_COMPONENTS 20
|
||||
#define MAX_LOG_COMPONENTS (MAX_LOG_PREDEF_COMPONENTS + MAX_LOG_DYNALLOC_COMPONENTS)
|
||||
@@ -237,23 +191,24 @@ typedef struct {
|
||||
|
||||
typedef int(*log_vprint_func_t)(FILE *stream, const char *format, va_list ap );
|
||||
typedef int(*log_print_func_t)(FILE *stream, const char *format, ... );
|
||||
typedef struct {
|
||||
int savedlevel;
|
||||
char *filelog_name;
|
||||
} log_component_back_t;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
int level;
|
||||
int savedlevel;
|
||||
int flag;
|
||||
int filelog;
|
||||
char *filelog_name;
|
||||
int level;
|
||||
int filelog;
|
||||
FILE *stream;
|
||||
log_vprint_func_t vprint;
|
||||
log_print_func_t print;
|
||||
/* SR: make the log buffer component relative */
|
||||
// char log_buffer[MAX_LOG_TOTAL];
|
||||
log_print_func_t print;
|
||||
} log_component_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
log_component_t log_component[MAX_LOG_COMPONENTS];
|
||||
log_component_back_t log_rarely_used[MAX_LOG_COMPONENTS];
|
||||
char level2string[NUM_LOG_LEVEL];
|
||||
int flag;
|
||||
char *filelog_name;
|
||||
@@ -272,8 +227,7 @@ extern "C" {
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
/*--- INCLUDES ---------------------------------------------------------------*/
|
||||
# include "log_if.h"
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int logInit (void);
|
||||
void logTerm (void);
|
||||
@@ -284,6 +238,9 @@ void log_dump(int component, void *buffer, int buffsize,int datatype, const char
|
||||
int set_log(int component, int level);
|
||||
void set_glog(int level);
|
||||
|
||||
mapping * log_level_names_ptr(void);
|
||||
mapping * log_option_names_ptr(void);
|
||||
mapping * log_maskmap_ptr(void);
|
||||
void set_glog_onlinelog(int enable);
|
||||
void set_glog_filelog(int enable);
|
||||
void set_component_filelog(int comp);
|
||||
@@ -292,21 +249,11 @@ void set_component_consolelog(int comp);
|
||||
int map_str_to_int(const mapping *map, const char *str);
|
||||
char *map_int_to_str(const mapping *map, const int val);
|
||||
void logClean (void);
|
||||
int is_newline( char *str, int size);
|
||||
|
||||
int register_log_component(char *name, char *fext, int compidx);
|
||||
int register_log_component(const char *name, const char *fext, int compidx);
|
||||
|
||||
#define LOG_MEM_SIZE 100*1024*1024
|
||||
#define LOG_MEM_FILE "./logmem.log"
|
||||
void flush_mem_to_file(void);
|
||||
int logInit_log_mem(void);
|
||||
int logInit_log_mem(char*);
|
||||
void close_log_mem(void);
|
||||
|
||||
typedef struct {
|
||||
char* buf_p;
|
||||
int buf_index;
|
||||
int enable_flag;
|
||||
} log_mem_cnt_t;
|
||||
|
||||
/** @}*/
|
||||
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "log.h"
|
||||
|
||||
extern log_t *g_log;
|
||||
|
||||
extern const mapping log_level_names[];
|
||||
extern const mapping log_options[];
|
||||
extern const mapping log_maskmap[];
|
||||
extern int log_mem_flag;
|
||||
extern char * log_mem_filename;
|
||||
extern char logmem_filename[1024];
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file log_if.h
|
||||
* \brief log interface
|
||||
* \author Navid Nikaein
|
||||
* \date 2009 - 2014
|
||||
* \version 0.3
|
||||
* \warning This component can be runned only in user-space
|
||||
* @ingroup routing
|
||||
*/
|
||||
|
||||
// LTS: kept this file for compatibility
|
||||
// this file was probably a trial to separate internal functions and external ones
|
||||
// but it has never been finished, most source code include directly log.h (not log_if.h)
|
||||
#include "log.h"
|
||||
@@ -214,10 +214,6 @@ void nr_est_delay(int ofdm_symbol_size, const c16_t *ls_est, c16_t *ch_estimates
|
||||
#define CEILIDIV(a,b) ((a+b-1)/b)
|
||||
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
|
||||
|
||||
#define cmax(a,b) ((a>b) ? (a) : (b))
|
||||
#define cmax3(a,b,c) ((cmax(a,b)>c) ? (cmax(a,b)) : (c))
|
||||
#define cmin(a,b) ((a<b) ? (a) : (b))
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifdef min
|
||||
#undef min
|
||||
|
||||
@@ -256,6 +256,9 @@ void print_threads(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
int proccmd_websrv_getdata(char *cmdbuff, int debug, void *data, telnet_printfunc_t prnt)
|
||||
{
|
||||
webdatadef_t *logsdata = (webdatadef_t *)data;
|
||||
const mapping *const log_level_names = log_level_names_ptr();
|
||||
const mapping *const log_options = log_option_names_ptr();
|
||||
const mapping *log_maskmap = log_maskmap_ptr();
|
||||
if (strncmp(cmdbuff, "set", 3) == 0) {
|
||||
telnet_printfunc_t printfunc = (prnt != NULL) ? prnt : (telnet_printfunc_t)printf;
|
||||
if (strcasestr(cmdbuff, "loglvl") != NULL) {
|
||||
@@ -274,7 +277,7 @@ int proccmd_websrv_getdata(char *cmdbuff, int debug, void *data, telnet_printfun
|
||||
logsdata->lines[0].val[0],
|
||||
logsdata->lines[0].val[1],
|
||||
enabled ? "enabled" : "disabled",
|
||||
loginfile ? g_log->log_component[logsdata->numlines].filelog_name : "stdout");
|
||||
loginfile ? g_log->log_rarely_used[logsdata->numlines].filelog_name : "stdout");
|
||||
}
|
||||
if (strcasestr(cmdbuff, "logopt") != NULL) {
|
||||
int optbit = map_str_to_int(log_options, logsdata->lines[0].val[0]);
|
||||
@@ -329,12 +332,14 @@ int proccmd_websrv_getdata(char *cmdbuff, int debug, void *data, telnet_printfun
|
||||
snprintf(logsdata->columns[3].coltitle, TELNET_CMD_MAXSIZE, "in file");
|
||||
logsdata->columns[3].coltype = TELNET_CHECKVAL_BOOL;
|
||||
|
||||
for (int i = MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
|
||||
for (int i = 0; i < MAX_LOG_COMPONENTS; i++) {
|
||||
if (g_log->log_component[i].name != NULL) {
|
||||
logsdata->numlines++;
|
||||
logsdata->lines[i].val[0] = (char *)(g_log->log_component[i].name);
|
||||
|
||||
logsdata->lines[i].val[1] = map_int_to_str(log_level_names, (g_log->log_component[i].level >= 0) ? g_log->log_component[i].level : g_log->log_component[i].savedlevel);
|
||||
logsdata->lines[i].val[1] = map_int_to_str(
|
||||
log_level_names,
|
||||
(g_log->log_component[i].level >= 0) ? g_log->log_component[i].level : g_log->log_rarely_used[i].savedlevel);
|
||||
logsdata->lines[i].val[2] = (g_log->log_component[i].level >= 0) ? "true" : "false";
|
||||
logsdata->lines[i].val[3] = (g_log->log_component[i].filelog > 0) ? "true" : "false";
|
||||
}
|
||||
@@ -353,7 +358,7 @@ int proccmd_websrv_getdata(char *cmdbuff, int debug, void *data, telnet_printfun
|
||||
|
||||
for (int i = 0; log_maskmap[i].name != NULL; i++) {
|
||||
logsdata->numlines++;
|
||||
logsdata->lines[i].val[0] = log_maskmap[i].name;
|
||||
logsdata->lines[i].val[0] = (char *)log_maskmap[i].name;
|
||||
logsdata->lines[i].val[1] = (g_log->debug_mask & log_maskmap[i].value) ? "true" : "false";
|
||||
logsdata->lines[i].val[2] = (g_log->dump_mask & log_maskmap[i].value) ? "true" : "false";
|
||||
}
|
||||
@@ -370,7 +375,7 @@ int proccmd_websrv_getdata(char *cmdbuff, int debug, void *data, telnet_printfun
|
||||
|
||||
for (int i = 0; log_options[i].name != NULL; i++) {
|
||||
logsdata->numlines++;
|
||||
logsdata->lines[i].val[0] = log_options[i].name;
|
||||
logsdata->lines[i].val[0] = (char *)log_options[i].name;
|
||||
logsdata->lines[i].val[1] = (g_log->flag & log_options[i].value) ? "true" : "false";
|
||||
}
|
||||
}
|
||||
@@ -395,17 +400,23 @@ int proccmd_show(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
}
|
||||
if (strcasestr(buf,"loglvl") != NULL) {
|
||||
prnt("\n component level enabled output\n");
|
||||
for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
|
||||
if (g_log->log_component[i].name != NULL) {
|
||||
prnt("%02i %17.17s:%10.10s %s %s\n",i ,g_log->log_component[i].name,
|
||||
map_int_to_str(log_level_names,(g_log->log_component[i].level>=0)?g_log->log_component[i].level:g_log->log_component[i].savedlevel),
|
||||
((g_log->log_component[i].level>=0)?"Y":"N"),
|
||||
((g_log->log_component[i].filelog>0)?g_log->log_component[i].filelog_name:"stdout"));
|
||||
}
|
||||
const mapping *const log_level_names = log_level_names_ptr();
|
||||
for (int i = 0; i < MAX_LOG_COMPONENTS; i++) {
|
||||
if (g_log->log_component[i].name != NULL) {
|
||||
prnt("%02i %17.17s:%10.10s %s %s\n",
|
||||
i,
|
||||
g_log->log_component[i].name,
|
||||
map_int_to_str(
|
||||
log_level_names,
|
||||
(g_log->log_component[i].level >= 0) ? g_log->log_component[i].level : g_log->log_rarely_used[i].savedlevel),
|
||||
((g_log->log_component[i].level >= 0) ? "Y" : "N"),
|
||||
((g_log->log_component[i].filelog > 0) ? g_log->log_rarely_used[i].filelog_name : "stdout"));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (strcasestr(buf,"logopt") != NULL) {
|
||||
prnt("\n option enabled\n");
|
||||
const mapping *const log_options = log_option_names_ptr();
|
||||
for (int i=0; log_options[i].name != NULL; i++) {
|
||||
prnt("%02i %17.17s %10.10s \n",i ,log_options[i].name,
|
||||
((g_log->flag & log_options[i].value)?"Y":"N") );
|
||||
@@ -413,6 +424,7 @@ int proccmd_show(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
}
|
||||
if (strcasestr(buf,"dbgopt") != NULL) {
|
||||
prnt("\n module debug dumpfile\n");
|
||||
const mapping *log_maskmap = log_maskmap_ptr();
|
||||
for (int i=0; log_maskmap[i].name != NULL ; i++) {
|
||||
prnt("%02i %17.17s %5.5s %5.5s\n",i ,log_maskmap[i].name,
|
||||
((g_log->debug_mask & log_maskmap[i].value)?"Y":"N"),
|
||||
@@ -528,7 +540,9 @@ int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2);
|
||||
|
||||
if (debug > 0)
|
||||
prnt( "proccmd_log received %s\n s=%i sub command %s\n",buf,s,((logsubcmd==NULL)?"":logsubcmd));
|
||||
|
||||
const mapping *const log_level_names = log_level_names_ptr();
|
||||
const mapping *const log_options = log_option_names_ptr();
|
||||
const mapping *log_maskmap = log_maskmap_ptr();
|
||||
if (s == 1 && logsubcmd != NULL) {
|
||||
if (strcasestr(logsubcmd,"online") != NULL) {
|
||||
if (strcasestr(buf,"noonline") != NULL) {
|
||||
@@ -540,21 +554,21 @@ int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2);
|
||||
}
|
||||
}
|
||||
else if (strcasestr(logsubcmd,"show") != NULL) {
|
||||
prnt("Available log levels: \n ");
|
||||
for (int i=0; log_level_names[i].name != NULL; i++)
|
||||
prnt("%s ",log_level_names[i].name);
|
||||
prnt("\n\n");
|
||||
prnt("Available display options: \n ");
|
||||
for (int i=0; log_options[i].name != NULL; i++)
|
||||
prnt("%s ",log_options[i].name);
|
||||
prnt("\n\n");
|
||||
prnt("Available debug and dump options: \n ");
|
||||
for (int i=0; log_maskmap[i].name != NULL; i++)
|
||||
prnt("%s ",log_maskmap[i].name);
|
||||
prnt("\n\n");
|
||||
proccmd_show("loglvl",debug,prnt);
|
||||
proccmd_show("logopt",debug,prnt);
|
||||
proccmd_show("dbgopt",debug,prnt);
|
||||
prnt("Available log levels: \n ");
|
||||
for (int i = 0; log_level_names[i].name != NULL; i++)
|
||||
prnt("%s ", log_level_names[i].name);
|
||||
prnt("\n\n");
|
||||
prnt("Available display options: \n ");
|
||||
for (int i = 0; log_options[i].name != NULL; i++)
|
||||
prnt("%s ", log_options[i].name);
|
||||
prnt("\n\n");
|
||||
prnt("Available debug and dump options: \n ");
|
||||
for (int i = 0; log_maskmap[i].name != NULL; i++)
|
||||
prnt("%s ", log_maskmap[i].name);
|
||||
prnt("\n\n");
|
||||
proccmd_show("loglvl", debug, prnt);
|
||||
proccmd_show("logopt", debug, prnt);
|
||||
proccmd_show("dbgopt", debug, prnt);
|
||||
}
|
||||
else if (strcasestr(logsubcmd,"help") != NULL) {
|
||||
prnt(PROCCMD_LOG_HELP_STRING);
|
||||
@@ -569,40 +583,40 @@ int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2);
|
||||
|
||||
l=sscanf(logsubcmd,"%m[^'_']_%ms",&logparam,&opt);
|
||||
if (l == 2 && strcmp(logparam,"print") == 0){
|
||||
optbit=map_str_to_int(log_options,opt);
|
||||
if (optbit < 0) {
|
||||
prnt("option %s unknown\n",opt);
|
||||
} else {
|
||||
if (idx1 > 0)
|
||||
SET_LOG_OPTION(optbit);
|
||||
else
|
||||
CLEAR_LOG_OPTION(optbit);
|
||||
proccmd_show("logopt",debug,prnt);
|
||||
}
|
||||
optbit = map_str_to_int(log_options, opt);
|
||||
if (optbit < 0) {
|
||||
prnt("option %s unknown\n", opt);
|
||||
} else {
|
||||
if (idx1 > 0)
|
||||
SET_LOG_OPTION(optbit);
|
||||
else
|
||||
CLEAR_LOG_OPTION(optbit);
|
||||
proccmd_show("logopt", debug, prnt);
|
||||
}
|
||||
}
|
||||
else if (l == 2 && strcmp(logparam,"debug") == 0){
|
||||
optbit=map_str_to_int(log_maskmap,opt);
|
||||
if (optbit < 0) {
|
||||
prnt("module %s unknown\n",opt);
|
||||
} else {
|
||||
if (idx1 > 0)
|
||||
SET_LOG_DEBUG(optbit);
|
||||
else
|
||||
CLEAR_LOG_DEBUG(optbit);
|
||||
proccmd_show("dbgopt",debug,prnt);
|
||||
}
|
||||
optbit = map_str_to_int(log_maskmap, opt);
|
||||
if (optbit < 0) {
|
||||
prnt("module %s unknown\n", opt);
|
||||
} else {
|
||||
if (idx1 > 0)
|
||||
SET_LOG_DEBUG(optbit);
|
||||
else
|
||||
CLEAR_LOG_DEBUG(optbit);
|
||||
proccmd_show("dbgopt", debug, prnt);
|
||||
}
|
||||
}
|
||||
else if (l == 2 && strcmp(logparam,"dump") == 0){
|
||||
optbit=map_str_to_int(log_maskmap,opt);
|
||||
if (optbit < 0) {
|
||||
prnt("module %s unknown\n",opt);
|
||||
} else {
|
||||
if (idx1 > 0)
|
||||
SET_LOG_DUMP(optbit);
|
||||
else
|
||||
CLEAR_LOG_DUMP(optbit);
|
||||
proccmd_show("dump", debug, prnt);
|
||||
}
|
||||
optbit = map_str_to_int(log_maskmap, opt);
|
||||
if (optbit < 0) {
|
||||
prnt("module %s unknown\n", opt);
|
||||
} else {
|
||||
if (idx1 > 0)
|
||||
SET_LOG_DUMP(optbit);
|
||||
else
|
||||
CLEAR_LOG_DUMP(optbit);
|
||||
proccmd_show("dump", debug, prnt);
|
||||
}
|
||||
}
|
||||
if (logparam != NULL) free(logparam);
|
||||
if (opt != NULL) free(opt);
|
||||
@@ -620,11 +634,11 @@ int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2);
|
||||
prnt("l=%i, %s %s\n",l,((logparam==NULL)?"\"\"":logparam), ((tmpstr==NULL)?"\"\"":tmpstr));
|
||||
if (l ==2 ) {
|
||||
if (strcmp(logparam,"level") == 0) {
|
||||
level=map_str_to_int(log_level_names,tmpstr);
|
||||
if (level < 0) {
|
||||
prnt("level %s unknown\n",tmpstr);
|
||||
level=OAILOG_DISABLE - 1;
|
||||
}
|
||||
level = map_str_to_int(log_level_names, tmpstr);
|
||||
if (level < 0) {
|
||||
prnt("level %s unknown\n", tmpstr);
|
||||
level = OAILOG_DISABLE - 1;
|
||||
}
|
||||
} else {
|
||||
prnt("%s%s unknown log sub command \n",logparam, tmpstr);
|
||||
}
|
||||
@@ -650,7 +664,7 @@ int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2);
|
||||
if (level >= OAILOG_DISABLE)
|
||||
set_log(i, level);
|
||||
else if ( enable == 1)
|
||||
set_log(i,g_log->log_component[i].savedlevel);
|
||||
set_log(i, g_log->log_rarely_used[i].savedlevel);
|
||||
else if ( filelog == 1 ) {
|
||||
set_component_filelog(i);
|
||||
} else if ( filelog == 0 ) {
|
||||
|
||||
+16
-3
@@ -18,10 +18,23 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#define sizeofArray(a) (sizeof(a)/sizeof(*(a)))
|
||||
#define CHECK_INDEX(ARRAY, INDEX) assert((INDEX) < sizeofArray(ARRAY))
|
||||
|
||||
// Prevent double evaluation in max macro
|
||||
#define cmax(a,b) ({ __typeof__ (a) _a = (a); \
|
||||
__typeof__ (b) _b = (b); \
|
||||
_a > _b ? _a : _b; })
|
||||
|
||||
|
||||
#define cmax3(a,b,c) ( cmax(cmax(a,b), c) )
|
||||
|
||||
// Prevent double evaluation in min macro
|
||||
#define cmin(a,b) ({ __typeof__ (a) _a = (a); \
|
||||
__typeof__ (b) _b = (b); \
|
||||
_a < _b ? _a : _b; })
|
||||
|
||||
|
||||
|
||||
#define cmax(a,b) ((a>b) ? (a) : (b))
|
||||
#define cmax3(a,b,c) ((cmax(a,b)>c) ? (cmax(a,b)) : (c))
|
||||
#define cmin(a,b) ((a<b) ? (a) : (b))
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifdef min
|
||||
|
||||
@@ -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
|
||||
|
||||
```
|
||||
@@ -902,7 +902,6 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../common/utils/LOG/vcd_signal_dumper.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../common/utils/LOG/log.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../common/utils/LOG/log.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../common/utils/LOG/log_extern.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../common/utils/time_stat.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../common/utils/ocp_itti/all_msg.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../common/utils/ocp_itti/intertask_interface.h \
|
||||
|
||||
@@ -45,7 +45,7 @@ Please install and configure OAI CN5G as described here:
|
||||
|
||||
|
||||
## 2.2 SIM Card
|
||||
Program SIM Card with [Open Cells Project](https://open-cells.com/) application [uicc-v3.2](https://open-cells.com/d5138782a8739209ec5760865b1e53b0/uicc-v3.2.tgz).
|
||||
Program UICC/SIM Card with [Open Cells Project](https://open-cells.com/) programming tool [uicc-v3.3](https://open-cells.com/d5138782a8739209ec5760865b1e53b0/uicc-v3.3.tgz).
|
||||
|
||||
```bash
|
||||
sudo ./program_uicc --adm 12345678 --imsi 001010000000001 --isdn 00000001 --acc 0001 --key fec86ba6eb707ed08905757b1bb44b8f --opc C42449363BBAD02B66D16BC975D77CC1 -spn "OpenAirInterface" --authenticate
|
||||
|
||||
@@ -120,7 +120,7 @@ sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band
|
||||
### RFsimulator in FR2
|
||||
```bash
|
||||
cd ~/openairinterface5g/cmake_targets/ran_build/build
|
||||
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band257.32prb.usrpx410.conf --rfsim
|
||||
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band257.u3.32prb.usrpx410.conf --rfsim
|
||||
```
|
||||
|
||||
# 5. OAI UE
|
||||
|
||||
+64
-34
@@ -22,7 +22,8 @@
|
||||
| nokiabox | 172.21.19.39 | _None_ | gNB (Nokia), 5GC | _Nokia RF integrated_ |
|
||||
| avra | 172.21.16.124 | CI-Avra-Usage | gNB (n78) | AW2S Jaguar (192.168.80.239) |
|
||||
| orion | 172.21.16.134 | CI-Orion-Build-Sanity-Check-Deploy-Test, CI-Orion-DsTester-Deploy-Test | Build | |
|
||||
| bellatrix | 172.21.16.104 | CI-Bellatrix-RAN-Docker | Static Code Analysis | -- |
|
||||
| aerial2 | 172.21.16.131 | CI-Aerial2-Usage | gNB (PNF/Nvidia CUBB + VNF) | Foxconn RU, _Nvidia Aerial SDK integrated_ |
|
||||
| sphex | 172.21.17.54 | CI-Sphex-Usage | Quectel | Quectel module |
|
||||
|
||||
Note: The available resources, and their current usage, is indicated here:
|
||||
- [Lockable resources of jenkins-oai](https://jenkins-oai.eurecom.fr/lockable-resources/):
|
||||
@@ -188,6 +189,10 @@ information on how the images are built.
|
||||
~5G-NR
|
||||
- 5G-NR SA test setup: gNB on avra(RHEL9.2) + N310, OAIUE on caracal(RHEL9.1) + N310, OAI CN5G
|
||||
- OpenShift cluster for CN deployment and container images for gNB and UE deployment
|
||||
- [RAN-SA-AERIAL-CN5G](https://jenkins-oai.eurecom.fr/job/RAN-SA-AERIAL-CN5G/)
|
||||
~5G-NR
|
||||
- 5G-NR SA test setup: OAI VNF + PNF/NVIDIA CUBB on Aerial2 (U22) + Foxconn RU, COTS UE (Quctel RM500Q), OAI CN5G
|
||||
- container images for gNB deployment
|
||||
|
||||
### RAN-CI-NSA-Trigger
|
||||
|
||||
@@ -250,7 +255,44 @@ Some tests are run from source (e.g.
|
||||
`ci-scripts/xml_files/gnb_phytest_usrp_run.xml`), which directly give the
|
||||
options they are run with.
|
||||
|
||||
## How to retrieve core dumps (for CI team members)
|
||||
## How to debug CI failures
|
||||
|
||||
It is possible to debug CI failures using the generated core dump and the image
|
||||
used for the run. A script is provided (see developer instructions below) that,
|
||||
provided the core dump file, container image, and the source tree, executes
|
||||
`gdb` inside the container; using the core dump information, a developer can
|
||||
investigate the cause of failure.
|
||||
|
||||
### Developer instructions
|
||||
|
||||
The CI team will send you a docker image and a core dump file, and the commit
|
||||
as of which the pipeline failed. Let's assume the coredump is stored at
|
||||
`/tmp/coredump.tar.xz`, and the image is in `/tmp/oai-nr-ue.tar.gz`. First, you
|
||||
should check out the corresponding branch (or directly the commit), let's say
|
||||
in `~/oai-branch-fail`. Now, unpack the core dump, load the image into docker,
|
||||
and use the script [`docker/debug_core_image.sh`](../docker/debug_core_image.sh)
|
||||
to open gdb, as follows:
|
||||
|
||||
```
|
||||
cd /tmp
|
||||
tar -xJf /tmp/coredump.tar.xz
|
||||
docker load < /tmp/oai-nr-ue.tar.gz
|
||||
~/oai-branch-fail/docker/debug_core_image.sh <image> /tmp/coredump ~/oai-branch-fail
|
||||
```
|
||||
|
||||
where you replace `<image>` with the image loaded in `docker load`. The script
|
||||
will start the container and open gdb; you should see information about where
|
||||
the failure (e.g., segmentation fault) happened. If you just see `??`, the core
|
||||
dump and container image don't match. Be also on the lookout for the
|
||||
corresponding message from gdb:
|
||||
```
|
||||
warning: core file may not match specified executable file.
|
||||
```
|
||||
|
||||
Once you quit `gdb`, the container image will be removed automatically.
|
||||
|
||||
|
||||
### CI team instructions
|
||||
|
||||
The entrypoint scripts of all containers print the core pattern that is used on
|
||||
the running machine. Search for `core_pattern` at the start of the container
|
||||
@@ -262,19 +304,14 @@ logs to retrieve the possible location. Possible locations might be:
|
||||
- abrt: see [documentation](https://abrt.readthedocs.io/en/latest/usage.html)
|
||||
- apport: see [documentation](https://wiki.ubuntu.com/Apport)
|
||||
|
||||
You furthermore have to extract the executable that caused the core dump.
|
||||
Download the container image, and extract, e.g.:
|
||||
See below for instructions on how to retrieve the core dump. Further, download
|
||||
the image and store it to a file using `docker save`. Make sure to pick the
|
||||
right image (Ubuntu or RHEL)!
|
||||
|
||||
```
|
||||
docker create --name c1 porcepix.sboai.cs.eurecom.fr/oai-gnb:develop-c99db698
|
||||
docker cp c1:/opt/oai-gnb/bin/nr-softmodem /tmp
|
||||
docker rm c1
|
||||
```
|
||||
|
||||
### Core dump in a file
|
||||
#### Core dump in a file
|
||||
|
||||
**This is not recommended, as files could pile up and fill the system disk
|
||||
completely!** Prefer systemd or abrt instead.
|
||||
completely!** Prefer another method further down.
|
||||
|
||||
If the core pattern is a path: it should at least include the time in the
|
||||
pattern name (suggested pattern: `/tmp/core.%e.%p.%t`) to correlate the time
|
||||
@@ -282,38 +319,31 @@ the segfault occurred with the CI logs. If you identified the core dump,
|
||||
copy the core dump from that machine; if identification is difficult, consider
|
||||
rerunning the pipeline.
|
||||
|
||||
### Core dump via systemd
|
||||
#### Core dump via systemd
|
||||
|
||||
Run this command to list all core dumps:
|
||||
Use the first command to list all core dumps. Scroll down to the core dump of
|
||||
interest (it lists the executables in the last column; use the time to
|
||||
correlate the segfault and the CI run). Take the PID of the executable (first
|
||||
column after the time). Dump the core dump to a location of your choice.
|
||||
|
||||
```
|
||||
sudo coredumpctl list
|
||||
```
|
||||
|
||||
Scroll to the end and find the core dump of interest (it lists the executables
|
||||
in the last column; use the time to correlate the segfault and the CI run).
|
||||
Take the PID of the executable (first column after the time). Dump the core
|
||||
dump to a location of your choice:
|
||||
|
||||
```
|
||||
sudo coredumpctl dump <PID> > /tmp/coredump
|
||||
```
|
||||
|
||||
### Core dump via abrt (automatic bug reporting tool)
|
||||
#### Core dump via abrt (automatic bug reporting tool)
|
||||
|
||||
TBD: use the documentation page for the moment.
|
||||
|
||||
### Core dump via apport
|
||||
|
||||
On Ubuntu machines, apport first needs to be enabled to collect core dumps:
|
||||
#### Core dump via apport
|
||||
|
||||
I did not find an easy way to use apport. Anyway, the systemd approach works
|
||||
fine. So remove apport, install systemd-coredump, and verify it is the new
|
||||
coredump handler:
|
||||
```
|
||||
sudo systemctl enable apport.service
|
||||
```
|
||||
|
||||
and [needs to be enabled](https://wiki.ubuntu.com/Apport#How_to_enable_apport).
|
||||
Then, show a list of core dumps using
|
||||
|
||||
```
|
||||
sudo apport-cli
|
||||
sudo systemctl stop apport
|
||||
sudo systemctl mask --now apport
|
||||
sudo apt install systemd-coredump
|
||||
# Verify this changed the core pattern to a pipe to systemd-coredump
|
||||
sysctl kernel.core_pattern
|
||||
```
|
||||
|
||||
@@ -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"]
|
||||
@@ -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"]
|
||||
Executable
+56
@@ -0,0 +1,56 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ $# -ne 3 ]; then
|
||||
echo "usage: $0 <image> <coredump> <path-to-sources>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
die() {
|
||||
echo $1
|
||||
exit 1
|
||||
}
|
||||
|
||||
IMAGE=$1
|
||||
COREDUMP=$2
|
||||
SOURCES=$3
|
||||
|
||||
set -x
|
||||
|
||||
# the image/build_oai builds in cmake_targets/ran_build/build, so source
|
||||
# information is relative to this path. In case the user did not compile on
|
||||
# their computer, this directory will not exist. still allow to find it by
|
||||
# creating it
|
||||
BUILD_DIR=$SOURCES/cmake_targets/ran_build/build
|
||||
mkdir -p $BUILD_DIR || die "cannot create $BUILD_DIR: is $SOURCES valid?"
|
||||
|
||||
# check if coredump is valid file
|
||||
[ -f $COREDUMP ] || die "no such file: $COREDUMP"
|
||||
|
||||
# check if image exists, and determine type (gnb, nr-ue) for correct invocation
|
||||
# of gdb
|
||||
docker image inspect $IMAGE > /dev/null || exit 1
|
||||
if [ $(grep "oai-gnb:" <<< $IMAGE) ] || [ $(grep "oai-gnb-aerial:" <<< $IMAGE) ]; then
|
||||
EXEC=bin/nr-softmodem
|
||||
TYPEPATH=oai-gnb
|
||||
elif [ $(grep "oai-nr-ue:" <<< $IMAGE) ]; then
|
||||
EXEC=bin/nr-uesoftmodem
|
||||
TYPEPATH=oai-nr-ue
|
||||
elif [ $(grep "oai-enb:" <<< $IMAGE) ]; then
|
||||
EXEC=bin/lte-softmodem
|
||||
TYPEPATH=oai-enb
|
||||
elif [ $(grep "oai-lte-ue:" <<< $IMAGE) ]; then
|
||||
EXEC=bin/lte-uesoftmodem
|
||||
TYPEPATH=oai-lte-ue
|
||||
else
|
||||
die "cannot determine if image is gnb or nr-ue: must match \"oai-gnb:\" or \"oai-nr-ue:\""
|
||||
fi
|
||||
|
||||
# run gdb inside a container. We mount the coredump and the sources inside the
|
||||
# container, and run gdb with the core dump, the correct executable, and using
|
||||
# the source directory to show correct line numbers
|
||||
docker run --rm -it \
|
||||
-v $COREDUMP:/tmp/coredump \
|
||||
-v $SOURCES:/opt/$TYPEPATH/src \
|
||||
--entrypoint bash \
|
||||
$IMAGE \
|
||||
-c "gdb --dir=src/cmake_targets/ran_build/build $EXEC /tmp/coredump"
|
||||
@@ -474,9 +474,10 @@ int main ( int argc, char **argv )
|
||||
// to make a graceful exit when ctrl-c is pressed
|
||||
set_softmodem_sighandler();
|
||||
#ifndef PACKAGE_VERSION
|
||||
# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
|
||||
#define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
|
||||
#endif
|
||||
LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
|
||||
// strdup to put the sring in the core file for post mortem identification
|
||||
LOG_I(HW, "Version: %s\n", strdup(PACKAGE_VERSION));
|
||||
|
||||
/* Read configuration */
|
||||
if (RC.nb_inst > 0) {
|
||||
|
||||
@@ -76,9 +76,6 @@
|
||||
#include "lte-softmodem.h"
|
||||
#include "executables/softmodem-common.h"
|
||||
|
||||
/* temporary compilation wokaround (UE/eNB split */
|
||||
|
||||
|
||||
pthread_cond_t nfapi_sync_cond;
|
||||
pthread_mutex_t nfapi_sync_mutex;
|
||||
int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex
|
||||
@@ -579,9 +576,10 @@ int main( int argc, char **argv ) {
|
||||
// to make a graceful exit when ctrl-c is pressed
|
||||
set_softmodem_sighandler();
|
||||
#ifndef PACKAGE_VERSION
|
||||
# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
|
||||
#define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
|
||||
#endif
|
||||
LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
|
||||
// strdup to put the sring in the core file for post mortem identification
|
||||
LOG_I(HW, "Version: %s\n", strdup(PACKAGE_VERSION));
|
||||
|
||||
// init the parameters
|
||||
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
|
||||
|
||||
@@ -160,11 +160,11 @@ int main ( int argc, char **argv )
|
||||
T_Config_Init();
|
||||
#endif
|
||||
printf("configuring for RRU\n");
|
||||
|
||||
#ifndef PACKAGE_VERSION
|
||||
# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
|
||||
#define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
|
||||
#endif
|
||||
LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
|
||||
// strdup to put the sring in the core file for post mortem identification
|
||||
LOG_I(HW, "Version: %s\n", strdup(PACKAGE_VERSION));
|
||||
|
||||
/* Read configuration */
|
||||
|
||||
|
||||
@@ -157,9 +157,10 @@ int main(int argc, char **argv)
|
||||
}
|
||||
logInit();
|
||||
#ifndef PACKAGE_VERSION
|
||||
# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
|
||||
#define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
|
||||
#endif
|
||||
LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
|
||||
// strdup to put the sring in the core file for post mortem identification
|
||||
LOG_I(HW, "Version: %s\n", strdup(PACKAGE_VERSION));
|
||||
set_softmodem_sighandler();
|
||||
itti_init(TASK_MAX, tasks_info);
|
||||
int rc;
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
#include "common/ran_context.h"
|
||||
#include "RRC/LTE/rrc_extern.h"
|
||||
#include "PHY_INTERFACE/phy_interface.h"
|
||||
#include "common/utils/LOG/log_extern.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "UTIL/OTG/otg_tx.h"
|
||||
#include "UTIL/OTG/otg_externs.h"
|
||||
#include "UTIL/MATH/oml.h"
|
||||
@@ -117,7 +117,10 @@ static void tx_func(void *param)
|
||||
int slot_rx = info->slot_rx;
|
||||
int absslot_tx = info->timestamp_tx / info->gNB->frame_parms.get_samples_per_slot(slot_tx, &info->gNB->frame_parms);
|
||||
int absslot_rx = absslot_tx - info->gNB->RU_list[0]->sl_ahead;
|
||||
|
||||
if (absslot_rx < 0) {
|
||||
LOG_W(NR_PHY, "Slot ahead %d is larger than absslot_tx %d. Cannot start TX yet.\n", info->gNB->RU_list[0]->sl_ahead, absslot_tx);
|
||||
return;
|
||||
}
|
||||
LOG_D(NR_PHY, "%d.%d running tx_func\n", frame_tx, slot_tx);
|
||||
PHY_VARS_gNB *gNB = info->gNB;
|
||||
module_id_t module_id = gNB->Mod_id;
|
||||
@@ -394,7 +397,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);
|
||||
|
||||
}
|
||||
|
||||
+8
-30
@@ -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;
|
||||
@@ -1331,11 +1331,10 @@ void *ru_thread( void *param ) {
|
||||
reset_meas(&ru->tx_fhaul);
|
||||
}
|
||||
proc->timestamp_tx = proc->timestamp_rx;
|
||||
int sl=proc->tti_tx;
|
||||
for (int slidx=0;slidx<ru->sl_ahead;slidx++)
|
||||
proc->timestamp_tx += fp->get_samples_per_slot((sl+slidx)%fp->slots_per_frame,fp);
|
||||
proc->frame_tx = (proc->tti_rx > (fp->slots_per_frame - 1 - (ru->sl_ahead))) ? (proc->frame_rx + 1) & 1023 : proc->frame_rx;
|
||||
for (int i = proc->tti_rx; i < proc->tti_rx + ru->sl_ahead; i++)
|
||||
proc->timestamp_tx += fp->get_samples_per_slot(i % fp->slots_per_frame, fp);
|
||||
proc->tti_tx = (proc->tti_rx + ru->sl_ahead) % fp->slots_per_frame;
|
||||
proc->frame_tx = proc->tti_rx > proc->tti_tx ? (proc->frame_rx + 1) & 1023 : proc->frame_rx;
|
||||
int absslot_rx = proc->timestamp_rx/fp->get_samples_per_slot(proc->tti_rx,fp);
|
||||
int rt_prof_idx = absslot_rx % RT_PROF_DEPTH;
|
||||
clock_gettime(CLOCK_MONOTONIC,&ru->rt_ru_profiling.return_RU_south_in[rt_prof_idx]);
|
||||
@@ -1349,27 +1348,6 @@ void *ru_thread( void *param ) {
|
||||
if (ru->idx != 0)
|
||||
proc->frame_tx = (proc->frame_tx + proc->frame_offset) & 1023;
|
||||
|
||||
LOG_D(NR_PHY, "In %d.%d: Checking L1 status\n", proc->frame_rx, proc->tti_rx);
|
||||
for (int n = 0; n < RU_RX_SLOT_DEPTH; n++)
|
||||
LOG_D(NR_PHY, "slot n %d => %d\n", n, rx_tti_busy[n]);
|
||||
// handle potential race by blocking if rxdataF is being used by L1
|
||||
// collect all pending msg in L1 return fifo to not down the memory is available (rx_tti_busy[slot] boolean array)
|
||||
notifiedFIFO_elt_t *res = pollNotifiedFIFO(&gNB->L1_rx_out);
|
||||
LOG_D(NR_PHY, "%d.%d Polling L1_rx_out %p\n", proc->frame_rx, proc->tti_rx, res);
|
||||
while (res) {
|
||||
processingData_L1_t *info = (processingData_L1_t *)NotifiedFifoData(res);
|
||||
LOG_D(NR_PHY,
|
||||
"%d.%d res %d.%d completed, clearing %d\n",
|
||||
proc->frame_rx,
|
||||
proc->tti_rx,
|
||||
info->frame_rx,
|
||||
info->slot_rx,
|
||||
info->slot_rx % RU_RX_SLOT_DEPTH);
|
||||
|
||||
rx_tti_busy[info->slot_rx % RU_RX_SLOT_DEPTH] = false;
|
||||
res = pollNotifiedFIFO(&gNB->L1_rx_out);
|
||||
}
|
||||
LOG_D(NR_PHY, "%d.%d Done polling\n", proc->frame_rx, proc->tti_rx);
|
||||
// do RX front-end processing (frequency-shift, dft) if needed
|
||||
int slot_type = nr_slot_select(cfg, proc->frame_rx, proc->tti_rx);
|
||||
if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) {
|
||||
@@ -1379,6 +1357,7 @@ void *ru_thread( void *param ) {
|
||||
LOG_D(NR_PHY, "%d.%d Waiting to access RX slot %d\n", proc->frame_rx, proc->tti_rx, proc->tti_rx % RU_RX_SLOT_DEPTH);
|
||||
// now we block and wait our slot memory zone is freed from previous slot processing
|
||||
// as we can get other slots ending, we loop on the queue
|
||||
notifiedFIFO_elt_t *res = NULL;
|
||||
while (not_done) {
|
||||
res = pullNotifiedFIFO(&gNB->L1_rx_out);
|
||||
if (!res)
|
||||
@@ -1414,17 +1393,16 @@ void *ru_thread( void *param ) {
|
||||
proc->tti_rx * gNB->frame_parms.samples_per_slot_wCP);
|
||||
|
||||
// Do PRACH RU processing
|
||||
int prach_id=find_nr_prach_ru(ru,proc->frame_rx,proc->tti_rx,SEARCH_EXIST);
|
||||
uint8_t prachStartSymbol,N_dur;
|
||||
int prach_id = find_nr_prach_ru(ru, proc->frame_rx, proc->tti_rx, SEARCH_EXIST);
|
||||
if (prach_id>=0) {
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 );
|
||||
|
||||
T(T_GNB_PHY_PRACH_INPUT_SIGNAL, T_INT(proc->frame_rx), T_INT(proc->tti_rx), T_INT(0),
|
||||
T_BUFFER(&ru->common.rxdata[0][fp->get_samples_slot_timestamp(proc->tti_rx-1,fp,0)]/*-ru->N_TA_offset*/, fp->get_samples_per_slot(proc->tti_rx,fp)*4*2));
|
||||
N_dur = get_nr_prach_duration(ru->prach_list[prach_id].fmt);
|
||||
int N_dur = get_nr_prach_duration(ru->prach_list[prach_id].fmt);
|
||||
|
||||
for (int prach_oc = 0; prach_oc<ru->prach_list[prach_id].num_prach_ocas; prach_oc++) {
|
||||
prachStartSymbol = ru->prach_list[prach_id].prachStartSymbol+prach_oc*N_dur;
|
||||
int prachStartSymbol = ru->prach_list[prach_id].prachStartSymbol + prach_oc * N_dur;
|
||||
//comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}.
|
||||
rx_nr_prach_ru(ru,
|
||||
ru->prach_list[prach_id].fmt, //could also use format
|
||||
|
||||
+19
-14
@@ -80,13 +80,14 @@ 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"
|
||||
#endif
|
||||
|
||||
|
||||
pthread_cond_t nfapi_sync_cond;
|
||||
pthread_mutex_t nfapi_sync_mutex;
|
||||
int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex
|
||||
@@ -286,9 +287,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);
|
||||
@@ -663,10 +670,10 @@ int main( int argc, char **argv ) {
|
||||
}
|
||||
}
|
||||
#ifndef PACKAGE_VERSION
|
||||
# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
|
||||
#define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
|
||||
#endif
|
||||
LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
|
||||
|
||||
// strdup to put the sring in the core file for post mortem identification
|
||||
LOG_I(HW, "Version: %s\n", strdup(PACKAGE_VERSION));
|
||||
|
||||
// don't create if node doesn't connect to RRC/S1/GTP
|
||||
const ngran_node_t node_type = get_node_type();
|
||||
@@ -679,15 +686,12 @@ int main( int argc, char **argv ) {
|
||||
AssertFatal(ret == 0, "cannot create ITTI tasks\n");
|
||||
}
|
||||
|
||||
// init UE_PF_PO and mutex lock
|
||||
pthread_mutex_init(&ue_pf_po_mutex, NULL);
|
||||
memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs);
|
||||
mlockall(MCL_CURRENT | MCL_FUTURE);
|
||||
pthread_cond_init(&sync_cond,NULL);
|
||||
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 +710,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 +753,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 +784,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 {
|
||||
@@ -823,7 +829,6 @@ int main( int argc, char **argv ) {
|
||||
pthread_mutex_destroy(&sync_mutex);
|
||||
pthread_cond_destroy(&nfapi_sync_cond);
|
||||
pthread_mutex_destroy(&nfapi_sync_mutex);
|
||||
pthread_mutex_destroy(&ue_pf_po_mutex);
|
||||
|
||||
// *** Handle per CC_id openair0
|
||||
|
||||
|
||||
+88
-84
@@ -439,11 +439,13 @@ static void UE_synch(void *arg) {
|
||||
|
||||
uint64_t dl_carrier, ul_carrier;
|
||||
nr_get_carrier_frequencies(UE, &dl_carrier, &ul_carrier);
|
||||
|
||||
if (nr_initial_sync(&syncD->proc, UE, 2, get_softmodem_params()->sa) == 0) {
|
||||
nr_initial_sync_t ret = nr_initial_sync(&syncD->proc, UE, 2, get_softmodem_params()->sa);
|
||||
if (!ret.cell_notdetected) {
|
||||
syncD->rx_offset = ret.rx_offset;
|
||||
freq_offset = UE->common_vars.freq_offset; // frequency offset computed with pss in initial sync
|
||||
hw_slot_offset = ((UE->rx_offset<<1) / UE->frame_parms.samples_per_subframe * UE->frame_parms.slots_per_subframe) +
|
||||
round((float)((UE->rx_offset<<1) % UE->frame_parms.samples_per_subframe)/UE->frame_parms.samples_per_slot0);
|
||||
hw_slot_offset =
|
||||
((ret.rx_offset << 1) / UE->frame_parms.samples_per_subframe * UE->frame_parms.slots_per_subframe)
|
||||
+ round((float)((ret.rx_offset << 1) % UE->frame_parms.samples_per_subframe) / UE->frame_parms.samples_per_slot0);
|
||||
|
||||
// rerun with new cell parameters and frequency-offset
|
||||
// todo: the freq_offset computed on DL shall be scaled before being applied to UL
|
||||
@@ -462,7 +464,6 @@ static void UE_synch(void *arg) {
|
||||
else
|
||||
UE->is_synchronized = 1;
|
||||
} else {
|
||||
|
||||
if (UE->UE_scan_carrier == 1) {
|
||||
|
||||
if (freq_offset >= 0)
|
||||
@@ -607,8 +608,9 @@ void processSlotTX(void *arg)
|
||||
RU_write(rxtxD);
|
||||
}
|
||||
|
||||
static void UE_dl_preprocessing(PHY_VARS_NR_UE *UE, const UE_nr_rxtx_proc_t *proc, int *tx_wait_for_dlsch, nr_phy_data_t *phy_data)
|
||||
static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE, const UE_nr_rxtx_proc_t *proc, int *tx_wait_for_dlsch, nr_phy_data_t *phy_data)
|
||||
{
|
||||
int sampleShift = 0;
|
||||
if (IS_SOFTMODEM_NOS1 || get_softmodem_params()->sa) {
|
||||
|
||||
// Start synchronization with a target gNB
|
||||
@@ -636,20 +638,16 @@ static void UE_dl_preprocessing(PHY_VARS_NR_UE *UE, const UE_nr_rxtx_proc_t *pro
|
||||
UE->if_inst->dl_indication(&dl_indication);
|
||||
}
|
||||
|
||||
uint64_t a=rdtsc_oai();
|
||||
pbch_pdcch_processing(UE, proc, phy_data);
|
||||
sampleShift = pbch_pdcch_processing(UE, proc, phy_data);
|
||||
if (phy_data->dlsch[0].active && phy_data->dlsch[0].rnti_type == TYPE_C_RNTI_) {
|
||||
// indicate to tx thread to wait for DLSCH decoding
|
||||
const int ack_nack_slot = (proc->nr_slot_rx + phy_data->dlsch[0].dlsch_config.k1_feedback) % UE->frame_parms.slots_per_frame;
|
||||
LOG_D(NR_PHY, "Adding one event to wait after decoding slot %d, for futre tx slot %d\n", proc->nr_slot_rx, ack_nack_slot);
|
||||
tx_wait_for_dlsch[ack_nack_slot]++;
|
||||
}
|
||||
|
||||
LOG_D(PHY, "In %s: slot %d, time %llu\n", __FUNCTION__, proc->nr_slot_rx, (rdtsc_oai()-a)/3500);
|
||||
}
|
||||
|
||||
ue_ta_procedures(UE, proc->nr_slot_tx, proc->frame_tx);
|
||||
return;
|
||||
return sampleShift;
|
||||
}
|
||||
|
||||
void UE_dl_processing(void *arg) {
|
||||
@@ -710,37 +708,39 @@ void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, bool toTrash)
|
||||
|
||||
}
|
||||
|
||||
void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
|
||||
|
||||
LOG_I(PHY,"Resynchronizing RX by %d samples\n",UE->rx_offset);
|
||||
|
||||
if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) {
|
||||
// Resynchonize by slot (will work with numerology 1 only)
|
||||
for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe/2 ) {
|
||||
int unitTransfer=size>UE->frame_parms.samples_per_subframe/2 ? UE->frame_parms.samples_per_subframe/2 : size ;
|
||||
AssertFatal(unitTransfer ==
|
||||
UE->rfdevice.trx_read_func(&UE->rfdevice,
|
||||
timestamp,
|
||||
(void **)UE->common_vars.rxdata,
|
||||
unitTransfer,
|
||||
UE->frame_parms.nb_antennas_rx),"");
|
||||
}
|
||||
} else {
|
||||
*timestamp += UE->frame_parms.get_samples_per_slot(1,&UE->frame_parms);
|
||||
for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe ) {
|
||||
int unitTransfer=size>UE->frame_parms.samples_per_subframe ? UE->frame_parms.samples_per_subframe : size ;
|
||||
// we write before read because gNB waits for UE to write and both executions halt
|
||||
// this happens here as the read size is samples_per_subframe which is very much larger than samp_per_slot
|
||||
if (IS_SOFTMODEM_RFSIM) dummyWrite(UE,*timestamp, unitTransfer);
|
||||
AssertFatal(unitTransfer ==
|
||||
UE->rfdevice.trx_read_func(&UE->rfdevice,
|
||||
timestamp,
|
||||
(void **)UE->common_vars.rxdata,
|
||||
unitTransfer,
|
||||
UE->frame_parms.nb_antennas_rx),"");
|
||||
*timestamp += unitTransfer; // this does not affect the read but needed for RFSIM write
|
||||
}
|
||||
static void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, int rx_offset)
|
||||
{
|
||||
LOG_I(PHY, "Resynchronizing RX by %d samples\n", rx_offset);
|
||||
if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) {
|
||||
// Resynchonize by slot (will work with numerology 1 only)
|
||||
for (int size = rx_offset; size > 0; size -= UE->frame_parms.samples_per_subframe / 2) {
|
||||
int unitTransfer = size > UE->frame_parms.samples_per_subframe / 2 ? UE->frame_parms.samples_per_subframe / 2 : size;
|
||||
AssertFatal(unitTransfer
|
||||
== UE->rfdevice.trx_read_func(&UE->rfdevice,
|
||||
timestamp,
|
||||
(void **)UE->common_vars.rxdata,
|
||||
unitTransfer,
|
||||
UE->frame_parms.nb_antennas_rx),
|
||||
"");
|
||||
}
|
||||
} else {
|
||||
*timestamp += UE->frame_parms.get_samples_per_slot(1, &UE->frame_parms);
|
||||
for (int size = rx_offset; size > 0; size -= UE->frame_parms.samples_per_subframe) {
|
||||
int unitTransfer = size > UE->frame_parms.samples_per_subframe ? UE->frame_parms.samples_per_subframe : size;
|
||||
// we write before read because gNB waits for UE to write and both executions halt
|
||||
// this happens here as the read size is samples_per_subframe which is very much larger than samp_per_slot
|
||||
if (IS_SOFTMODEM_RFSIM)
|
||||
dummyWrite(UE, *timestamp, unitTransfer);
|
||||
AssertFatal(unitTransfer
|
||||
== UE->rfdevice.trx_read_func(&UE->rfdevice,
|
||||
timestamp,
|
||||
(void **)UE->common_vars.rxdata,
|
||||
unitTransfer,
|
||||
UE->frame_parms.nb_antennas_rx),
|
||||
"");
|
||||
*timestamp += unitTransfer; // this does not affect the read but needed for RFSIM write
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline int get_firstSymSamp(uint16_t slot, NR_DL_FRAME_PARMS *fp) {
|
||||
@@ -764,8 +764,6 @@ void *UE_thread(void *arg)
|
||||
//this thread should be over the processing thread to keep in real time
|
||||
PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg;
|
||||
// int tx_enabled = 0;
|
||||
openair0_timestamp timestamp = 0;
|
||||
openair0_timestamp writeTimestamp = 0;
|
||||
void *rxp[NB_ANTENNAS_RX];
|
||||
int start_rx_stream = 0;
|
||||
fapi_nr_config_request_t *cfg = &UE->nrUE_config;
|
||||
@@ -796,9 +794,10 @@ void *UE_thread(void *arg)
|
||||
for(int i=0; i < num_ind_fifo; i++) {
|
||||
initNotifiedFIFO(UE->tx_resume_ind_fifo + i);
|
||||
}
|
||||
|
||||
int shiftForNextFrame = 0;
|
||||
int intialSyncOffset = 0;
|
||||
openair0_timestamp sync_timestamp;
|
||||
while (!oai_exit) {
|
||||
|
||||
if (syncRunning) {
|
||||
notifiedFIFO_elt_t *res=tryPullTpool(&nf,&(get_nrUE_params()->Tpool));
|
||||
|
||||
@@ -806,25 +805,28 @@ void *UE_thread(void *arg)
|
||||
syncRunning=false;
|
||||
if (UE->is_synchronized) {
|
||||
decoded_frame_rx = mac->mib_frame;
|
||||
LOG_I(PHY,"UE synchronized decoded_frame_rx=%d UE->init_sync_frame=%d trashed_frames=%d\n",
|
||||
LOG_A(PHY,
|
||||
"UE synchronized! decoded_frame_rx=%d UE->init_sync_frame=%d trashed_frames=%d\n",
|
||||
decoded_frame_rx,
|
||||
UE->init_sync_frame,
|
||||
trashed_frames);
|
||||
// shift the frame index with all the frames we trashed meanwhile we perform the synch search
|
||||
decoded_frame_rx = (decoded_frame_rx + UE->init_sync_frame + trashed_frames) % MAX_FRAME_NUMBER;
|
||||
syncData_t *syncMsg = (syncData_t *)NotifiedFifoData(res);
|
||||
intialSyncOffset = syncMsg->rx_offset;
|
||||
}
|
||||
delNotifiedFIFO_elt(res);
|
||||
start_rx_stream=0;
|
||||
} else {
|
||||
if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) {
|
||||
// For IQ recorder/player we force synchronization to happen in 280 ms
|
||||
// For IQ recorder-player we force synchronization to happen in 280 ms
|
||||
while (trashed_frames != 28) {
|
||||
readFrame(UE, ×tamp, true);
|
||||
trashed_frames+=2;
|
||||
readFrame(UE, &sync_timestamp, true);
|
||||
trashed_frames += 2;
|
||||
}
|
||||
} else {
|
||||
readFrame(UE, ×tamp, true);
|
||||
trashed_frames+=2;
|
||||
readFrame(UE, &sync_timestamp, true);
|
||||
trashed_frames += 2;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -833,7 +835,7 @@ void *UE_thread(void *arg)
|
||||
AssertFatal(!syncRunning, "At this point synchronization can't be running\n");
|
||||
|
||||
if (!UE->is_synchronized) {
|
||||
readFrame(UE, ×tamp, false);
|
||||
readFrame(UE, &sync_timestamp, false);
|
||||
notifiedFIFO_elt_t *Msg = newNotifiedFIFO_elt(sizeof(syncData_t), 0, &nf, UE_synch);
|
||||
syncData_t *syncMsg = (syncData_t *)NotifiedFifoData(Msg);
|
||||
syncMsg->UE = UE;
|
||||
@@ -846,16 +848,16 @@ void *UE_thread(void *arg)
|
||||
|
||||
if (start_rx_stream == 0) {
|
||||
start_rx_stream=1;
|
||||
syncInFrame(UE, ×tamp);
|
||||
UE->rx_offset=0;
|
||||
UE->time_sync_cell=0;
|
||||
syncInFrame(UE, &sync_timestamp, intialSyncOffset);
|
||||
shiftForNextFrame = 0; // will be used to track clock drift
|
||||
// read in first symbol
|
||||
AssertFatal (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 ==
|
||||
UE->rfdevice.trx_read_func(&UE->rfdevice,
|
||||
×tamp,
|
||||
(void **)UE->common_vars.rxdata,
|
||||
UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0,
|
||||
UE->frame_parms.nb_antennas_rx),"");
|
||||
AssertFatal(UE->frame_parms.ofdm_symbol_size + UE->frame_parms.nb_prefix_samples0
|
||||
== UE->rfdevice.trx_read_func(&UE->rfdevice,
|
||||
&sync_timestamp,
|
||||
(void **)UE->common_vars.rxdata,
|
||||
UE->frame_parms.ofdm_symbol_size + UE->frame_parms.nb_prefix_samples0,
|
||||
UE->frame_parms.nb_antennas_rx),
|
||||
"");
|
||||
// we have the decoded frame index in the return of the synch process
|
||||
// and we shifted above to the first slot of next frame
|
||||
decoded_frame_rx++;
|
||||
@@ -871,7 +873,7 @@ void *UE_thread(void *arg)
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// start of normal case, the UE is in sync
|
||||
absolute_slot++;
|
||||
|
||||
int slot_nr = absolute_slot % nb_slot_frame;
|
||||
@@ -893,26 +895,21 @@ void *UE_thread(void *arg)
|
||||
|
||||
int firstSymSamp = get_firstSymSamp(slot_nr, &UE->frame_parms);
|
||||
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
|
||||
rxp[i] = (void *)&UE->common_vars.rxdata[i][firstSymSamp+
|
||||
UE->frame_parms.get_samples_slot_timestamp(slot_nr,&UE->frame_parms,0)];
|
||||
rxp[i] = (void *)&UE->common_vars
|
||||
.rxdata[i][firstSymSamp + UE->frame_parms.get_samples_slot_timestamp(slot_nr, &UE->frame_parms, 0)];
|
||||
|
||||
int readBlockSize, writeBlockSize;
|
||||
|
||||
readBlockSize = get_readBlockSize(slot_nr, &UE->frame_parms);
|
||||
writeBlockSize = UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX) % nb_slot_frame, &UE->frame_parms);
|
||||
if (UE->apply_timing_offset && (slot_nr == nb_slot_frame - 1)) {
|
||||
const int sampShift = -(UE->rx_offset>>1);
|
||||
readBlockSize -= sampShift;
|
||||
writeBlockSize -= sampShift;
|
||||
UE->apply_timing_offset = false;
|
||||
int iq_shift_to_apply = 0;
|
||||
if (slot_nr == nb_slot_frame - 1) {
|
||||
// we shift of half of measured drift, at each beginning of frame for both rx and tx
|
||||
iq_shift_to_apply = shiftForNextFrame;
|
||||
shiftForNextFrame = 0; // We will get a new measured offset if we decode PBCH
|
||||
}
|
||||
|
||||
AssertFatal(readBlockSize ==
|
||||
UE->rfdevice.trx_read_func(&UE->rfdevice,
|
||||
×tamp,
|
||||
rxp,
|
||||
readBlockSize,
|
||||
UE->frame_parms.nb_antennas_rx),"");
|
||||
const int readBlockSize = get_readBlockSize(slot_nr, &UE->frame_parms) - iq_shift_to_apply;
|
||||
openair0_timestamp rx_timestamp;
|
||||
AssertFatal(readBlockSize
|
||||
== UE->rfdevice.trx_read_func(&UE->rfdevice, &rx_timestamp, rxp, readBlockSize, UE->frame_parms.nb_antennas_rx),
|
||||
"");
|
||||
|
||||
if(slot_nr == (nb_slot_frame - 1)) {
|
||||
// read in first symbol of next frame and adjust for timing drift
|
||||
@@ -931,11 +928,13 @@ void *UE_thread(void *arg)
|
||||
}
|
||||
|
||||
// use previous timing_advance value to compute writeTimestamp
|
||||
writeTimestamp = timestamp +
|
||||
UE->frame_parms.get_samples_slot_timestamp(slot_nr,&UE->frame_parms,DURATION_RX_TO_TX)
|
||||
- firstSymSamp - UE->N_TA_offset - timing_advance;
|
||||
const openair0_timestamp writeTimestamp =
|
||||
rx_timestamp + UE->frame_parms.get_samples_slot_timestamp(slot_nr, &UE->frame_parms, DURATION_RX_TO_TX) - firstSymSamp
|
||||
- UE->N_TA_offset - timing_advance;
|
||||
|
||||
// but use current UE->timing_advance value to compute writeBlockSize
|
||||
int writeBlockSize =
|
||||
UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX) % nb_slot_frame, &UE->frame_parms) - iq_shift_to_apply;
|
||||
if (UE->timing_advance != timing_advance) {
|
||||
writeBlockSize -= UE->timing_advance - timing_advance;
|
||||
timing_advance = UE->timing_advance;
|
||||
@@ -948,7 +947,12 @@ void *UE_thread(void *arg)
|
||||
notifiedFIFO_elt_t *newRx = newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), curMsg.proc.nr_slot_rx, NULL, UE_dl_processing);
|
||||
nr_rxtx_thread_data_t *curMsgRx = (nr_rxtx_thread_data_t *)NotifiedFifoData(newRx);
|
||||
*curMsgRx = (nr_rxtx_thread_data_t){.proc = curMsg.proc, .UE = UE};
|
||||
UE_dl_preprocessing(UE, &curMsgRx->proc, tx_wait_for_dlsch, &curMsgRx->phy_data);
|
||||
int ret = UE_dl_preprocessing(UE, &curMsgRx->proc, tx_wait_for_dlsch, &curMsgRx->phy_data);
|
||||
if (ret)
|
||||
// if ret is 0, no rx_offset has been computed,
|
||||
// or the computed value is 0 = no offset to do
|
||||
// we store it to apply the drift compensation at beginning of next frame
|
||||
shiftForNextFrame = ret;
|
||||
pushTpool(&(get_nrUE_params()->Tpool), newRx);
|
||||
|
||||
// Start TX slot processing here. It runs in parallel with RX slot processing
|
||||
|
||||
@@ -497,11 +497,11 @@ int main(int argc, char **argv)
|
||||
if (ouput_vcd) {
|
||||
vcd_signal_dumper_init("/tmp/openair_dump_nrUE.vcd");
|
||||
}
|
||||
|
||||
#ifndef PACKAGE_VERSION
|
||||
# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
|
||||
#ifndef PACKAGE_VERSION
|
||||
#define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
|
||||
#endif
|
||||
LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
|
||||
// strdup to put the sring in the core file for post mortem identification
|
||||
LOG_I(HW, "Version: %s\n", strdup(PACKAGE_VERSION));
|
||||
|
||||
PHY_vars_UE_g = malloc(sizeof(*PHY_vars_UE_g));
|
||||
PHY_vars_UE_g[0] = malloc(sizeof(*PHY_vars_UE_g[0]) * MAX_NUM_CCs);
|
||||
@@ -567,9 +567,6 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
init_openair0();
|
||||
// init UE_PF_PO and mutex lock
|
||||
pthread_mutex_init(&ue_pf_po_mutex, NULL);
|
||||
memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs);
|
||||
set_latency_target();
|
||||
|
||||
if(IS_SOFTMODEM_DOSCOPE_QT) {
|
||||
|
||||
@@ -138,10 +138,8 @@ void get_common_options(configmodule_interface_t *cfg, uint32_t execmask)
|
||||
}
|
||||
|
||||
if (logmem_filename != NULL && strlen(logmem_filename) > 0) {
|
||||
log_mem_filename = &logmem_filename[0];
|
||||
log_mem_flag = 1;
|
||||
printf("Enabling OPT for log save at memory %s\n",log_mem_filename);
|
||||
logInit_log_mem();
|
||||
printf("Enabling OPT for log save at memory %s\n",logmem_filename);
|
||||
logInit_log_mem(logmem_filename);
|
||||
}
|
||||
|
||||
if (noS1) {
|
||||
|
||||
@@ -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 } }, \
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
include(${OPENAIR_DIR}/nfapi/oai_integration/aerial/CMakeLists.txt)
|
||||
@@ -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()
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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) {
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "common/ran_context.h"
|
||||
#include "openair2/PHY_INTERFACE/queue_t.h"
|
||||
#include "gnb_ind_vars.h"
|
||||
#include "LAYER2/MAC/mac.h"
|
||||
|
||||
#define TEST
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@ typedef enum {
|
||||
NFAPI_UE_STUB_PNF,
|
||||
NFAPI_UE_STUB_OFFNET,
|
||||
NFAPI_MODE_STANDALONE_PNF,
|
||||
NFAPI_MODE_AERIAL,
|
||||
NFAPI_MODE_UNKNOWN
|
||||
} nfapi_mode_t;
|
||||
|
||||
|
||||
@@ -9,19 +9,6 @@
|
||||
#ifndef _NFAPI_NR_INTERFACE_H_
|
||||
#define _NFAPI_NR_INTERFACE_H_
|
||||
|
||||
#include "nfapi_interface.h"
|
||||
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h"
|
||||
|
||||
#define NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS 5
|
||||
#define NFAPI_NR_MAX_NB_TCI_STATES_PDCCH 64
|
||||
#define NFAPI_NR_MAX_NB_CORESETS 12
|
||||
#define NFAPI_NR_MAX_NB_SEARCH_SPACES 40
|
||||
|
||||
|
||||
|
||||
// nFAPI enums
|
||||
|
||||
|
||||
//These TLVs are used exclusively by nFAPI
|
||||
#define NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG 0x0100
|
||||
#define NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG 0x0101
|
||||
@@ -37,510 +24,26 @@
|
||||
#define NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG 0x011F
|
||||
#define NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG 0x0120
|
||||
|
||||
/*
|
||||
#define NFAPI_NR_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG 0x510A
|
||||
#define NFAPI_NR_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG 0x510B
|
||||
#define NFAPI_NR_NFAPI_RF_BANDS_TAG 0x5114
|
||||
#define NFAPI_NR_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG 0x5128
|
||||
#define NFAPI_NR_NFAPI_NRARFCN_TAG 0x5129
|
||||
#define NFAPI_NR_NFAPI_NMM_GSM_FREQUENCY_BANDS_TAG 0x5130
|
||||
#define NFAPI_NR_NFAPI_NMM_UMTS_FREQUENCY_BANDS_TAG 0x5131
|
||||
#define NFAPI_NR_NFAPI_NMM_LTE_FREQUENCY_BANDS_TAG 0x5132
|
||||
#define NFAPI_NR_NFAPI_NMM_UPLINK_RSSI_SUPPORTED_TAG 0x5133
|
||||
*/
|
||||
// P5 Message Structures
|
||||
|
||||
typedef struct {
|
||||
nfapi_uint16_tlv_t numerology_index_mu;
|
||||
nfapi_uint16_tlv_t duplex_mode;
|
||||
nfapi_uint16_tlv_t dl_cyclic_prefix_type;
|
||||
nfapi_uint16_tlv_t ul_cyclic_prefix_type;
|
||||
} nfapi_nr_subframe_config_t;
|
||||
|
||||
#define NFAPI_NR_SUBFRAME_CONFIG_DUPLEX_MODE_TAG 0x5001
|
||||
#define NFAPI_NR_SUBFRAME_CONFIG_PCFICH_POWER_OFFSET_TAG 0x5002
|
||||
#define NFAPI_NR_SUBFRAME_CONFIG_PB_TAG 0x5003
|
||||
#define NFAPI_NR_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG 0x5004
|
||||
#define NFAPI_NR_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG 0x5005
|
||||
#define NFAPI_NR_SUBFRAME_CONFIG_NUMEROLOGY_INDEX_MU_TAG 0x5006
|
||||
|
||||
typedef struct {
|
||||
nfapi_uint16_tlv_t dl_carrier_bandwidth;
|
||||
nfapi_uint16_tlv_t ul_carrier_bandwidth;
|
||||
nfapi_uint16_tlv_t dl_absolutefrequencypointA;
|
||||
nfapi_uint16_tlv_t ul_absolutefrequencypointA;
|
||||
nfapi_uint16_tlv_t dl_offsettocarrier;
|
||||
nfapi_uint16_tlv_t ul_offsettocarrier;
|
||||
nfapi_uint16_tlv_t dl_subcarrierspacing;
|
||||
nfapi_uint16_tlv_t ul_subcarrierspacing;
|
||||
nfapi_uint16_tlv_t dl_specificcarrier_k0;
|
||||
nfapi_uint16_tlv_t ul_specificcarrier_k0;
|
||||
nfapi_uint16_tlv_t NIA_subcarrierspacing;
|
||||
} nfapi_nr_rf_config_t;
|
||||
|
||||
#define NFAPI_NR_RF_CONFIG_DL_CARRIER_BANDWIDTH_TAG 0x500A
|
||||
#define NFAPI_NR_RF_CONFIG_UL_CARRIER_BANDWIDTH_TAG 0x500B
|
||||
#define NFAPI_NR_RF_CONFIG_DL_SUBCARRIERSPACING_TAG 0x500C
|
||||
#define NFAPI_NR_RF_CONFIG_UL_SUBCARRIERSPACING_TAG 0x500D
|
||||
#define NFAPI_NR_RF_CONFIG_DL_OFFSETTOCARRIER_TAG 0x500E
|
||||
#define NFAPI_NR_RF_CONFIG_UL_OFFSETTOCARRIER_TAG 0x500F
|
||||
|
||||
typedef struct {
|
||||
nfapi_uint16_tlv_t physical_cell_id;
|
||||
nfapi_uint16_tlv_t half_frame_index;
|
||||
nfapi_uint16_tlv_t ssb_subcarrier_offset;
|
||||
nfapi_uint16_tlv_t ssb_sib1_position_in_burst; // in sib1
|
||||
nfapi_uint64_tlv_t ssb_scg_position_in_burst; // in servingcellconfigcommon
|
||||
nfapi_uint16_tlv_t ssb_periodicity;
|
||||
nfapi_uint16_tlv_t ss_pbch_block_power;
|
||||
nfapi_uint16_tlv_t n_ssb_crb;
|
||||
} nfapi_nr_sch_config_t;
|
||||
|
||||
typedef struct {
|
||||
nfapi_uint16_tlv_t dl_bandwidth;
|
||||
nfapi_uint16_tlv_t ul_bandwidth;
|
||||
nfapi_uint16_tlv_t dl_offset;
|
||||
nfapi_uint16_tlv_t ul_offset;
|
||||
nfapi_uint16_tlv_t dl_subcarrierSpacing;
|
||||
nfapi_uint16_tlv_t ul_subcarrierSpacing;
|
||||
} nfapi_nr_initialBWP_config_t;
|
||||
|
||||
#define NFAPI_INITIALBWP_DL_BANDWIDTH_TAG 0x5010
|
||||
#define NFAPI_INITIALBWP_DL_OFFSET_TAG 0x5011
|
||||
#define NFAPI_INITIALBWP_DL_SUBCARRIERSPACING_TAG 0x5012
|
||||
#define NFAPI_INITIALBWP_UL_BANDWIDTH_TAG 0x5013
|
||||
#define NFAPI_INITIALBWP_UL_OFFSET_TAG 0x5014
|
||||
#define NFAPI_INITIALBWP_UL_SUBCARRIERSPACING_TAG 0x5015
|
||||
|
||||
|
||||
#define NFAPI_NR_SCH_CONFIG_PHYSICAL_CELL_ID_TAG 0x501E
|
||||
#define NFAPI_NR_SCH_CONFIG_HALF_FRAME_INDEX_TAG 0x501F
|
||||
#define NFAPI_NR_SCH_CONFIG_SSB_SUBCARRIER_OFFSET_TAG 0x5020
|
||||
#define NFAPI_NR_SCH_CONFIG_SSB_POSITION_IN_BURST 0x5021
|
||||
#define NFAPI_NR_SCH_CONFIG_SSB_PERIODICITY 0x5022
|
||||
#define NFAPI_NR_SCH_CONFIG_SS_PBCH_BLOCK_POWER 0x5023
|
||||
#define NFAPI_NR_SCH_CONFIG_N_SSB_CRB 0x5024
|
||||
#define NFAPI_NR_PDSCH_CONFIG_MAXALLOCATIONS 16
|
||||
#define NFAPI_NR_PUSCH_CONFIG_MAXALLOCATIONS 16
|
||||
|
||||
typedef struct {
|
||||
nfapi_uint16_tlv_t dmrs_TypeA_Position;
|
||||
nfapi_uint16_tlv_t num_PDSCHTimeDomainResourceAllocations;
|
||||
nfapi_uint16_tlv_t PDSCHTimeDomainResourceAllocation_k0[NFAPI_NR_PDSCH_CONFIG_MAXALLOCATIONS];
|
||||
nfapi_uint16_tlv_t PDSCHTimeDomainResourceAllocation_mappingType[NFAPI_NR_PDSCH_CONFIG_MAXALLOCATIONS];
|
||||
nfapi_uint16_tlv_t PDSCHTimeDomainResourceAllocation_startSymbolAndLength[NFAPI_NR_PDSCH_CONFIG_MAXALLOCATIONS];
|
||||
} nfapi_nr_pdsch_config_t;
|
||||
#define NFAPI_NR_PDSCH_CONFIG_TAG
|
||||
|
||||
|
||||
typedef struct {
|
||||
nfapi_uint16_tlv_t prach_RootSequenceIndex; ///// L1 parameter 'PRACHRootSequenceIndex'
|
||||
nfapi_uint16_tlv_t prach_msg1_SubcarrierSpacing; ///// L1 parameter 'prach-Msg1SubcarrierSpacing'
|
||||
nfapi_uint16_tlv_t restrictedSetConfig;
|
||||
nfapi_uint16_tlv_t msg3_transformPrecoding; ///// L1 parameter 'msg3-tp'
|
||||
nfapi_uint16_tlv_t ssb_perRACH_OccasionAndCB_PreamblesPerSSB;
|
||||
nfapi_uint16_tlv_t ra_ContentionResolutionTimer;
|
||||
nfapi_uint16_tlv_t rsrp_ThresholdSSB;
|
||||
/////////////////--------------------NR RACH-ConfigGeneric--------------------/////////////////
|
||||
nfapi_uint16_tlv_t prach_ConfigurationIndex; ///// L1 parameter 'PRACHConfigurationIndex'
|
||||
nfapi_uint16_tlv_t prach_msg1_FDM; ///// L1 parameter 'prach-FDM'
|
||||
nfapi_uint16_tlv_t prach_msg1_FrequencyStart; ///// L1 parameter 'prach-frequency-start'
|
||||
nfapi_uint16_tlv_t zeroCorrelationZoneConfig;
|
||||
nfapi_uint16_tlv_t preambleReceivedTargetPower;
|
||||
nfapi_uint16_tlv_t preambleTransMax;
|
||||
nfapi_uint16_tlv_t powerRampingStep;
|
||||
nfapi_uint16_tlv_t ra_ResponseWindow;
|
||||
} nfapi_nr_rach_config_t;
|
||||
|
||||
typedef struct {
|
||||
nfapi_uint16_tlv_t groupHoppingEnabledTransformPrecoding; ///// L1 parameter 'Group-hopping-enabled-Transform-precoding'
|
||||
nfapi_uint16_tlv_t msg3_DeltaPreamble; ///// L1 parameter 'Delta-preamble-msg3'
|
||||
nfapi_uint16_tlv_t p0_NominalWithGrant; ///// L1 parameter 'p0-nominal-pusch-withgrant'
|
||||
nfapi_uint16_tlv_t dmrs_TypeA_Position;
|
||||
nfapi_uint16_tlv_t num_PUSCHTimeDomainResourceAllocations;
|
||||
nfapi_uint16_tlv_t PUSCHTimeDomainResourceAllocation_k2[NFAPI_NR_PUSCH_CONFIG_MAXALLOCATIONS]; ///// L1 parameter 'K2'
|
||||
nfapi_uint16_tlv_t PUSCHTimeDomainResourceAllocation_mappingType[NFAPI_NR_PUSCH_CONFIG_MAXALLOCATIONS]; ///// L1 parameter 'Mapping-type'
|
||||
nfapi_uint16_tlv_t PUSCHTimeDomainResourceAllocation_startSymbolAndLength[NFAPI_NR_PUSCH_CONFIG_MAXALLOCATIONS];
|
||||
} nfapi_nr_pusch_config_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t pucch_resource_common;
|
||||
nfapi_uint16_tlv_t pucch_GroupHopping; ///// L1 parameter 'PUCCH-GroupHopping'
|
||||
nfapi_uint16_tlv_t p0_nominal; ///// L1 parameter 'p0-nominal-pucch'
|
||||
} nfapi_nr_pucch_config_t;
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
nfapi_tl_t tl;
|
||||
|
||||
nfapi_uint16_tlv_t controlResourceSetZero;
|
||||
nfapi_uint16_tlv_t searchSpaceZero;
|
||||
|
||||
// nfapi_nr_SearchSpace_t sib1searchSpace;
|
||||
// nfapi_nr_SearchSpace_t sibssearchSpace;
|
||||
// nfapi_nr_SearchSpace_t ra_SearchSpace;
|
||||
}nfapi_nr_pdcch_config_t;
|
||||
|
||||
typedef struct {
|
||||
//NR TDD-UL-DL-ConfigCommon ///// L1 parameter 'UL-DL-configuration-common'
|
||||
nfapi_uint16_tlv_t referenceSubcarrierSpacing; ///// L1 parameter 'reference-SCS'
|
||||
nfapi_uint16_tlv_t dl_ul_periodicity; ///// L1 parameter 'DL-UL-transmission-periodicity'
|
||||
nfapi_uint16_tlv_t nrofDownlinkSlots; ///// L1 parameter 'number-of-DL-slots'
|
||||
nfapi_uint16_tlv_t nrofDownlinkSymbols; ///// L1 parameter 'number-of-DL-symbols-common'
|
||||
nfapi_uint16_tlv_t nrofUplinkSlots; ///// L1 parameter 'number-of-UL-slots'
|
||||
nfapi_uint16_tlv_t nrofUplinkSymbols; ///// L1 parameter 'number-of-UL-symbols-common'
|
||||
nfapi_uint16_tlv_t Pattern2Present;
|
||||
nfapi_uint16_tlv_t Pattern2_dl_ul_periodicity; ///// L1 parameter 'DL-UL-transmission-periodicity'
|
||||
nfapi_uint16_tlv_t Pattern2_nrofDownlinkSlots; ///// L1 parameter 'number-of-DL-slots'
|
||||
nfapi_uint16_tlv_t Pattern2_nrofDownlinkSymbols; ///// L1 parameter 'number-of-DL-symbols-common'
|
||||
nfapi_uint16_tlv_t Pattern2_nrofUplinkSlots; ///// L1 parameter 'number-of-UL-slots'
|
||||
nfapi_uint16_tlv_t Pattern2_nrofUplinkSymbols; ///// L1 parameter 'number-of-UL-symbols-common'
|
||||
} nfapi_nr_tdd_ul_dl_config_t;
|
||||
|
||||
typedef struct {
|
||||
//RateMatchPattern is used to configure one rate matching pattern for PDSCH ///// L1 parameter 'Resource-set-cekk'
|
||||
nfapi_uint16_tlv_t Match_Id;
|
||||
nfapi_uint16_tlv_t patternType;
|
||||
nfapi_uint16_tlv_t symbolsInResourceBlock; ///// L1 parameter 'rate-match-PDSCH-bitmap2
|
||||
nfapi_uint16_tlv_t periodicityAndPattern; ///// L1 parameter 'rate-match-PDSCH-bitmap3'
|
||||
nfapi_uint16_tlv_t controlResourceSet;
|
||||
nfapi_uint16_tlv_t subcarrierSpacing; ///// L1 parameter 'resource-pattern-scs'
|
||||
nfapi_uint16_tlv_t mode;
|
||||
} nfapi_nr_ratematchpattern_t;
|
||||
|
||||
typedef struct {
|
||||
//NR RateMatchPatternLTE-CRS
|
||||
nfapi_uint16_tlv_t carrierfreqDL; ///// L1 parameter 'center-subcarrier-location'
|
||||
nfapi_uint16_tlv_t dl_bandwidth; ///// L1 parameter 'BW'
|
||||
nfapi_uint16_tlv_t nrofcrs_Ports; ///// L1 parameter 'rate-match-resources-numb-LTE-CRS-antenna-port'
|
||||
nfapi_uint16_tlv_t v_Shift; ///// L1 parameter 'rate-match-resources-LTE-CRS-v-shift'
|
||||
nfapi_uint16_tlv_t frame_Period;
|
||||
nfapi_uint16_tlv_t frame_Offset;
|
||||
} nfapi_nr_ratematchpattern_lte_crs_t;
|
||||
|
||||
typedef struct {
|
||||
nfapi_p4_p5_message_header_t header;
|
||||
uint8_t num_tlv;
|
||||
nfapi_nr_subframe_config_t subframe_config;
|
||||
nfapi_nr_rf_config_t rf_config;
|
||||
nfapi_nr_sch_config_t sch_config;
|
||||
nfapi_nr_initialBWP_config_t initialBWP_config;
|
||||
nfapi_nr_pdsch_config_t pdsch_config;
|
||||
nfapi_nr_rach_config_t rach_config;
|
||||
nfapi_nr_pusch_config_t pusch_config;
|
||||
nfapi_nr_pucch_config_t pucch_config;
|
||||
nfapi_nr_pdcch_config_t pdcch_config;
|
||||
nfapi_nr_tdd_ul_dl_config_t tdd_ul_dl_config;
|
||||
nfapi_nr_ratematchpattern_t ratematchpattern;
|
||||
nfapi_nr_ratematchpattern_lte_crs_t ratematchpattern_lte_crs;
|
||||
nfapi_nr_nfapi_t nfapi_config;
|
||||
|
||||
nfapi_vendor_extension_tlv_t vendor_extension;
|
||||
} nfapi_nr_config_request_t;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_USS_FORMAT_0_0_AND_1_0,
|
||||
NFAPI_NR_USS_FORMAT_0_1_AND_1_1,
|
||||
} nfapi_nr_uss_dci_formats_e;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_SEARCH_SPACE_TYPE_COMMON=0,
|
||||
NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC
|
||||
} nfapi_nr_search_space_type_e;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_0=0,
|
||||
NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_0A,
|
||||
NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_1,
|
||||
NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_2
|
||||
} nfapi_nr_common_search_space_type_e;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1=0,
|
||||
NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE2,
|
||||
NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE3
|
||||
} nfapi_nr_ssb_and_cset_mux_pattern_type_e;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED=1,
|
||||
NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED=0
|
||||
} nfapi_nr_cce_reg_mapping_type_e;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_CSET_CONFIG_MIB_SIB1=0,
|
||||
NFAPI_NR_CSET_CONFIG_MIB_SIB1 = 0,
|
||||
NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG, // implicit assumption of coreset Id other than 0
|
||||
} nfapi_nr_coreset_config_type_e;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_CSET_SAME_AS_REG_BUNDLE=0,
|
||||
NFAPI_NR_CSET_ALL_CONTIGUOUS_RBS
|
||||
} nfapi_nr_coreset_precoder_granularity_type_e;
|
||||
NFAPI_NR_DMRS_TYPE1,
|
||||
NFAPI_NR_DMRS_TYPE2
|
||||
} nfapi_nr_dmrs_type_e;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_QCL_TYPE_A=0,
|
||||
NFAPI_NR_QCL_TYPE_B,
|
||||
NFAPI_NR_QCL_TYPE_C,
|
||||
NFAPI_NR_QCL_TYPE_D
|
||||
} nfapi_nr_qcl_type_e;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_SS_PERIODICITY_SL1=1,
|
||||
NFAPI_NR_SS_PERIODICITY_SL2=2,
|
||||
NFAPI_NR_SS_PERIODICITY_SL4=4,
|
||||
NFAPI_NR_SS_PERIODICITY_SL5=5,
|
||||
NFAPI_NR_SS_PERIODICITY_SL8=8,
|
||||
NFAPI_NR_SS_PERIODICITY_SL10=10,
|
||||
NFAPI_NR_SS_PERIODICITY_SL16=16,
|
||||
NFAPI_NR_SS_PERIODICITY_SL20=20,
|
||||
NFAPI_NR_SS_PERIODICITY_SL40=40,
|
||||
NFAPI_NR_SS_PERIODICITY_SL80=80,
|
||||
NFAPI_NR_SS_PERIODICITY_SL160=160,
|
||||
NFAPI_NR_SS_PERIODICITY_SL320=320,
|
||||
NFAPI_NR_SS_PERIODICITY_SL640=640,
|
||||
NFAPI_NR_SS_PERIODICITY_SL1280=1280,
|
||||
NFAPI_NR_SS_PERIODICITY_SL2560=2560
|
||||
} nfapi_nr_search_space_monitoring_periodicity_e;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_A=0,
|
||||
NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_B,
|
||||
NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_C,
|
||||
NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_ALLOC_LIST
|
||||
} nfapi_nr_pdsch_time_domain_alloc_type_e;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_PDSCH_MAPPING_TYPE_A=0,
|
||||
NFAPI_NR_PDSCH_MAPPING_TYPE_B
|
||||
} nfapi_nr_pdsch_mapping_type_e;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_PDSCH_RBG_CONFIG_TYPE1=0,
|
||||
NFAPI_NR_PDSCH_RBG_CONFIG_TYPE2
|
||||
} nfapi_nr_pdsch_rbg_config_type_e;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_PRG_GRANULARITY_2=2,
|
||||
NFAPI_NR_PRG_GRANULARITY_4=4,
|
||||
NFAPI_NR_PRG_GRANULARITY_WIDEBAND
|
||||
} nfapi_nr_prg_granularity_e;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_PRB_BUNDLING_TYPE_STATIC=0,
|
||||
NFAPI_NR_PRB_BUNDLING_TYPE_DYNAMIC
|
||||
} nfapi_nr_prb_bundling_type_e;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_MCS_TABLE_QAM64_LOW_SE=0,
|
||||
NFAPI_NR_MCS_TABLE_QAM256
|
||||
} nfapi_nr_pdsch_mcs_table_e;
|
||||
|
||||
// P7 Sub Structures
|
||||
|
||||
/*
|
||||
typedef struct {
|
||||
|
||||
nfapi_tl_t tl;
|
||||
|
||||
uint8_t format_indicator; //1 bit
|
||||
uint16_t frequency_domain_assignment; //up to 16 bits
|
||||
uint8_t time_domain_assignment; // 4 bits
|
||||
uint8_t frequency_hopping_flag; //1 bit
|
||||
|
||||
uint8_t ra_preamble_index; //6 bits
|
||||
uint8_t ss_pbch_index; //6 bits
|
||||
uint8_t prach_mask_index; //4 bits
|
||||
|
||||
uint8_t vrb_to_prb_mapping; //0 or 1 bit
|
||||
uint8_t mcs; //5 bits
|
||||
uint8_t ndi; //1 bit
|
||||
uint8_t rv; //2 bits
|
||||
uint8_t harq_pid; //4 bits
|
||||
uint8_t dai; //0, 2 or 4 bits
|
||||
uint8_t dai1; //1 or 2 bits
|
||||
uint8_t dai2; //0 or 2 bits
|
||||
uint8_t tpc; //2 bits
|
||||
uint8_t pucch_resource_indicator; //3 bits
|
||||
uint8_t pdsch_to_harq_feedback_timing_indicator; //0, 1, 2 or 3 bits
|
||||
|
||||
uint8_t short_messages_indicator; //2 bits
|
||||
uint8_t short_messages; //8 bits
|
||||
uint8_t tb_scaling; //2 bits
|
||||
|
||||
uint8_t carrier_indicator; //0 or 3 bits
|
||||
uint8_t bwp_indicator; //0, 1 or 2 bits
|
||||
uint8_t prb_bundling_size_indicator; //0 or 1 bits
|
||||
uint8_t rate_matching_indicator; //0, 1 or 2 bits
|
||||
uint8_t zp_csi_rs_trigger; //0, 1 or 2 bits
|
||||
uint8_t transmission_configuration_indication; //0 or 3 bits
|
||||
uint8_t srs_request; //2 bits
|
||||
uint8_t cbgti; //CBG Transmission Information: 0, 2, 4, 6 or 8 bits
|
||||
uint8_t cbgfi; //CBG Flushing Out Information: 0 or 1 bit
|
||||
uint8_t dmrs_sequence_initialization; //0 or 1 bit
|
||||
|
||||
uint8_t srs_resource_indicator;
|
||||
uint8_t precoding_information;
|
||||
uint8_t csi_request;
|
||||
uint8_t ptrs_dmrs_association;
|
||||
uint8_t beta_offset_indicator; //0 or 2 bits
|
||||
|
||||
uint8_t slot_format_indicator_count;
|
||||
uint8_t *slot_format_indicators;
|
||||
|
||||
uint8_t pre_emption_indication_count;
|
||||
uint16_t *pre_emption_indications; //14 bit
|
||||
|
||||
uint8_t block_number_count;
|
||||
uint8_t *block_numbers;
|
||||
|
||||
uint8_t ul_sul_indicator; //0 or 1 bit
|
||||
uint8_t antenna_ports;
|
||||
|
||||
uint16_t reserved; //1_0/C-RNTI:10 bits, 1_0/P-RNTI: 6 bits, 1_0/SI-&RA-RNTI: 16 bits
|
||||
uint16_t padding;
|
||||
|
||||
} nfapi_nr_dl_config_dci_dl_pdu_rel15_t;
|
||||
*/
|
||||
//#define NFAPI_NR_DL_CONFIG_REQUEST_DCI_DL_PDU_REL15_TAG 0x????
|
||||
|
||||
|
||||
|
||||
/*
|
||||
typedef struct{
|
||||
nfapi_tl_t tl;
|
||||
uint8_t coreset_id;
|
||||
uint64_t frequency_domain_resources;
|
||||
uint8_t duration;
|
||||
uint8_t cce_reg_mapping_type;
|
||||
uint8_t reg_bundle_size;
|
||||
uint8_t interleaver_size;
|
||||
uint8_t shift_index;
|
||||
uint8_t precoder_granularity;
|
||||
uint8_t tci_state_id;
|
||||
uint8_t tci_present_in_dci;
|
||||
uint32_t dmrs_scrambling_id;
|
||||
} nfapi_nr_coreset_t;
|
||||
|
||||
typedef struct{
|
||||
nfapi_tl_t tl;
|
||||
uint8_t search_space_id;
|
||||
uint8_t coreset_id;
|
||||
uint8_t search_space_type;
|
||||
uint8_t duration;
|
||||
uint8_t css_formats_0_0_and_1_0;
|
||||
uint8_t css_format_2_0;
|
||||
uint8_t css_format_2_1;
|
||||
uint8_t css_format_2_2;
|
||||
uint8_t css_format_2_3;
|
||||
uint8_t uss_dci_formats;
|
||||
uint16_t srs_monitoring_periodicity;
|
||||
uint16_t slot_monitoring_periodicity;
|
||||
uint16_t slot_monitoring_offset;
|
||||
uint32_t monitoring_symbols_in_slot;
|
||||
uint16_t number_of_candidates[NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS];
|
||||
} nfapi_nr_search_space_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
nfapi_tl_t tl;
|
||||
uint16_t rnti;
|
||||
uint8_t rnti_type;
|
||||
uint8_t dci_format;
|
||||
uint16_t cce_index;
|
||||
/// Number of CRB in BWP that this DCI configures
|
||||
uint16_t n_RB_BWP;
|
||||
uint8_t config_type;
|
||||
uint8_t search_space_type;
|
||||
uint8_t common_search_space_type;
|
||||
uint8_t aggregation_level;
|
||||
uint8_t n_rb;
|
||||
uint8_t n_symb;
|
||||
int8_t rb_offset;
|
||||
uint8_t cr_mapping_type;
|
||||
uint8_t reg_bundle_size;
|
||||
uint8_t interleaver_size;
|
||||
uint8_t shift_index;
|
||||
uint8_t mux_pattern;
|
||||
uint8_t precoder_granularity;
|
||||
uint8_t first_slot;
|
||||
uint8_t first_symbol;
|
||||
uint8_t nb_ss_sets_per_slot;
|
||||
uint8_t nb_slots;
|
||||
uint8_t sfn_mod2;
|
||||
uint16_t scrambling_id;
|
||||
nfapi_bf_vector_t bf_vector;
|
||||
} nfapi_nr_dl_config_pdcch_parameters_rel15_t;
|
||||
|
||||
*/
|
||||
|
||||
|
||||
typedef enum {nr_pusch_freq_hopping_disabled = 0 ,
|
||||
nr_pusch_freq_hopping_enabled = 1
|
||||
} nr_pusch_freq_hopping_t;
|
||||
|
||||
typedef struct{
|
||||
uint8_t aperiodicSRS_ResourceTrigger;
|
||||
} nfapi_nr_ul_srs_config_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t bandwidth_part_ind;
|
||||
uint16_t number_rbs;
|
||||
uint16_t start_rb;
|
||||
uint8_t frame_offset;
|
||||
uint16_t number_symbols;
|
||||
uint16_t start_symbol;
|
||||
uint8_t length_dmrs;
|
||||
nr_pusch_freq_hopping_t pusch_freq_hopping;
|
||||
uint8_t mcs;
|
||||
uint8_t Qm;
|
||||
uint16_t R;
|
||||
uint8_t ndi;
|
||||
uint8_t rv;
|
||||
int8_t accumulated_delta_PUSCH;
|
||||
int8_t absolute_delta_PUSCH;
|
||||
uint8_t n_layers;
|
||||
uint8_t tpmi;
|
||||
uint8_t n_dmrs_cdm_groups;
|
||||
uint8_t dmrs_ports[4];
|
||||
uint8_t n_front_load_symb;
|
||||
nfapi_nr_ul_srs_config_t srs_config;
|
||||
uint8_t csi_reportTriggerSize;
|
||||
uint8_t maxCodeBlockGroupsPerTransportBlock;
|
||||
uint8_t ptrs_dmrs_association_port;
|
||||
uint8_t beta_offset_ind;
|
||||
} nfapi_nr_ul_config_ulsch_pdu_rel15_t;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint16_t rnti;
|
||||
nfapi_nr_ul_config_ulsch_pdu_rel15_t ulsch_pdu_rel15;
|
||||
} nfapi_nr_ul_config_ulsch_pdu;
|
||||
|
||||
typedef struct {
|
||||
uint8_t pdu_type;
|
||||
uint8_t pdu_size;
|
||||
|
||||
union {
|
||||
// nfapi_nr_ul_config_uci_pdu uci_pdu;
|
||||
nfapi_nr_ul_config_ulsch_pdu ulsch_pdu;
|
||||
// nfapi_nr_ul_config_srs_pdu srs_pdu;
|
||||
};
|
||||
} nfapi_nr_ul_config_request_pdu_t;
|
||||
|
||||
typedef struct {
|
||||
nfapi_tl_t tl;
|
||||
uint8_t number_pdu;
|
||||
nfapi_nr_ul_config_request_pdu_t *ul_config_pdu_list;
|
||||
} nfapi_nr_ul_config_request_body_t;
|
||||
|
||||
typedef struct {
|
||||
nfapi_p7_message_header_t header;
|
||||
uint16_t sfn_sf;
|
||||
nfapi_nr_ul_config_request_body_t ul_config_request_body;
|
||||
nfapi_vendor_extension_tlv_t vendor_extension;
|
||||
} nfapi_nr_ul_config_request_t;
|
||||
NFAPI_NR_SRS_BEAMMANAGEMENT = 0,
|
||||
NFAPI_NR_SRS_CODEBOOK = 1,
|
||||
NFAPI_NR_SRS_NONCODEBOOK = 2,
|
||||
NFAPI_NR_SRS_ANTENNASWITCH = 3
|
||||
} nfapi_nr_srs_usage_e;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
#include "stddef.h"
|
||||
#include "nfapi_interface.h"
|
||||
#include "nfapi_nr_interface.h"
|
||||
|
||||
#define NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS 5
|
||||
#define NFAPI_NR_MAX_NB_TCI_STATES_PDCCH 64
|
||||
@@ -26,13 +25,6 @@
|
||||
|
||||
// Extension to the generic structures for single tlv values
|
||||
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_DMRS_TYPE1=0,
|
||||
NFAPI_NR_DMRS_TYPE2
|
||||
} nfapi_nr_dmrs_type_e;
|
||||
|
||||
|
||||
typedef struct {
|
||||
/// Value: 0 -> 1, 0: Payload is carried directly in the value field, 1: Pointer to payload is in the value field
|
||||
uint16_t tag;
|
||||
@@ -328,6 +320,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 +1460,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 +1496,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
|
||||
|
||||
@@ -171,6 +171,7 @@ int LDPCencoder(unsigned char **inputArray, unsigned char **outputArray, encoder
|
||||
{
|
||||
fprintf(fd,"\n//row: %d\n",i1);
|
||||
fprintf(fd2,"\n//row: %d\n",i1);
|
||||
AssertFatal(shift > 0 , "The result of the right shift is undefined because the right operand is negative\n");
|
||||
fprintf(fd," d2[%d]=",(Zc*i1)>>shift);
|
||||
fprintf(fd2," d2[%d]=",(Zc*i1)>>(shift-1));
|
||||
|
||||
|
||||
@@ -116,6 +116,7 @@ int8_t polar_decoder(double *input,
|
||||
}
|
||||
|
||||
//The index of the last 1-valued bit that appears in each column.
|
||||
AssertFatal(polarParams->crcParityBits > 0, "UB for VLA. crcParityBits negative\n");
|
||||
uint16_t last1ind[polarParams->crcParityBits];
|
||||
|
||||
for (int j=0; j<polarParams->crcParityBits; j++) {
|
||||
|
||||
@@ -239,7 +239,7 @@ void nr_polar_info_bit_pattern(uint8_t *ibp,
|
||||
{
|
||||
int Q_Ftmp_N[N + 1]; // Last element shows the final
|
||||
int Q_Itmp_N[N + 1]; // array index assigned a value.
|
||||
|
||||
|
||||
for (int i = 0; i <= N; i++) {
|
||||
Q_Ftmp_N[i] = -1; // Empty array.
|
||||
Q_Itmp_N[i] = -1;
|
||||
@@ -282,11 +282,13 @@ void nr_polar_info_bit_pattern(uint8_t *ibp,
|
||||
// Q_I,tmp_N = Q_0_N-1 \ Q_F,tmp_N
|
||||
for (int n = 0; n <= N - 1; n++) {
|
||||
bool flag = true;
|
||||
for (int m = 0; m <= Q_Ftmp_N[N]; m++)
|
||||
for (int m = 0; m <= Q_Ftmp_N[N]; m++){
|
||||
AssertFatal(m < N+1, "Buffer boundary overflow");
|
||||
if (Q_0_Nminus1[n] == Q_Ftmp_N[m]) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (flag) {
|
||||
Q_Itmp_N[Q_Itmp_N[N] + 1] = Q_0_Nminus1[n];
|
||||
Q_Itmp_N[N]++;
|
||||
|
||||
@@ -292,6 +292,7 @@ void phy_viterbi_dot11_sse2(char *y,unsigned char *decoded_bytes,unsigned short
|
||||
// Traceback
|
||||
if (traceback == 1) {
|
||||
prev_state0 = 0;
|
||||
AssertFatal((offset+n-1) > 0, "Left shift is undefined if the left operand is negative\n");
|
||||
TB_ptr2 = (unsigned char *)&TB[(offset+n-1)<<2];
|
||||
|
||||
for (position = offset+n-1 ; position>-1; position--) {
|
||||
|
||||
@@ -39,8 +39,6 @@
|
||||
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
|
||||
#include "PHY/NR_REFSIG/nr_refsig.h"
|
||||
#include "SCHED_NR/fapi_nr_l1.h"
|
||||
#include "nfapi_nr_interface.h"
|
||||
|
||||
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
|
||||
|
||||
|
||||
@@ -79,8 +77,11 @@ NR_gNB_PHY_STATS_t *get_phy_stats(PHY_VARS_gNB *gNB, uint16_t rnti)
|
||||
else if (!stats->active && first_free == -1)
|
||||
first_free = i;
|
||||
}
|
||||
|
||||
if (first_free < 0)
|
||||
return NULL;
|
||||
|
||||
// new stats
|
||||
AssertFatal(first_free >= 0, "PHY statistics list is full\n");
|
||||
stats = &gNB->phy_stats[first_free];
|
||||
stats->active = true;
|
||||
stats->rnti = rnti;
|
||||
@@ -132,6 +133,8 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
|
||||
load_LDPClib(NULL, &ldpc_interface);
|
||||
|
||||
pthread_mutex_init(&gNB->UL_INFO.crc_rx_mutex, NULL);
|
||||
|
||||
if (gNB->ldpc_offload_flag)
|
||||
load_LDPClib("_t2", &ldpc_interface_offload);
|
||||
gNB->max_nb_pdsch = MAX_MOBILES_PER_GNB;
|
||||
@@ -328,6 +331,8 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
const int max_ul_mimo_layers = 4; // taken from phy_init_nr_gNB()
|
||||
const int n_buf = Prx * max_ul_mimo_layers;
|
||||
|
||||
pthread_mutex_destroy(&gNB->UL_INFO.crc_rx_mutex);
|
||||
|
||||
PHY_MEASUREMENTS_gNB *meas = &gNB->measurements;
|
||||
free_and_zero(meas->n0_subband_power);
|
||||
free_and_zero(meas->n0_subband_power_dB);
|
||||
|
||||
@@ -171,6 +171,8 @@ void rx_prach0(PHY_VARS_eNB *eNB,
|
||||
AssertFatal(ru!=NULL,"ru is null\n");
|
||||
int8_t dBEn0=0;
|
||||
int16_t *prach[nb_rx];
|
||||
memset(prach, 0, nb_rx * sizeof(int16_t*));
|
||||
|
||||
for (int aa=0; aa<nb_rx; aa++) {
|
||||
if (ru->if_south == LOCAL_RF || ru->function == NGFI_RAU_IF5) { // set the time-domain signal if we have to use it in this node
|
||||
// DJP - indexing below in subframe zero takes us off the beginning of the array???
|
||||
|
||||
@@ -756,9 +756,9 @@ uint32_t calc_pucch_1x_interference(PHY_VARS_eNB *eNB,
|
||||
LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
|
||||
|
||||
uint32_t u,v,n,aa;
|
||||
uint32_t z[12*14];
|
||||
int16_t *zptr;
|
||||
int16_t rxcomp[NB_ANTENNAS_RX][2*12*14];
|
||||
uint32_t z[12*14] = {0};
|
||||
int16_t *zptr = NULL;
|
||||
int16_t rxcomp[NB_ANTENNAS_RX][2*12*14] = {0};
|
||||
uint8_t ns,N_UL_symb,nsymb,n_cs_base;
|
||||
uint16_t i,j,re_offset;
|
||||
uint8_t m,l;
|
||||
|
||||
@@ -5188,7 +5188,7 @@ double sinr_eff_cqi_calc(PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe)
|
||||
|
||||
sinr_eff_qam64 = (p_qam64[0]*pow(I_qam64_avg,7) + p_qam64[1]*pow(I_qam64_avg,6) + p_qam64[2]*pow(I_qam64_avg,5) + p_qam64[3]*pow(I_qam64_avg,4) + p_qam64[4]*pow(I_qam64_avg,
|
||||
3) + p_qam64[5]*pow(I_qam64_avg,2) + p_qam64[6]*I_qam64_avg + p_qam64[7]);
|
||||
sinr_eff = cmax3(sinr_eff_qpsk,sinr_eff_qam16,sinr_eff_qam64);
|
||||
sinr_eff = cmax3(sinr_eff_qpsk, sinr_eff_qam16,sinr_eff_qam64);
|
||||
|
||||
//printf("SINR_Eff = %e\n",sinr_eff);
|
||||
|
||||
|
||||
@@ -110,8 +110,16 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
|
||||
if (pusch_pdu->transform_precoding == transformPrecoder_disabled) {
|
||||
nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], (int32_t *)pilot, (1000+p), 0, nb_rb_pusch,
|
||||
(pusch_pdu->bwp_start + pusch_pdu->rb_start)*NR_NB_SC_PER_RB, pusch_pdu->dmrs_config_type);
|
||||
// Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS
|
||||
nr_pusch_dmrs_rx(gNB,
|
||||
Ns,
|
||||
gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol],
|
||||
(int32_t *)pilot,
|
||||
(1000 + p),
|
||||
0,
|
||||
nb_rb_pusch,
|
||||
(pusch_pdu->bwp_start + pusch_pdu->rb_start) * NR_NB_SC_PER_RB,
|
||||
pusch_pdu->dmrs_config_type);
|
||||
} else { // if transform precoding or SC-FDMA is enabled in Uplink
|
||||
// NR_SC_FDMA supports type1 DMRS so only 6 DMRS REs per RB possible
|
||||
const uint16_t index = get_index_for_dmrs_lowpapr_seq(nb_rb_pusch * (NR_NB_SC_PER_RB/2));
|
||||
@@ -634,10 +642,21 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB,
|
||||
|
||||
c16_t srs_ls_estimated_channel[frame_parms->ofdm_symbol_size*(1<<srs_pdu->num_symbols)];
|
||||
uint32_t noise_power_per_rb[srs_pdu->bwp_size];
|
||||
int16_t ch_real[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS];
|
||||
int16_t ch_imag[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS];
|
||||
int16_t noise_real[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS];
|
||||
int16_t noise_imag[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS];
|
||||
|
||||
const uint32_t arr_len = frame_parms->nb_antennas_rx * N_ap * M_sc_b_SRS;
|
||||
|
||||
int16_t ch_real[arr_len];
|
||||
memset(ch_real, 0, arr_len * sizeof(int16_t));
|
||||
|
||||
int16_t ch_imag[arr_len];
|
||||
memset(ch_imag, 0, arr_len * sizeof(int16_t));
|
||||
|
||||
int16_t noise_real[arr_len];
|
||||
memset(noise_real, 0, arr_len * sizeof(int16_t));
|
||||
|
||||
int16_t noise_imag[arr_len];
|
||||
memset(noise_imag, 0, arr_len * sizeof(int16_t));
|
||||
|
||||
int16_t ls_estimated[2];
|
||||
|
||||
uint8_t mem_offset = ((16 - ((long)&srs_estimated_channel_freq[0][0][subcarrier_offset + nr_srs_info->k_0_p[0][0]])) & 0xF) >> 2; // >> 2 <=> /sizeof(int32_t)
|
||||
@@ -836,8 +855,7 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB,
|
||||
} // for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++)
|
||||
|
||||
// Compute signal power
|
||||
uint32_t signal_power = calc_power(ch_real,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS)
|
||||
+ calc_power(ch_imag,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS);
|
||||
uint32_t signal_power = calc_power(ch_real, arr_len) + calc_power(ch_imag, arr_len);
|
||||
|
||||
#ifdef SRS_DEBUG
|
||||
LOG_I(NR_PHY,"signal_power = %u\n", signal_power);
|
||||
@@ -890,8 +908,7 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB,
|
||||
|
||||
} // for (int rb = 0; rb < m_SRS_b; rb++)
|
||||
|
||||
uint32_t noise_power = max(calc_power(noise_real,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS)
|
||||
+ calc_power(noise_imag,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS), 1);
|
||||
const uint32_t noise_power = max(calc_power(noise_real, arr_len) + calc_power(noise_imag, arr_len), 1);
|
||||
|
||||
*snr = dB_fixed((int32_t)((signal_power<<factor_bits)/(noise_power))) - factor_dB;
|
||||
|
||||
|
||||
@@ -32,29 +32,29 @@
|
||||
|
||||
#include "PHY/NR_REFSIG/ss_pbch_nr.h"
|
||||
#include "PHY/NR_REFSIG/dmrs_nr.h"
|
||||
|
||||
|
||||
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h"
|
||||
|
||||
uint8_t allowed_xlsch_re_in_dmrs_symbol(uint16_t k,
|
||||
uint16_t start_sc,
|
||||
uint16_t ofdm_symbol_size,
|
||||
uint8_t numDmrsCdmGrpsNoData,
|
||||
uint8_t dmrs_type) {
|
||||
uint8_t dmrs_type)
|
||||
{
|
||||
uint8_t delta;
|
||||
uint16_t diff;
|
||||
if (k>start_sc)
|
||||
if (k > start_sc)
|
||||
diff = k-start_sc;
|
||||
else
|
||||
diff = (ofdm_symbol_size-start_sc)+k;
|
||||
for (int i = 0; i<numDmrsCdmGrpsNoData; i++){
|
||||
if (dmrs_type==NFAPI_NR_DMRS_TYPE1) {
|
||||
if (dmrs_type == NFAPI_NR_DMRS_TYPE1) {
|
||||
delta = i;
|
||||
if (((diff)%2) == delta)
|
||||
return (0);
|
||||
}
|
||||
else {
|
||||
delta = i<<1;
|
||||
if (((diff%6) == delta) || ((diff%6) == (delta+1)))
|
||||
delta = i << 1;
|
||||
if (((diff % 6) == delta) || ((diff % 6) == (delta + 1)))
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
#include "nr_refsig.h"
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h"
|
||||
|
||||
// Table 6.4.1.1.3-1/2 from TS 38.211
|
||||
static const int delta1[8] = {0, 0, 1, 1, 0, 0, 1, 1};
|
||||
@@ -195,9 +196,7 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue,
|
||||
}
|
||||
|
||||
|
||||
int nr_pbch_dmrs_rx(int symbol,
|
||||
unsigned int *nr_gold_pbch,
|
||||
int32_t *output)
|
||||
int nr_pbch_dmrs_rx(int symbol, unsigned int *nr_gold_pbch, int32_t *output)
|
||||
{
|
||||
int m,m0,m1;
|
||||
uint8_t idx=0;
|
||||
@@ -257,14 +256,14 @@ void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, int16_t *output, uin
|
||||
}
|
||||
|
||||
int nr_pusch_lowpaprtype1_dmrs_rx(PHY_VARS_gNB *gNB,
|
||||
unsigned int Ns,
|
||||
int16_t *dmrs_seq,
|
||||
int32_t *output,
|
||||
unsigned short p,
|
||||
unsigned char lp,
|
||||
unsigned short nb_pusch_rb,
|
||||
uint32_t re_offset,
|
||||
uint8_t dmrs_type)
|
||||
unsigned int Ns,
|
||||
int16_t *dmrs_seq,
|
||||
int32_t *output,
|
||||
unsigned short p,
|
||||
unsigned char lp,
|
||||
unsigned short nb_pusch_rb,
|
||||
uint32_t re_offset,
|
||||
uint8_t dmrs_type)
|
||||
{
|
||||
int8_t w, nb_dmrs;
|
||||
int k;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "PHY/NR_REFSIG/nr_refsig.h"
|
||||
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h"
|
||||
|
||||
void nr_generate_dci_top(processingData_L1tx_t *msgTx,
|
||||
int slot,
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#define NR_SCH_DMRS_H
|
||||
|
||||
#include "PHY/defs_nr_common.h"
|
||||
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h"
|
||||
|
||||
#define NR_PDSCH_DMRS_ANTENNA_PORT0 1000
|
||||
#define NR_PDSCH_DMRS_NB_ANTENNA_PORTS 12
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
|
||||
|
||||
NR_gNB_ULSCH_t *find_nr_ulsch(PHY_VARS_gNB *gNB, uint16_t rnti, int pid)
|
||||
static NR_gNB_ULSCH_t *find_nr_ulsch(PHY_VARS_gNB *gNB, uint16_t rnti, int pid)
|
||||
{
|
||||
int16_t first_free_index = -1;
|
||||
AssertFatal(gNB != NULL, "gNB is null\n");
|
||||
@@ -62,7 +62,10 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pusch_pdu_t
|
||||
{
|
||||
int harq_pid = ulsch_pdu->pusch_data.harq_process_id;
|
||||
NR_gNB_ULSCH_t *ulsch = find_nr_ulsch(gNB, ulsch_pdu->rnti, harq_pid);
|
||||
AssertFatal(ulsch, "No ulsch_id found for rnti %04x\n", ulsch_pdu->rnti);
|
||||
if (ulsch == NULL) {
|
||||
LOG_E(NR_PHY, "No ulsch_id found for rnti %04x\n", ulsch_pdu->rnti);
|
||||
return;
|
||||
}
|
||||
|
||||
ulsch->rnti = ulsch_pdu->rnti;
|
||||
ulsch->harq_pid = harq_pid;
|
||||
|
||||
@@ -30,9 +30,14 @@
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#ifndef NR_ULSCH_H_
|
||||
#define NR_ULSCH_H_
|
||||
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "common/utils/threadPool/thread-pool.h"
|
||||
|
||||
#define NUMBER_FRAMES_PHY_UE_INACTIVE 10
|
||||
|
||||
void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch, uint16_t N_RB_UL);
|
||||
|
||||
NR_gNB_ULSCH_t new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL);
|
||||
@@ -71,10 +76,10 @@ void nr_ulsch_unscrambling(int16_t* llr, uint32_t size, uint32_t Nid, uint32_t n
|
||||
|
||||
void nr_ulsch_layer_demapping(int16_t *llr_cw, uint8_t Nl, uint8_t mod_order, uint32_t length, int16_t **llr_layers);
|
||||
|
||||
NR_gNB_ULSCH_t *find_nr_ulsch(PHY_VARS_gNB *gNB, uint16_t rnti, int pid);
|
||||
|
||||
void dump_pusch_stats(FILE *fd,PHY_VARS_gNB *gNB);
|
||||
|
||||
void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB);
|
||||
|
||||
NR_gNB_SCH_STATS_t *get_ulsch_stats(PHY_VARS_gNB *gNB,NR_gNB_ULSCH_t *ulsch);
|
||||
|
||||
#endif /* NR_ULSCH_H_ */
|
||||
|
||||
@@ -1178,7 +1178,8 @@ static uint8_t nr_ulsch_mmse_2layers(NR_DL_FRAME_PARMS *frame_parms,
|
||||
|
||||
int sum_det = 0;
|
||||
for (int k = 0; k < 4; k++) {
|
||||
sum_det += ((((int *)&determ_fin_128[0])[k]) >> 2);
|
||||
AssertFatal(((int *)&determ_fin_128[0])[k] > 0 ,"Right shifting negative values is UB" );
|
||||
sum_det += ((((uint32_t *)&determ_fin_128[0])[k]) >> 2);
|
||||
}
|
||||
|
||||
int b = log2_approx(sum_det) - 8;
|
||||
|
||||
@@ -162,10 +162,15 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
pucch_pdu->bit_len_harq,
|
||||
pucch_pdu->sr_flag);
|
||||
|
||||
/* it might be that the stats list is full: In this case, we will simply
|
||||
* write to some memory on the stack instead of the UE's UCI stats */
|
||||
NR_gNB_UCI_STATS_t stack_uci_stats = {0};
|
||||
NR_gNB_UCI_STATS_t *uci_stats = &stack_uci_stats;
|
||||
NR_gNB_PHY_STATS_t *phy_stats = get_phy_stats(gNB, pucch_pdu->rnti);
|
||||
AssertFatal(phy_stats != NULL, "phy_stats shouldn't be NULL\n");
|
||||
phy_stats->frame = frame;
|
||||
NR_gNB_UCI_STATS_t *uci_stats = &phy_stats->uci_stats;
|
||||
if (phy_stats != NULL) {
|
||||
phy_stats->frame = frame;
|
||||
uci_stats = &phy_stats->uci_stats;
|
||||
}
|
||||
|
||||
int nr_sequences;
|
||||
const uint8_t *mcs;
|
||||
@@ -225,6 +230,8 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
x_im[1] = table_5_2_2_2_2_Im[u[1]];
|
||||
|
||||
c64_t xr[frame_parms->nb_antennas_rx][pucch_pdu->nr_of_symbols][12] __attribute__((aligned(32)));
|
||||
memset(xr, 0, frame_parms->nb_antennas_rx * pucch_pdu->nr_of_symbols * 12 * sizeof(c64_t));
|
||||
|
||||
int64_t xrtmag=0,xrtmag_next=0;
|
||||
uint8_t maxpos=0;
|
||||
uint8_t index=0;
|
||||
@@ -348,9 +355,14 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
#endif
|
||||
|
||||
index=maxpos;
|
||||
uci_stats->pucch0_n00 = gNB->measurements.n0_subband_power_tot_dB[prb_offset[0]];
|
||||
uci_stats->pucch0_n01 = gNB->measurements.n0_subband_power_tot_dB[prb_offset[1]];
|
||||
LOG_D(PHY,"n00[%d] = %d, n01[%d] = %d\n",prb_offset[0],uci_stats->pucch0_n00,prb_offset[1],uci_stats->pucch0_n01);
|
||||
int pucch0_n00 = gNB->measurements.n0_subband_power_tot_dB[prb_offset[0]];
|
||||
int pucch0_n01 = gNB->measurements.n0_subband_power_tot_dB[prb_offset[1]];
|
||||
LOG_D(PHY, "n00[%d] = %d, n01[%d] = %d\n", prb_offset[0], pucch0_n00, prb_offset[1], pucch0_n01);
|
||||
|
||||
uci_stats->pucch0_n00 = pucch0_n00;
|
||||
uci_stats->pucch0_n01 = pucch0_n01;
|
||||
uci_stats->pucch0_thres = gNB->pucch0_thres;
|
||||
|
||||
// estimate CQI for MAC (from antenna port 0 only)
|
||||
int max_n0 =
|
||||
max(gNB->measurements.n0_subband_power_tot_dB[prb_offset[0]], gNB->measurements.n0_subband_power_tot_dB[prb_offset[1]]);
|
||||
@@ -363,7 +375,6 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
else
|
||||
cqi = (640 + SNRtimes10) / 5;
|
||||
|
||||
uci_stats->pucch0_thres = gNB->pucch0_thres; /* + (10*max_n0);*/
|
||||
bool no_conf=false;
|
||||
if (nr_sequences>1) {
|
||||
if (/*xrtmag_dBtimes10 < (30+xrtmag_next_dBtimes10) ||*/ SNRtimes10 < gNB->pucch0_thres) {
|
||||
@@ -372,7 +383,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
"%d.%d PUCCH bad confidence: %d threshold, %d, %d, %d\n",
|
||||
frame,
|
||||
slot,
|
||||
uci_stats->pucch0_thres,
|
||||
gNB->pucch0_thres,
|
||||
SNRtimes10,
|
||||
xrtmag_dBtimes10,
|
||||
xrtmag_next_dBtimes10);
|
||||
@@ -388,7 +399,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
uci_pdu->rssi = 1280 - (10 * dB_fixed(32767 * 32767)) - dB_fixed_times10(signal_energy_ant0);
|
||||
|
||||
if (pucch_pdu->bit_len_harq==0) {
|
||||
uci_pdu->sr.sr_confidence_level = SNRtimes10 < uci_stats->pucch0_thres;
|
||||
uci_pdu->sr.sr_confidence_level = SNRtimes10 < gNB->pucch0_thres;
|
||||
uci_stats->pucch0_sr_trials++;
|
||||
if (xrtmag_dBtimes10>(10*max_n0+100)) {
|
||||
uci_pdu->sr.sr_indication = 1;
|
||||
@@ -415,9 +426,9 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
xrtmag_next_dBtimes10,
|
||||
pucch_power_dBtimes10,
|
||||
max_n0,
|
||||
uci_stats->pucch0_n00,
|
||||
uci_stats->pucch0_n01,
|
||||
uci_stats->pucch0_thres,
|
||||
pucch0_n00,
|
||||
pucch0_n01,
|
||||
gNB->pucch0_thres,
|
||||
cqi,
|
||||
SNRtimes10,
|
||||
10 * log10((double)signal_energy_ant0));
|
||||
@@ -450,9 +461,9 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
xrtmag_next_dBtimes10,
|
||||
pucch_power_dBtimes10,
|
||||
max_n0,
|
||||
uci_stats->pucch0_n00,
|
||||
uci_stats->pucch0_n01,
|
||||
uci_stats->pucch0_thres,
|
||||
pucch0_n00,
|
||||
pucch0_n01,
|
||||
gNB->pucch0_thres,
|
||||
cqi,
|
||||
SNRtimes10);
|
||||
if (pucch_pdu->sr_flag == 1) {
|
||||
|
||||
@@ -33,29 +33,22 @@
|
||||
// The adjustment is performed once per frame based on the
|
||||
// last channel estimate of the receiver
|
||||
|
||||
void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
|
||||
PHY_VARS_NR_UE *ue,
|
||||
module_id_t gNB_id,
|
||||
const int estimateSz,
|
||||
struct complex16 dl_ch_estimates_time[][estimateSz],
|
||||
uint8_t frame,
|
||||
uint8_t subframe,
|
||||
unsigned char clear,
|
||||
short coef)
|
||||
int nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
|
||||
PHY_VARS_NR_UE *ue,
|
||||
module_id_t gNB_id,
|
||||
const int estimateSz,
|
||||
struct complex16 dl_ch_estimates_time[][estimateSz],
|
||||
uint8_t frame,
|
||||
uint8_t slot,
|
||||
short coef)
|
||||
{
|
||||
|
||||
static int count_max_pos_ok = 0;
|
||||
static int first_time = 1;
|
||||
int max_val = 0, max_pos = 0;
|
||||
const int sync_pos = 0;
|
||||
uint8_t sync_offset = 0;
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_IN);
|
||||
|
||||
short ncoef = 32767 - coef;
|
||||
|
||||
LOG_D(PHY,"AbsSubframe %d: rx_offset (before) = %d\n",subframe,ue->rx_offset);
|
||||
|
||||
// search for maximum position within the cyclic prefix
|
||||
for (int i = -frame_parms->nb_prefix_samples/2; i < frame_parms->nb_prefix_samples/2; i++) {
|
||||
int temp = 0;
|
||||
@@ -74,53 +67,32 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
|
||||
}
|
||||
|
||||
// filter position to reduce jitter
|
||||
if (clear == 1)
|
||||
ue->max_pos_fil = max_pos << 15;
|
||||
else
|
||||
ue->max_pos_fil = ((ue->max_pos_fil * coef) >> 15) + (max_pos * ncoef);
|
||||
ue->max_pos_avg = ((ue->max_pos_avg * coef) >> 15) + (max_pos * ncoef);
|
||||
|
||||
// do not filter to have proactive timing adjustment
|
||||
//ue->max_pos_fil = max_pos << 15;
|
||||
|
||||
int diff = (ue->max_pos_fil >> 15) - sync_pos;
|
||||
int diff = ue->max_pos_avg >> 15;
|
||||
|
||||
if (frame_parms->freq_range==nr_FR2)
|
||||
sync_offset = 2;
|
||||
else
|
||||
sync_offset = 0;
|
||||
|
||||
if ( abs(diff) < (SYNCH_HYST+sync_offset) )
|
||||
ue->rx_offset = 0;
|
||||
else
|
||||
ue->rx_offset = diff;
|
||||
int sampleShift = 0;
|
||||
if (abs(diff) > (NR_SYNCH_HYST + sync_offset))
|
||||
sampleShift = diff;
|
||||
|
||||
const int sample_shift = -(ue->rx_offset>>1);
|
||||
const int sample_shift = -(sampleShift / 2);
|
||||
// reset IIR filter for next offset calculation
|
||||
ue->max_pos_fil += sample_shift * 32768;
|
||||
ue->max_pos_avg += sample_shift * 32768;
|
||||
|
||||
if(abs(diff)<5)
|
||||
count_max_pos_ok ++;
|
||||
else
|
||||
count_max_pos_ok = 0;
|
||||
|
||||
//printf("adjust sync count_max_pos_ok = %d\n",count_max_pos_ok);
|
||||
|
||||
if(count_max_pos_ok > 10 && first_time == 1) {
|
||||
first_time = 0;
|
||||
ue->time_sync_cell = 1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_PHY
|
||||
LOG_I(PHY,"AbsSubframe %d: diff = %i, rx_offset (final) = %i : clear = %d, max_pos = %d, max_pos_fil = %d, max_val = %d, sync_pos %d\n",
|
||||
subframe,
|
||||
LOG_D(PHY,
|
||||
"Slot %d: diff = %i, rx_offset (final) = %i : max_pos = %d, max_pos filtered = %ld, max_power = %d\n",
|
||||
slot,
|
||||
diff,
|
||||
ue->rx_offset,
|
||||
clear,
|
||||
sampleShift,
|
||||
max_pos,
|
||||
ue->max_pos_fil,
|
||||
max_val,
|
||||
sync_pos);
|
||||
#endif //DEBUG_PHY
|
||||
ue->max_pos_avg,
|
||||
max_val);
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT);
|
||||
return sample_shift;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include "SCHED_NR_UE/defs.h"
|
||||
#include "nr_estimation.h"
|
||||
@@ -34,6 +33,8 @@
|
||||
#include "filt16a_32.h"
|
||||
#include "T.h"
|
||||
#include <openair1/PHY/TOOLS/phy_scope_interface.h>
|
||||
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h"
|
||||
|
||||
extern openair0_config_t openair0_cfg[];
|
||||
|
||||
//#define DEBUG_PDSCH
|
||||
@@ -129,6 +130,8 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
|
||||
printf("[gNB %d][rsc %d] PRS config l %d k_prime %d:\nprs_cfg->SymbolStart %d\nprs_cfg->NumPRSSymbols %d\nprs_cfg->NumRB %d\nprs_cfg->CombSize %d\n", gNB_id, rsc_id, l, k_prime, prs_cfg->SymbolStart, prs_cfg->NumPRSSymbols, prs_cfg->NumRB, prs_cfg->CombSize);
|
||||
#endif
|
||||
// Pilots generation and modulation
|
||||
|
||||
AssertFatal(num_pilots > 0, "num_pilots needs to be gt 0 or mod_prs[0] UB");
|
||||
for (int m = 0; m < num_pilots; m++)
|
||||
{
|
||||
idx = (((nr_gold_prs[l][(m<<1)>>5])>>((m<<1)&0x1f))&3);
|
||||
@@ -658,7 +661,8 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
|
||||
#endif
|
||||
|
||||
// generate pilot
|
||||
nr_pbch_dmrs_rx(dmrss,ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]);
|
||||
// Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS
|
||||
nr_pbch_dmrs_rx(dmrss, ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]);
|
||||
|
||||
for (int aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
|
||||
|
||||
@@ -898,7 +902,8 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
}
|
||||
|
||||
// generate pilot
|
||||
nr_pbch_dmrs_rx(dmrss,ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]);
|
||||
// Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS
|
||||
nr_pbch_dmrs_rx(dmrss, ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]);
|
||||
|
||||
for (int aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
|
||||
|
||||
@@ -1111,7 +1116,8 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
dmrs_ref = BWPStart;
|
||||
// generate pilot
|
||||
int pilot[(nb_rb_coreset + dmrs_ref) * 3] __attribute__((aligned(16)));
|
||||
nr_pdcch_dmrs_rx(ue,Ns,ue->nr_gold_pdcch[gNB_id][Ns][symbol], &pilot[0],2000,(nb_rb_coreset+dmrs_ref));
|
||||
// Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS
|
||||
nr_pdcch_dmrs_rx(ue, Ns, ue->nr_gold_pdcch[gNB_id][Ns][symbol], &pilot[0], 2000, (nb_rb_coreset + dmrs_ref));
|
||||
|
||||
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
|
||||
|
||||
@@ -1648,7 +1654,15 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
}
|
||||
|
||||
c16_t pilot[3280] __attribute__((aligned(16)));
|
||||
nr_pdsch_dmrs_rx(ue, Ns, ue->nr_gold_pdsch[gNB_id][Ns][symbol][nscid], (int32_t *)pilot, 1000 + p, 0, nb_rb_pdsch + rb_offset, config_type);
|
||||
// Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS
|
||||
nr_pdsch_dmrs_rx(ue,
|
||||
Ns,
|
||||
ue->nr_gold_pdsch[gNB_id][Ns][symbol][nscid],
|
||||
(int32_t *)pilot,
|
||||
1000 + p,
|
||||
0,
|
||||
nb_rb_pdsch + rb_offset,
|
||||
config_type);
|
||||
|
||||
uint8_t nushift = 0;
|
||||
if (config_type == NFAPI_NR_DMRS_TYPE1) {
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
*/
|
||||
|
||||
/*!\brief Timing drift hysterisis in samples*/
|
||||
#define SYNCH_HYST 2
|
||||
#define NR_SYNCH_HYST 1
|
||||
|
||||
/* A function to perform the channel estimation of DL PRS signal */
|
||||
int nr_prs_channel_estimation(uint8_t gNB_id,
|
||||
@@ -91,15 +91,14 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
int rxdataFsize,
|
||||
c16_t rxdataF[][rxdataFsize]);
|
||||
|
||||
void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
|
||||
PHY_VARS_NR_UE *ue,
|
||||
module_id_t gNB_id,
|
||||
int estimateSz,
|
||||
struct complex16 dl_ch_estimates_time [][estimateSz],
|
||||
uint8_t frame,
|
||||
uint8_t subframe,
|
||||
unsigned char clear,
|
||||
short coef);
|
||||
int nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
|
||||
PHY_VARS_NR_UE *ue,
|
||||
module_id_t gNB_id,
|
||||
int estimateSz,
|
||||
struct complex16 dl_ch_estimates_time[][estimateSz],
|
||||
uint8_t frame,
|
||||
uint8_t subframe,
|
||||
short coef);
|
||||
|
||||
void nr_ue_measurements(PHY_VARS_NR_UE *ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
|
||||
@@ -510,6 +510,8 @@ void cic_decimator(int16_t *input_buffer, int16_t *output_buffer, int length, in
|
||||
|
||||
void fir_decimator(int16_t *input_buffer, int16_t *output_buffer, int length, int rate_change, int scaling_factor)
|
||||
{
|
||||
AssertFatal(length > 0, "Precondition not met");
|
||||
|
||||
int32_t *buffer_one;
|
||||
int32_t *buffer_two;
|
||||
int32_t *input;
|
||||
|
||||
@@ -409,6 +409,7 @@ int nr_csi_rs_channel_estimation(const PHY_VARS_NR_UE *ue,
|
||||
}
|
||||
|
||||
/// Power noise estimation
|
||||
AssertFatal(csirs_config_pdu->nr_of_rbs > 0, " nr_of_rbs needs to be greater than 0\n");
|
||||
uint16_t noise_real[frame_parms->nb_antennas_rx][N_ports][csirs_config_pdu->nr_of_rbs];
|
||||
uint16_t noise_imag[frame_parms->nb_antennas_rx][N_ports][csirs_config_pdu->nr_of_rbs];
|
||||
for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) {
|
||||
|
||||
@@ -36,15 +36,14 @@
|
||||
#include "PHY/phy_extern_nr_ue.h"
|
||||
#include "PHY/CODING/coding_extern.h"
|
||||
#include "PHY/CODING/coding_defs.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
|
||||
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
|
||||
#include "SCHED_NR_UE/defs.h"
|
||||
#include "SIMULATION/TOOLS/sim.h"
|
||||
#include "executables/nr-uesoftmodem.h"
|
||||
#include "PHY/CODING/nrLDPC_extern.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include "openair1/PHY/TOOLS/phy_scope_interface.h"
|
||||
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h"
|
||||
|
||||
//#define ENABLE_PHY_PAYLOAD_DEBUG 1
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include <complex.h>
|
||||
#include "openair1/PHY/TOOLS/phy_scope_interface.h"
|
||||
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h"
|
||||
|
||||
/* dynamic shift for LLR computation for TM3/4
|
||||
* set as command line argument, see lte-softmodem.c
|
||||
@@ -275,7 +276,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
const int frame = proc->frame_rx;
|
||||
const int nr_slot_rx = proc->nr_slot_rx;
|
||||
const int gNB_id = proc->gNB_id;
|
||||
|
||||
uint8_t slot = 0;
|
||||
|
||||
int32_t codeword_TB0 = -1;
|
||||
@@ -699,7 +699,8 @@ void nr_dlsch_deinterleaving(uint8_t symbol,
|
||||
N_bundle = nb_rb_pdsch/L;
|
||||
C=N_bundle/R;
|
||||
|
||||
uint32_t *bundle_deint = malloc(N_bundle*sizeof(uint32_t));
|
||||
uint32_t bundle_deint[N_bundle];
|
||||
memset(bundle_deint, 0 , sizeof(bundle_deint));
|
||||
|
||||
printf("N_bundle %u L %d nb_rb_pdsch %d\n",N_bundle, L,nb_rb_pdsch);
|
||||
|
||||
@@ -727,7 +728,6 @@ void nr_dlsch_deinterleaving(uint8_t symbol,
|
||||
//printf("k %d m %d bundle_deint %d llr_deint %d\n", k, m, bundle_deint[k], llr_deint[bundle_deint[k]*nb_re*L+m]);
|
||||
}
|
||||
}
|
||||
free(bundle_deint);
|
||||
}
|
||||
|
||||
//==============================================================================================
|
||||
|
||||
@@ -50,7 +50,7 @@ extern openair0_config_t openair0_cfg[];
|
||||
//static nfapi_nr_config_request_t* config =&config_t;
|
||||
int cnt=0;
|
||||
|
||||
#define DEBUG_INITIAL_SYNCH
|
||||
// #define DEBUG_INITIAL_SYNCH
|
||||
#define DUMP_PBCH_CH_ESTIMATES 0
|
||||
|
||||
// create a new node of SSB structure
|
||||
@@ -111,11 +111,6 @@ int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
|
||||
NR_UE_SSB *best_ssb = NULL;
|
||||
NR_UE_SSB *current_ssb;
|
||||
|
||||
#ifdef DEBUG_INITIAL_SYNCH
|
||||
LOG_I(PHY,"[UE%d] Initial sync: starting PBCH detection (rx_offset %d)\n",ue->Mod_id,
|
||||
ue->rx_offset);
|
||||
#endif
|
||||
|
||||
uint8_t N_L = (frame_parms->Lmax == 4)? 4:8;
|
||||
uint8_t N_hf = (frame_parms->Lmax == 4)? 2:1;
|
||||
|
||||
@@ -129,7 +124,7 @@ int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
|
||||
start_meas(&ue->dlsch_channel_estimation_stats);
|
||||
// computing correlation between received DMRS symbols and transmitted sequence for current i_ssb and n_hf
|
||||
for(int i=pbch_initial_symbol; i<pbch_initial_symbol+3;i++)
|
||||
nr_pbch_dmrs_correlation(ue,proc,i,i-pbch_initial_symbol,current_ssb,rxdataF);
|
||||
nr_pbch_dmrs_correlation(ue, proc, i, i - pbch_initial_symbol, current_ssb, rxdataF);
|
||||
stop_meas(&ue->dlsch_channel_estimation_stats);
|
||||
|
||||
current_ssb->metric = current_ssb->c_re*current_ssb->c_re + current_ssb->c_im*current_ssb->c_im;
|
||||
@@ -147,7 +142,7 @@ int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
|
||||
while (ret!=0 && temp_ptr != NULL) {
|
||||
|
||||
start_meas(&ue->dlsch_channel_estimation_stats);
|
||||
// computing channel estimation for selected best ssb
|
||||
// computing channel estimation for selected best ssb
|
||||
const int estimateSz = frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size;
|
||||
__attribute__ ((aligned(32))) struct complex16 dl_ch_estimates[frame_parms->nb_antennas_rx][estimateSz];
|
||||
__attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size];
|
||||
@@ -178,242 +173,230 @@ int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
|
||||
|
||||
free_list(best_ssb);
|
||||
|
||||
|
||||
if (ret==0) {
|
||||
|
||||
frame_parms->nb_antenna_ports_gNB = 1; //pbch_tx_ant;
|
||||
|
||||
// set initial transmission mode to 1 or 2 depending on number of detected TX antennas
|
||||
//frame_parms->mode1_flag = (pbch_tx_ant==1);
|
||||
// openair_daq_vars.dlsch_transmission_mode = (pbch_tx_ant>1) ? 2 : 1;
|
||||
if (ret == 0)
|
||||
frame_parms->nb_antenna_ports_gNB = 1; // pbch_tx_ant;
|
||||
|
||||
// set initial transmission mode to 1 or 2 depending on number of detected TX antennas
|
||||
// frame_parms->mode1_flag = (pbch_tx_ant==1);
|
||||
// openair_daq_vars.dlsch_transmission_mode = (pbch_tx_ant>1) ? 2 : 1;
|
||||
|
||||
#ifdef DEBUG_INITIAL_SYNCH
|
||||
LOG_I(PHY, "[UE%d] Initial sync: pbch decoded sucessfully, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index);
|
||||
#endif
|
||||
return(0);
|
||||
} else {
|
||||
return(-1);
|
||||
}
|
||||
|
||||
LOG_I(PHY, "[UE%d] Initial sync: pbch decoded sucessfully, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int nr_initial_sync(const UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames, int sa)
|
||||
nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames, int sa)
|
||||
{
|
||||
|
||||
int32_t sync_pos, sync_pos_frame; // k_ssb, N_ssb_crb, sync_pos2,
|
||||
int32_t metric_tdd_ncp=0;
|
||||
int32_t metric_tdd_ncp = 0;
|
||||
uint8_t phase_tdd_ncp;
|
||||
int frame_id;
|
||||
|
||||
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
|
||||
int ret=-1;
|
||||
int rx_power=0; //aarx,
|
||||
|
||||
nr_initial_sync_t ret = {true, 0};
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INITIAL_UE_SYNC, VCD_FUNCTION_IN);
|
||||
|
||||
|
||||
LOG_D(PHY,"nr_initial sync ue RB_DL %d\n", fp->N_RB_DL);
|
||||
LOG_D(PHY, "nr_initial sync ue RB_DL %d\n", fp->N_RB_DL);
|
||||
|
||||
/* Initial synchronisation
|
||||
*
|
||||
* 1 radio frame = 10 ms
|
||||
* <--------------------------------------------------------------------------->
|
||||
* -----------------------------------------------------------------------------
|
||||
* | Received UE data buffer |
|
||||
* ----------------------------------------------------------------------------
|
||||
* --------------------------
|
||||
* <-------------->| pss | pbch | sss | pbch |
|
||||
* --------------------------
|
||||
* sync_pos SS/PBCH block
|
||||
*/
|
||||
* 1 radio frame = 10 ms
|
||||
* <--------------------------------------------------------------------------->
|
||||
* -----------------------------------------------------------------------------
|
||||
* | Received UE data buffer |
|
||||
* ----------------------------------------------------------------------------
|
||||
* --------------------------
|
||||
* <-------------->| pss | pbch | sss | pbch |
|
||||
* --------------------------
|
||||
* sync_pos SS/PBCH block
|
||||
*/
|
||||
|
||||
const uint32_t rxdataF_sz = ue->frame_parms.samples_per_slot_wCP;
|
||||
__attribute__ ((aligned(32))) c16_t rxdataF[ue->frame_parms.nb_antennas_rx][rxdataF_sz];
|
||||
__attribute__((aligned(32))) c16_t rxdataF[ue->frame_parms.nb_antennas_rx][rxdataF_sz];
|
||||
cnt++;
|
||||
if (1){ // (cnt>100)
|
||||
cnt =0;
|
||||
if (1) { // (cnt>100)
|
||||
cnt = 0;
|
||||
|
||||
// initial sync performed on two successive frames, if pbch passes on first frame, no need to process second frame
|
||||
// only one frame is used for symulation tools
|
||||
for (frame_id = 0; frame_id < n_frames; frame_id++) {
|
||||
/* process pss search on received buffer */
|
||||
sync_pos = pss_synchro_nr(ue, frame_id, NO_RATE_CHANGE);
|
||||
if (sync_pos < fp->nb_prefix_samples)
|
||||
continue;
|
||||
// initial sync performed on two successive frames, if pbch passes on first frame, no need to process second frame
|
||||
// only one frame is used for symulation tools
|
||||
for (frame_id = 0; frame_id < n_frames; frame_id++) {
|
||||
/* process pss search on received buffer */
|
||||
sync_pos = pss_synchro_nr(ue, frame_id, NO_RATE_CHANGE);
|
||||
if (sync_pos < fp->nb_prefix_samples)
|
||||
continue;
|
||||
|
||||
ue->ssb_offset = sync_pos - fp->nb_prefix_samples;
|
||||
ue->ssb_offset = sync_pos - fp->nb_prefix_samples;
|
||||
|
||||
#ifdef DEBUG_INITIAL_SYNCH
|
||||
LOG_I(PHY, "[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d\n", ue->Mod_id, sync_pos, ue->common_vars.nid2);
|
||||
LOG_I(PHY,"sync_pos %d ssb_offset %d \n",sync_pos,ue->ssb_offset);
|
||||
LOG_I(PHY, "[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d\n", ue->Mod_id, sync_pos, ue->common_vars.nid2);
|
||||
LOG_I(PHY, "sync_pos %d ssb_offset %d \n", sync_pos, ue->ssb_offset);
|
||||
#endif
|
||||
|
||||
/* check that SSS/PBCH block is continuous inside the received buffer */
|
||||
if (ue->ssb_offset + NR_N_SYMBOLS_SSB * (fp->ofdm_symbol_size + fp->nb_prefix_samples) < fp->samples_per_frame) {
|
||||
/* check that SSS/PBCH block is continuous inside the received buffer */
|
||||
if (ue->ssb_offset + NR_N_SYMBOLS_SSB * (fp->ofdm_symbol_size + fp->nb_prefix_samples) < fp->samples_per_frame) {
|
||||
// digital compensation of FFO for SSB symbols
|
||||
if (ue->UE_fo_compensation) {
|
||||
double s_time = 1 / (1.0e3 * fp->samples_per_subframe); // sampling time
|
||||
double off_angle = -2 * M_PI * s_time * (ue->common_vars.freq_offset); // offset rotation angle compensation per sample
|
||||
|
||||
// digital compensation of FFO for SSB symbols
|
||||
if (ue->UE_fo_compensation){
|
||||
double s_time = 1/(1.0e3*fp->samples_per_subframe); // sampling time
|
||||
double off_angle = -2*M_PI*s_time*(ue->common_vars.freq_offset); // offset rotation angle compensation per sample
|
||||
// In SA we need to perform frequency offset correction until the end of buffer because we need to decode SIB1
|
||||
// and we do not know yet in which slot it goes.
|
||||
|
||||
// In SA we need to perform frequency offset correction until the end of buffer because we need to decode SIB1
|
||||
// and we do not know yet in which slot it goes.
|
||||
|
||||
for (int n = frame_id * fp->samples_per_frame; n < (frame_id + 1) * fp->samples_per_frame; n++) {
|
||||
for (int ar=0; ar<fp->nb_antennas_rx; ar++) {
|
||||
const double re = ue->common_vars.rxdata[ar][n].r;
|
||||
const double im = ue->common_vars.rxdata[ar][n].i;
|
||||
ue->common_vars.rxdata[ar][n].r = (short)(round(re * cos(n * off_angle) - im * sin(n * off_angle)));
|
||||
ue->common_vars.rxdata[ar][n].i = (short)(round(re * sin(n * off_angle) + im * cos(n * off_angle)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* slot_fep function works for lte and takes into account begining of frame with prefix for subframe 0 */
|
||||
/* for NR this is not the case but slot_fep is still used for computing FFT of samples */
|
||||
/* in order to achieve correct processing for NR prefix samples is forced to 0 and then restored after function call */
|
||||
/* symbol number are from beginning of SS/PBCH blocks as below: */
|
||||
/* Signal PSS PBCH SSS PBCH */
|
||||
/* symbol number 0 1 2 3 */
|
||||
/* time samples in buffer rxdata are used as input of FFT -> FFT results are stored in the frequency buffer rxdataF */
|
||||
/* rxdataF stores SS/PBCH from beginning of buffers in the same symbol order as in time domain */
|
||||
|
||||
for (int i = 0; i < NR_N_SYMBOLS_SSB; i++)
|
||||
nr_slot_fep_init_sync(ue, proc, i, frame_id * fp->samples_per_frame + ue->ssb_offset, false, rxdataF, link_type_dl);
|
||||
|
||||
#ifdef DEBUG_INITIAL_SYNCH
|
||||
LOG_I(PHY,"Calling sss detection (normal CP)\n");
|
||||
#endif
|
||||
|
||||
int freq_offset_sss = 0;
|
||||
bool ret_sss = rx_sss_nr(ue, proc, &metric_tdd_ncp, &phase_tdd_ncp, &freq_offset_sss, rxdataF);
|
||||
ret = !ret_sss;
|
||||
// digital compensation of FFO for SSB symbols
|
||||
if (ue->UE_fo_compensation){
|
||||
double s_time = 1/(1.0e3*fp->samples_per_subframe); // sampling time
|
||||
double off_angle = -2*M_PI*s_time*freq_offset_sss; // offset rotation angle compensation per sample
|
||||
|
||||
// In SA we need to perform frequency offset correction until the end of buffer because we need to decode SIB1
|
||||
// and we do not know yet in which slot it goes.
|
||||
for (int n = frame_id * fp->samples_per_frame; n < (frame_id + 1) * fp->samples_per_frame; n++) {
|
||||
for (int ar=0; ar<fp->nb_antennas_rx; ar++) {
|
||||
const double re = ue->common_vars.rxdata[ar][n].r;
|
||||
const double im = ue->common_vars.rxdata[ar][n].i;
|
||||
ue->common_vars.rxdata[ar][n].r = (short)(round(re * cos(n * off_angle) - im * sin(n * off_angle)));
|
||||
ue->common_vars.rxdata[ar][n].i = (short)(round(re * sin(n * off_angle) + im * cos(n * off_angle)));
|
||||
for (int n = frame_id * fp->samples_per_frame; n < (frame_id + 1) * fp->samples_per_frame; n++) {
|
||||
for (int ar = 0; ar < fp->nb_antennas_rx; ar++) {
|
||||
const double re = ue->common_vars.rxdata[ar][n].r;
|
||||
const double im = ue->common_vars.rxdata[ar][n].i;
|
||||
ue->common_vars.rxdata[ar][n].r = (short)(round(re * cos(n * off_angle) - im * sin(n * off_angle)));
|
||||
ue->common_vars.rxdata[ar][n].i = (short)(round(re * sin(n * off_angle) + im * cos(n * off_angle)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ue->common_vars.freq_offset += freq_offset_sss;
|
||||
}
|
||||
|
||||
if (ret==0) { //we got sss channel
|
||||
nr_gold_pbch(ue);
|
||||
ret = nr_pbch_detection(proc, ue, 1, rxdataF); // start pbch detection at first symbol after pss
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
|
||||
// sync at symbol ue->symbol_offset
|
||||
// computing the offset wrt the beginning of the frame
|
||||
int mu = fp->numerology_index;
|
||||
// number of symbols with different prefix length
|
||||
// every 7*(1<<mu) symbols there is a different prefix length (38.211 5.3.1)
|
||||
int n_symb_prefix0 = (ue->symbol_offset/(7*(1<<mu)))+1;
|
||||
sync_pos_frame = n_symb_prefix0*(fp->ofdm_symbol_size + fp->nb_prefix_samples0)+(ue->symbol_offset-n_symb_prefix0)*(fp->ofdm_symbol_size + fp->nb_prefix_samples);
|
||||
// for a correct computation of frame number to sync with the one decoded at MIB we need to take into account in which of the n_frames we got sync
|
||||
ue->init_sync_frame = n_frames - 1 - frame_id;
|
||||
|
||||
// compute the scramblingID_pdcch and the gold pdcch
|
||||
ue->scramblingID_pdcch = fp->Nid_cell;
|
||||
nr_gold_pdcch(ue,fp->Nid_cell);
|
||||
|
||||
// compute the scrambling IDs for PDSCH DMRS
|
||||
for (int i=0; i<NR_NB_NSCID; i++) {
|
||||
ue->scramblingID_dlsch[i]=fp->Nid_cell;
|
||||
nr_gold_pdsch(ue, i, ue->scramblingID_dlsch[i]);
|
||||
}
|
||||
|
||||
nr_init_csi_rs(fp, ue->nr_csi_info->nr_gold_csi_rs, fp->Nid_cell);
|
||||
|
||||
// initialize the pusch dmrs
|
||||
for (int i=0; i<NR_NB_NSCID; i++) {
|
||||
ue->scramblingID_ulsch[i]=fp->Nid_cell;
|
||||
nr_init_pusch_dmrs(ue, ue->scramblingID_ulsch[i], i);
|
||||
}
|
||||
|
||||
|
||||
// we also need to take into account the shift by samples_per_frame in case the if is true
|
||||
if (ue->ssb_offset < sync_pos_frame){
|
||||
ue->rx_offset = fp->samples_per_frame - sync_pos_frame + ue->ssb_offset;
|
||||
ue->init_sync_frame += 1;
|
||||
}
|
||||
else
|
||||
ue->rx_offset = ue->ssb_offset - sync_pos_frame;
|
||||
}
|
||||
|
||||
/*
|
||||
int nb_prefix_samples0 = fp->nb_prefix_samples0;
|
||||
fp->nb_prefix_samples0 = fp->nb_prefix_samples;
|
||||
|
||||
nr_slot_fep(ue, proc, 0, 0, ue->ssb_offset, 0, NR_PDCCH_EST);
|
||||
nr_slot_fep(ue, proc, 1, 0, ue->ssb_offset, 0, NR_PDCCH_EST);
|
||||
fp->nb_prefix_samples0 = nb_prefix_samples0;
|
||||
|
||||
LOG_I(PHY,"[UE %d] AUTOTEST Cell Sync : frame = %d, rx_offset %d, freq_offset %d \n",
|
||||
ue->Mod_id,
|
||||
ue->proc.proc_rxtx[0].frame_rx,
|
||||
ue->rx_offset,
|
||||
ue->common_vars.freq_offset );
|
||||
*/
|
||||
/* slot_fep function works for lte and takes into account begining of frame with prefix for subframe 0 */
|
||||
/* for NR this is not the case but slot_fep is still used for computing FFT of samples */
|
||||
/* in order to achieve correct processing for NR prefix samples is forced to 0 and then restored after function call */
|
||||
/* symbol number are from beginning of SS/PBCH blocks as below: */
|
||||
/* Signal PSS PBCH SSS PBCH */
|
||||
/* symbol number 0 1 2 3 */
|
||||
/* time samples in buffer rxdata are used as input of FFT -> FFT results are stored in the frequency buffer rxdataF */
|
||||
/* rxdataF stores SS/PBCH from beginning of buffers in the same symbol order as in time domain */
|
||||
|
||||
for (int i = 0; i < NR_N_SYMBOLS_SSB; i++)
|
||||
nr_slot_fep_init_sync(ue, proc, i, frame_id * fp->samples_per_frame + ue->ssb_offset, false, rxdataF, link_type_dl);
|
||||
|
||||
#ifdef DEBUG_INITIAL_SYNCH
|
||||
LOG_I(PHY,"TDD Normal prefix: CellId %d metric %d, phase %d, pbch %d\n",
|
||||
fp->Nid_cell,metric_tdd_ncp,phase_tdd_ncp,ret);
|
||||
LOG_I(PHY, "Calling sss detection (normal CP)\n");
|
||||
#endif
|
||||
|
||||
}
|
||||
else {
|
||||
int freq_offset_sss = 0;
|
||||
bool ret_sss = rx_sss_nr(ue, proc, &metric_tdd_ncp, &phase_tdd_ncp, &freq_offset_sss, rxdataF);
|
||||
ret.cell_notdetected = !ret_sss; // rx_sss_nr returns true if success
|
||||
// digital compensation of FFO for SSB symbols
|
||||
if (ue->UE_fo_compensation) {
|
||||
double s_time = 1 / (1.0e3 * fp->samples_per_subframe); // sampling time
|
||||
double off_angle = -2 * M_PI * s_time * freq_offset_sss; // offset rotation angle compensation per sample
|
||||
|
||||
// In SA we need to perform frequency offset correction until the end of buffer because we need to decode SIB1
|
||||
// and we do not know yet in which slot it goes.
|
||||
for (int n = frame_id * fp->samples_per_frame; n < (frame_id + 1) * fp->samples_per_frame; n++) {
|
||||
for (int ar = 0; ar < fp->nb_antennas_rx; ar++) {
|
||||
const double re = ue->common_vars.rxdata[ar][n].r;
|
||||
const double im = ue->common_vars.rxdata[ar][n].i;
|
||||
ue->common_vars.rxdata[ar][n].r = (short)(round(re * cos(n * off_angle) - im * sin(n * off_angle)));
|
||||
ue->common_vars.rxdata[ar][n].i = (short)(round(re * sin(n * off_angle) + im * cos(n * off_angle)));
|
||||
}
|
||||
}
|
||||
|
||||
ue->common_vars.freq_offset += freq_offset_sss;
|
||||
}
|
||||
|
||||
if (ret.cell_notdetected == 0) { // we got sss channel
|
||||
nr_gold_pbch(ue);
|
||||
ret.cell_notdetected = nr_pbch_detection(proc, ue, 1, rxdataF); // start pbch detection at first symbol after pss
|
||||
}
|
||||
|
||||
if (ret.cell_notdetected == 0) {
|
||||
// sync at symbol ue->symbol_offset
|
||||
// computing the offset wrt the beginning of the frame
|
||||
int mu = fp->numerology_index;
|
||||
// number of symbols with different prefix length
|
||||
// every 7*(1<<mu) symbols there is a different prefix length (38.211 5.3.1)
|
||||
int n_symb_prefix0 = (ue->symbol_offset / (7 * (1 << mu))) + 1;
|
||||
sync_pos_frame = n_symb_prefix0 * (fp->ofdm_symbol_size + fp->nb_prefix_samples0)
|
||||
+ (ue->symbol_offset - n_symb_prefix0) * (fp->ofdm_symbol_size + fp->nb_prefix_samples);
|
||||
// for a correct computation of frame number to sync with the one decoded at MIB we need to take into account in which of
|
||||
// the n_frames we got sync
|
||||
ue->init_sync_frame = n_frames - 1 - frame_id;
|
||||
|
||||
// compute the scramblingID_pdcch and the gold pdcch
|
||||
ue->scramblingID_pdcch = fp->Nid_cell;
|
||||
nr_gold_pdcch(ue, fp->Nid_cell);
|
||||
|
||||
// compute the scrambling IDs for PDSCH DMRS
|
||||
for (int i = 0; i < NR_NB_NSCID; i++) {
|
||||
ue->scramblingID_dlsch[i] = fp->Nid_cell;
|
||||
nr_gold_pdsch(ue, i, ue->scramblingID_dlsch[i]);
|
||||
}
|
||||
|
||||
nr_init_csi_rs(fp, ue->nr_csi_info->nr_gold_csi_rs, fp->Nid_cell);
|
||||
|
||||
// initialize the pusch dmrs
|
||||
for (int i = 0; i < NR_NB_NSCID; i++) {
|
||||
ue->scramblingID_ulsch[i] = fp->Nid_cell;
|
||||
nr_init_pusch_dmrs(ue, ue->scramblingID_ulsch[i], i);
|
||||
}
|
||||
|
||||
// we also need to take into account the shift by samples_per_frame in case the if is true
|
||||
if (ue->ssb_offset < sync_pos_frame) {
|
||||
ret.rx_offset = fp->samples_per_frame - sync_pos_frame + ue->ssb_offset;
|
||||
ue->init_sync_frame += 1;
|
||||
} else
|
||||
ret.rx_offset = ue->ssb_offset - sync_pos_frame;
|
||||
}
|
||||
|
||||
/*
|
||||
int nb_prefix_samples0 = fp->nb_prefix_samples0;
|
||||
fp->nb_prefix_samples0 = fp->nb_prefix_samples;
|
||||
|
||||
nr_slot_fep(ue, proc, 0, 0, ue->ssb_offset, 0, NR_PDCCH_EST);
|
||||
nr_slot_fep(ue, proc, 1, 0, ue->ssb_offset, 0, NR_PDCCH_EST);
|
||||
fp->nb_prefix_samples0 = nb_prefix_samples0;
|
||||
|
||||
LOG_I(PHY,"[UE %d] AUTOTEST Cell Sync : frame = %d, rx_offset %d, freq_offset %d \n",
|
||||
ue->Mod_id,
|
||||
ue->proc.proc_rxtx[0].frame_rx,
|
||||
ue->rx_offset,
|
||||
ue->common_vars.freq_offset );
|
||||
*/
|
||||
|
||||
#ifdef DEBUG_INITIAL_SYNCH
|
||||
LOG_I(PHY,"TDD Normal prefix: SSS error condition: sync_pos %d\n", sync_pos);
|
||||
LOG_I(PHY,
|
||||
"TDD Normal prefix: CellId %d metric %d, phase %d, pbch detected %d, measured offset %d\n",
|
||||
fp->Nid_cell,
|
||||
metric_tdd_ncp,
|
||||
phase_tdd_ncp,
|
||||
!ret.cell_notdetected,
|
||||
ret.rx_offset);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
#ifdef DEBUG_INITIAL_SYNCH
|
||||
LOG_I(PHY, "TDD Normal prefix: SSS error condition: sync_pos %d\n", sync_pos);
|
||||
#endif
|
||||
}
|
||||
if (ret == 0) break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ret = -1;
|
||||
if (ret.cell_notdetected == 0)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ret.cell_notdetected = true;
|
||||
}
|
||||
|
||||
/* Consider this is a false detection if the offset is > 1000 Hz
|
||||
/* Consider this is a false detection if the offset is > 1000 Hz
|
||||
Not to be used now that offest estimation is in place
|
||||
if( (abs(ue->common_vars.freq_offset) > 150) && (ret == 0) )
|
||||
{
|
||||
ret=-1;
|
||||
LOG_E(HW, "Ignore MIB with high freq offset [%d Hz] estimation \n",ue->common_vars.freq_offset);
|
||||
}*/
|
||||
if( (abs(ue->common_vars.freq_offset) > 150) && (ret == 0) )
|
||||
{
|
||||
ret=-1;
|
||||
LOG_E(HW, "Ignore MIB with high freq offset [%d Hz] estimation \n",ue->common_vars.freq_offset);
|
||||
}*/
|
||||
|
||||
if (ret==0) { // PBCH found so indicate sync to higher layers and configure frame parameters
|
||||
if (ret.cell_notdetected == 0) { // PBCH found so indicate sync to higher layers and configure frame parameters
|
||||
|
||||
//#ifdef DEBUG_INITIAL_SYNCH
|
||||
|
||||
LOG_I(PHY, "[UE%d] In synch, rx_offset %d samples\n",ue->Mod_id, ue->rx_offset);
|
||||
LOG_I(PHY, "[UE%d] In synch, rx_offset %d samples\n", ue->Mod_id, ret.rx_offset);
|
||||
|
||||
//#endif
|
||||
|
||||
if (ue->UE_scan_carrier == 0) {
|
||||
#if UE_AUTOTEST_TRACE
|
||||
LOG_I(PHY,
|
||||
"[UE %d] AUTOTEST Cell Sync : rx_offset %d, freq_offset %d \n",
|
||||
ue->Mod_id,
|
||||
ue->rx_offset,
|
||||
ue->common_vars.freq_offset);
|
||||
#endif
|
||||
|
||||
#if UE_AUTOTEST_TRACE
|
||||
LOG_I(PHY,"[UE %d] AUTOTEST Cell Sync : rx_offset %d, freq_offset %d \n",
|
||||
ue->Mod_id,
|
||||
ue->rx_offset,
|
||||
ue->common_vars.freq_offset );
|
||||
#endif
|
||||
|
||||
// send sync status to higher layers later when timing offset converge to target timing
|
||||
|
||||
// send sync status to higher layers later when timing offset converge to target timing
|
||||
}
|
||||
|
||||
LOG_I(PHY,
|
||||
@@ -428,23 +411,22 @@ int nr_initial_sync(const UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_fra
|
||||
LOG_I(PHY,"[UE%d] Initial sync : Estimated Nid_cell %d, Frame_type %d\n",ue->Mod_id,
|
||||
frame_parms->Nid_cell,frame_parms->frame_type);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
// gain control
|
||||
if (ret!=0) { //we are not synched, so we cannot use rssi measurement (which is based on channel estimates)
|
||||
rx_power = 0;
|
||||
if (ret.cell_notdetected != 0) { // we are not synched, so we cannot use rssi measurement (which is based on channel estimates)
|
||||
int rx_power = 0;
|
||||
|
||||
// do a measurement on the best guess of the PSS
|
||||
//for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++)
|
||||
// for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++)
|
||||
// rx_power += signal_energy(&ue->common_vars.rxdata[aarx][sync_pos2],
|
||||
// frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples);
|
||||
// frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples);
|
||||
|
||||
/*
|
||||
// do a measurement on the full frame
|
||||
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++)
|
||||
rx_power += signal_energy(&ue->common_vars.rxdata[aarx][0],
|
||||
frame_parms->samples_per_subframe*10);
|
||||
rx_power += signal_energy(&ue->common_vars.rxdata[aarx][0],
|
||||
frame_parms->samples_per_subframe*10);
|
||||
*/
|
||||
|
||||
// we might add a low-pass filter here later
|
||||
@@ -453,12 +435,10 @@ int nr_initial_sync(const UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_fra
|
||||
ue->measurements.rx_power_avg_dB[0] = dB_fixed(ue->measurements.rx_power_avg[0]);
|
||||
|
||||
#ifdef DEBUG_INITIAL_SYNCH
|
||||
LOG_I(PHY,"[UE%d] Initial sync : Estimated power: %d dB\n",ue->Mod_id,ue->measurements.rx_power_avg_dB[0] );
|
||||
LOG_I(PHY, "[UE%d] Initial sync : Estimated power: %d dB\n", ue->Mod_id, ue->measurements.rx_power_avg_dB[0]);
|
||||
#endif
|
||||
|
||||
}
|
||||
// exit_fun("debug exit");
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INITIAL_UE_SYNC, VCD_FUNCTION_OUT);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -287,6 +287,7 @@ int rx_sss(PHY_VARS_NR_UE *phy_vars_ue,int32_t *tot_metric,uint8_t *flip_max,uin
|
||||
/*! \brief receiver for the PBCH
|
||||
\returns number of tx antennas or -1 if error
|
||||
*/
|
||||
|
||||
int nr_rx_pbch(PHY_VARS_NR_UE *ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
const int estimateSz,
|
||||
@@ -297,11 +298,6 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue,
|
||||
fapiPbch_t *result,
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
|
||||
|
||||
int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
|
||||
PHY_VARS_NR_UE *ue,
|
||||
int pbch_initial_symbol,
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
|
||||
|
||||
#ifndef modOrder
|
||||
#define modOrder(I_MCS,I_TBS) ((I_MCS-I_TBS)*2+2) // Find modulation order from I_TBS and I_MCS
|
||||
#endif
|
||||
@@ -323,7 +319,11 @@ int dump_ue_stats(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
@param n_frames
|
||||
@param sa current running mode
|
||||
*/
|
||||
int nr_initial_sync(const UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *phy_vars_ue, int n_frames, int sa);
|
||||
typedef struct {
|
||||
bool cell_notdetected;
|
||||
int rx_offset;
|
||||
} nr_initial_sync_t;
|
||||
nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *phy_vars_ue, int n_frames, int sa);
|
||||
|
||||
/*!
|
||||
\brief This function gets the carrier frequencies either from FP or command-line-set global variables, depending on the
|
||||
|
||||
@@ -895,6 +895,8 @@ void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue,
|
||||
* n_id = N_ID_cell if higher layer parameter not configured
|
||||
*/
|
||||
uint8_t btilde[M_bit];
|
||||
memset(btilde, 0, sizeof(btilde));
|
||||
|
||||
// rnti is given by the C-RNTI
|
||||
uint16_t rnti=pucch_pdu->rnti, n_id=0;
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
@@ -912,6 +914,8 @@ void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue,
|
||||
*/
|
||||
// complex-valued symbol d(0)
|
||||
c16_t d[M_bit];
|
||||
memset(d, 0, sizeof(d));
|
||||
|
||||
uint16_t m_symbol = (M_bit%2==0) ? M_bit/2 : floor(M_bit/2)+1;
|
||||
const int16_t baseVal = (amp * ONE_OVER_SQRT2) >> 15;
|
||||
|
||||
@@ -962,6 +966,7 @@ void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue,
|
||||
// uint8_t nrofSymbols;
|
||||
// complex-valued symbol d(0)
|
||||
c16_t y_n[4 * M_bit]; // 4 is the maximum number n_SF_PUCCH_s, so is the maximunm size of y_n
|
||||
memset(y_n, 0, sizeof(y_n));
|
||||
// Re part orthogonal sequences w_n(k) for PUCCH format 4 when N_SF_PUCCH4 = 2 (Table 6.3.2.6.3-1)
|
||||
// k={0,..11} n={0,1,2,3}
|
||||
// parameter PUCCH-F4-preDFT-OCC-index set of {0,1,2,3} -> n
|
||||
@@ -1051,6 +1056,8 @@ void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue,
|
||||
* Implementing Transform pre-coding subclause 6.3.2.6.4
|
||||
*/
|
||||
c16_t z[4 * M_bit]; // 4 is the maximum number n_SF_PUCCH_s
|
||||
memset(z, 0 , sizeof(z));
|
||||
|
||||
#define M_PI 3.14159265358979323846 // pi
|
||||
const int64_t base = round(32767 / sqrt(12 * nrofPRB));
|
||||
for (int l=0; l<floor((n_SF_PUCCH_s*m_symbol)/(12*nrofPRB)); l++) {
|
||||
|
||||
@@ -267,6 +267,7 @@ static int do_pss_sss_extract_nr(
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) // add flag to indicate extracting only PSS, only SSS, or both
|
||||
{
|
||||
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||
AssertFatal(frame_parms->nb_antennas_rx > 0, "UB as sss_ext is not set to any value\n");
|
||||
|
||||
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
|
||||
int pss_symbol = 0;
|
||||
@@ -369,8 +370,8 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue,
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
|
||||
{
|
||||
uint8_t i;
|
||||
c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR];
|
||||
c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR];
|
||||
c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR] = {0};
|
||||
c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR] = {0};
|
||||
uint8_t Nid2 = GET_NID2(ue->common_vars.nid2);
|
||||
uint16_t Nid1;
|
||||
uint8_t phase;
|
||||
|
||||
@@ -614,8 +614,8 @@ static void pucchIQ (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
|
||||
static void puschThroughtput (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
|
||||
// PUSCH Throughput
|
||||
/*
|
||||
float tput_time_enb[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
|
||||
float tput_enb[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
|
||||
float tput_time_enb[MAX_MOBILES_PER_GNB][TPUT_WINDOW_LENGTH] = {{0}};
|
||||
float tput_enb[MAX_MOBILES_PER_GNB][TPUT_WINDOW_LENGTH] = {{0}};
|
||||
|
||||
memmove( tput_time_enb[UE_id], &tput_time_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
|
||||
memmove( tput_enb[UE_id], &tput_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
|
||||
@@ -725,7 +725,7 @@ static void *scope_thread_gNB(void *arg) {
|
||||
int fl_argc=1;
|
||||
char *name="5G-gNB-scope";
|
||||
fl_initialize (&fl_argc, &name, NULL, 0, 0);
|
||||
int nb_ue=min(NUMBER_OF_UE_MAX, scope_enb_num_ue);
|
||||
int nb_ue=min(MAX_MOBILES_PER_GNB, scope_enb_num_ue);
|
||||
OAI_phy_scope_t *form_gnb = create_phy_scope_gnb();
|
||||
|
||||
while (!oai_exit) {
|
||||
@@ -985,9 +985,9 @@ static void uePdschIQ (scopeGraphData_t **data, OAIgraph_t *graph, PHY_VARS_NR_
|
||||
}
|
||||
static void uePdschThroughput (scopeGraphData_t **data, OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
||||
/*
|
||||
float tput_time_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
|
||||
float tput_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
|
||||
float tput_ue_max[NUMBER_OF_UE_MAX] = {0};
|
||||
float tput_time_ue[MAX_MOBILES_PER_GNB][TPUT_WINDOW_LENGTH] = {{0}};
|
||||
float tput_ue[MAX_MOBILES_PER_GNB][TPUT_WINDOW_LENGTH] = {{0}};
|
||||
float tput_ue_max[MAX_MOBILES_PER_GNB] = {0};
|
||||
|
||||
|
||||
// PDSCH Throughput
|
||||
@@ -1178,7 +1178,7 @@ static void reset_stats_gNB(FL_OBJECT *button,
|
||||
int i,k;
|
||||
//PHY_VARS_gNB *phy_vars_gNB = RC.gNB[0][0];
|
||||
|
||||
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
|
||||
for (i=0; i<MAX_MOBILES_PER_GNB; i++) {
|
||||
for (k=0; k<8; k++) { //harq_processes
|
||||
/* for (j=0; j<phy_vars_gNB->dlsch[i][0]->Mlimit; j++) {
|
||||
phy_vars_gNB->UE_stats[i].dlsch_NAK[k][j]=0;
|
||||
|
||||
@@ -953,7 +953,7 @@ typedef enum {no_relay=1,unicast_relay_type1,unicast_relay_type2, multicast_rela
|
||||
|
||||
#define NB_BANDS_MAX 8
|
||||
|
||||
#include "common/utils/LOG/log_extern.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
extern pthread_cond_t sync_cond;
|
||||
extern pthread_mutex_t sync_mutex;
|
||||
extern int sync_var;
|
||||
|
||||
@@ -86,9 +86,6 @@
|
||||
#define openair_sched_exit() exit(-1)
|
||||
|
||||
#define bzero(s,n) (memset((s),0,(n)))
|
||||
#define cmax(a,b) ((a>b) ? (a) : (b))
|
||||
#define cmin(a,b) ((a<b) ? (a) : (b))
|
||||
#define cmax3(a,b,c) ((cmax(a,b)>c) ? (cmax(a,b)) : (c))
|
||||
/// suppress compiler warning for unused arguments
|
||||
#define UNUSED(x) (void)x;
|
||||
|
||||
@@ -485,12 +482,8 @@ typedef struct PHY_VARS_NR_UE_s {
|
||||
uint8_t init_sync_frame;
|
||||
/// temporary offset during cell search prior to MIB decoding
|
||||
int ssb_offset;
|
||||
uint16_t symbol_offset; /// offset in terms of symbols for detected ssb in sync
|
||||
int rx_offset; /// Timing offset
|
||||
int rx_offset_diff; /// Timing adjustment for ofdm symbol0 on HW USRP
|
||||
int64_t max_pos_fil; /// Timing offset IIR filter
|
||||
bool apply_timing_offset; /// Do time sync for current frame
|
||||
int time_sync_cell;
|
||||
uint16_t symbol_offset; /// offset in terms of symbols for detected ssb in sync
|
||||
int64_t max_pos_avg; /// Timing offset IIR filter
|
||||
|
||||
/// Timing Advance updates variables
|
||||
/// Timing advance update computed from the TA command signalled from gNB
|
||||
@@ -644,6 +637,7 @@ typedef struct nr_rxtx_thread_data_s {
|
||||
int writeBlockSize;
|
||||
nr_phy_data_t phy_data;
|
||||
int tx_wait_for_dlsch;
|
||||
int rx_offset;
|
||||
} nr_rxtx_thread_data_t;
|
||||
|
||||
typedef struct LDPCDecode_ue_s {
|
||||
|
||||
@@ -30,8 +30,6 @@
|
||||
|
||||
PHY_VARS_UE ***PHY_vars_UE_g;
|
||||
UL_RCC_IND_t UL_RCC_INFO;
|
||||
NR_UL_IND_t UL_INFO;
|
||||
|
||||
unsigned char NB_RU=0;
|
||||
int number_of_cards;
|
||||
uint8_t max_turbo_iterations=4;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "SCHED_NR/sched_nr.h"
|
||||
#include "nfapi_nr_interface.h"
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
|
||||
// added
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include "PHY/NR_TRANSPORT/nr_dci.h"
|
||||
#include "PHY/NR_ESTIMATION/nr_ul_estimation.h"
|
||||
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h"
|
||||
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h"
|
||||
#include "fapi_nr_l1.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
@@ -38,10 +37,7 @@
|
||||
#include "executables/nr-softmodem.h"
|
||||
#include "executables/softmodem-common.h"
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
#include "NR_SRS-ResourceSet.h"
|
||||
|
||||
#include "assertions.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
//#define DEBUG_RXDATA
|
||||
@@ -471,75 +467,13 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
|
||||
else if (SNRtimes10 > 635) cqi=255;
|
||||
else cqi=(640+SNRtimes10)/5;
|
||||
|
||||
|
||||
if (0/*pusch_pdu->mcs_index == 9*/) {
|
||||
__attribute__((unused))
|
||||
int off = ((pusch_pdu->rb_size&1) == 1)? 4:0;
|
||||
|
||||
LOG_M("rxsigF0.m",
|
||||
"rxsF0",
|
||||
&gNB->common_vars
|
||||
.rxdataF[0][(slot_rx % RU_RX_SLOT_DEPTH) * gNB->frame_parms.ofdm_symbol_size * gNB->frame_parms.symbols_per_slot],
|
||||
gNB->frame_parms.ofdm_symbol_size * gNB->frame_parms.symbols_per_slot,
|
||||
1,
|
||||
1);
|
||||
LOG_M("chestF0.m",
|
||||
"chF0",
|
||||
&gNB->pusch_vars[0].ul_ch_estimates[0][pusch_pdu->start_symbol_index * gNB->frame_parms.ofdm_symbol_size],
|
||||
gNB->frame_parms.ofdm_symbol_size,
|
||||
1,
|
||||
1);
|
||||
LOG_M("chestF0_ext.m",
|
||||
"chF0_ext",
|
||||
&gNB->pusch_vars[0]
|
||||
.ul_ch_estimates_ext[0][(pusch_pdu->start_symbol_index + 1) * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size))],
|
||||
(pusch_pdu->nr_of_symbols - 1) * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size)),
|
||||
1,
|
||||
1);
|
||||
LOG_M("rxsigF0_comp.m",
|
||||
"rxsF0_comp",
|
||||
&gNB->pusch_vars[0].rxdataF_comp[0][pusch_pdu->start_symbol_index * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size))],
|
||||
pusch_pdu->nr_of_symbols * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size)),
|
||||
1,
|
||||
1);
|
||||
LOG_M("rxsigF0_llr.m",
|
||||
"rxsF0_llr",
|
||||
&gNB->pusch_vars[0].llr[0],
|
||||
(pusch_pdu->nr_of_symbols - 1) * NR_NB_SC_PER_RB * pusch_pdu->rb_size * pusch_pdu->qam_mod_order,
|
||||
1,
|
||||
0);
|
||||
if (gNB->frame_parms.nb_antennas_rx > 1) {
|
||||
LOG_M(
|
||||
"rxsigF1.m",
|
||||
"rxsF1",
|
||||
&gNB->common_vars
|
||||
.rxdataF[1][(slot_rx % RU_RX_SLOT_DEPTH) * gNB->frame_parms.ofdm_symbol_size * gNB->frame_parms.symbols_per_slot],
|
||||
gNB->frame_parms.ofdm_symbol_size * gNB->frame_parms.symbols_per_slot,
|
||||
1,
|
||||
1);
|
||||
LOG_M("chestF1.m",
|
||||
"chF1",
|
||||
&gNB->pusch_vars[0].ul_ch_estimates[1][pusch_pdu->start_symbol_index * gNB->frame_parms.ofdm_symbol_size],
|
||||
gNB->frame_parms.ofdm_symbol_size,
|
||||
1,
|
||||
1);
|
||||
LOG_M("chestF1_ext.m",
|
||||
"chF1_ext",
|
||||
&gNB->pusch_vars[0]
|
||||
.ul_ch_estimates_ext[1][(pusch_pdu->start_symbol_index + 1) * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size))],
|
||||
(pusch_pdu->nr_of_symbols - 1) * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size)),
|
||||
1,
|
||||
1);
|
||||
LOG_M("rxsigF1_comp.m",
|
||||
"rxsF1_comp",
|
||||
&gNB->pusch_vars[0].rxdataF_comp[1][pusch_pdu->start_symbol_index * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size))],
|
||||
pusch_pdu->nr_of_symbols * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size)),
|
||||
1,
|
||||
1);
|
||||
}
|
||||
exit(-1);
|
||||
|
||||
}
|
||||
// multiple threads might call this function at the same time, or while the
|
||||
// L2 reads the messages. Hence, if not protected, crc and rx indications
|
||||
// might not appear pairwise (in the same order) in the same slot, or even in
|
||||
// separate slots. The L2 does not support this; hence, use the crc_rx_mutex
|
||||
// to ensure that messages are pairwise.
|
||||
int rc = pthread_mutex_lock(&gNB->UL_INFO.crc_rx_mutex);
|
||||
DevAssert(rc == 0);
|
||||
|
||||
// crc indication
|
||||
uint16_t num_crc = gNB->UL_INFO.crc_ind.number_crcs;
|
||||
@@ -577,8 +511,10 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
|
||||
gNB->rx_pdu_list[num_rx].pdu_length = harq_process->TBS;
|
||||
gNB->rx_pdu_list[num_rx].pdu = harq_process->b;
|
||||
}
|
||||
|
||||
gNB->UL_INFO.rx_ind.number_of_pdus++;
|
||||
|
||||
rc = pthread_mutex_unlock(&gNB->UL_INFO.crc_rx_mutex);
|
||||
DevAssert(rc == 0);
|
||||
}
|
||||
|
||||
// Function to fill UL RB mask to be used for N0 measurements
|
||||
@@ -1040,17 +976,17 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
||||
case 0:
|
||||
LOG_W(NR_PHY, "SRS report was not requested by MAC\n");
|
||||
return 0;
|
||||
case 1 << NR_SRS_ResourceSet__usage_beamManagement:
|
||||
srs_indication->srs_usage = NR_SRS_ResourceSet__usage_beamManagement;
|
||||
case 1 << NFAPI_NR_SRS_BEAMMANAGEMENT:
|
||||
srs_indication->srs_usage = NFAPI_NR_SRS_BEAMMANAGEMENT;
|
||||
break;
|
||||
case 1 << NR_SRS_ResourceSet__usage_codebook:
|
||||
srs_indication->srs_usage = NR_SRS_ResourceSet__usage_codebook;
|
||||
case 1 << NFAPI_NR_SRS_CODEBOOK:
|
||||
srs_indication->srs_usage = NFAPI_NR_SRS_CODEBOOK;
|
||||
break;
|
||||
case 1 << NR_SRS_ResourceSet__usage_nonCodebook:
|
||||
srs_indication->srs_usage = NR_SRS_ResourceSet__usage_nonCodebook;
|
||||
case 1 << NFAPI_NR_SRS_NONCODEBOOK:
|
||||
srs_indication->srs_usage = NFAPI_NR_SRS_NONCODEBOOK;
|
||||
break;
|
||||
case 1 << NR_SRS_ResourceSet__usage_antennaSwitching:
|
||||
srs_indication->srs_usage = NR_SRS_ResourceSet__usage_antennaSwitching;
|
||||
case 1 << NFAPI_NR_SRS_ANTENNASWITCH:
|
||||
srs_indication->srs_usage = NFAPI_NR_SRS_ANTENNASWITCH;
|
||||
break;
|
||||
default:
|
||||
LOG_E(NR_PHY, "Invalid srs_pdu->srs_parameters_v4.usage %i\n", srs_pdu->srs_parameters_v4.usage);
|
||||
@@ -1073,7 +1009,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
||||
|
||||
start_meas(&gNB->srs_report_tlv_stats);
|
||||
switch (srs_indication->srs_usage) {
|
||||
case NR_SRS_ResourceSet__usage_beamManagement: {
|
||||
case NFAPI_NR_SRS_BEAMMANAGEMENT: {
|
||||
start_meas(&gNB->srs_beam_report_stats);
|
||||
nfapi_nr_srs_beamforming_report_t nr_srs_bf_report;
|
||||
nr_srs_bf_report.prg_size = srs_pdu->beamforming.prg_size;
|
||||
@@ -1102,7 +1038,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
||||
break;
|
||||
}
|
||||
|
||||
case NR_SRS_ResourceSet__usage_codebook: {
|
||||
case NFAPI_NR_SRS_CODEBOOK: {
|
||||
start_meas(&gNB->srs_iq_matrix_stats);
|
||||
nfapi_nr_srs_normalized_channel_iq_matrix_t nr_srs_channel_iq_matrix;
|
||||
nr_srs_channel_iq_matrix.normalized_iq_representation = srs_pdu->srs_parameters_v4.iq_representation;
|
||||
@@ -1151,8 +1087,8 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
||||
break;
|
||||
}
|
||||
|
||||
case NR_SRS_ResourceSet__usage_nonCodebook:
|
||||
case NR_SRS_ResourceSet__usage_antennaSwitching:
|
||||
case NFAPI_NR_SRS_NONCODEBOOK:
|
||||
case NFAPI_NR_SRS_ANTENNASWITCH:
|
||||
LOG_W(NR_PHY, "PHY procedures for this SRS usage are not implemented yet!\n");
|
||||
break;
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ typedef struct {
|
||||
*/
|
||||
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data);
|
||||
|
||||
void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data);
|
||||
int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data);
|
||||
|
||||
void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data);
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include "executables/nr-uesoftmodem.h"
|
||||
#include "SCHED_NR_UE/pucch_uci_ue_nr.h"
|
||||
#include <openair1/PHY/TOOLS/phy_scope_interface.h>
|
||||
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h"
|
||||
|
||||
//#define DEBUG_PHY_PROC
|
||||
//#define NR_PDCCH_SCHED_DEBUG
|
||||
@@ -826,7 +827,7 @@ static bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *
|
||||
return dec;
|
||||
}
|
||||
|
||||
void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data)
|
||||
int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data)
|
||||
{
|
||||
int frame_rx = proc->frame_rx;
|
||||
int nr_slot_rx = proc->nr_slot_rx;
|
||||
@@ -834,6 +835,7 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr
|
||||
fapi_nr_config_request_t *cfg = &ue->nrUE_config;
|
||||
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
|
||||
NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config;
|
||||
int sampleShift = 0;
|
||||
nr_ue_dlsch_init(phy_data->dlsch, NR_MAX_NB_LAYERS>4 ? 2:1, ue->max_ldpc_iterations);
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
|
||||
@@ -896,17 +898,9 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr
|
||||
|
||||
if (ue->no_timing_correction==0 && pbchSuccess == 0) {
|
||||
LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction);
|
||||
nr_adjust_synch_ue(fp,
|
||||
ue,
|
||||
gNB_id,
|
||||
fp->ofdm_symbol_size,
|
||||
dl_ch_estimates_time,
|
||||
frame_rx,
|
||||
nr_slot_rx,
|
||||
0,
|
||||
16384);
|
||||
sampleShift =
|
||||
nr_adjust_synch_ue(fp, ue, gNB_id, fp->ofdm_symbol_size, dl_ch_estimates_time, frame_rx, nr_slot_rx, 16384);
|
||||
}
|
||||
ue->apply_timing_offset = true;
|
||||
}
|
||||
LOG_D(PHY, "Doing N0 measurements in %s\n", __FUNCTION__);
|
||||
nr_ue_rrc_measurements(ue, proc, rxdataF);
|
||||
@@ -996,6 +990,7 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr
|
||||
LOG_D(PHY,"[UE %d] Frame %d, nr_slot_rx %d: found %d DCIs\n", ue->Mod_id, frame_rx, nr_slot_rx, dci_cnt);
|
||||
phy_pdcch_config->nb_search_space = 0;
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_OUT);
|
||||
return sampleShift;
|
||||
}
|
||||
|
||||
void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user