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:
Robert Schmidt
2024-03-11 16:57:07 +00:00
151 changed files with 6436 additions and 2055 deletions
+2 -1
View File
@@ -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
+23
View File
@@ -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 {
+53
View File
@@ -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
+22 -15
View File
@@ -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
View File
@@ -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
+6 -2
View File
@@ -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
+2 -1
View File
@@ -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)
-2
View File
@@ -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
View File
@@ -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
View File
@@ -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;
/** @}*/
-31
View File
@@ -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];
-34
View File
@@ -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"
-4
View File
@@ -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
+78 -64
View File
@@ -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
View File
@@ -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
+266
View File
@@ -0,0 +1,266 @@
<table style="border-collapse: collapse; border: none;">
<tr style="border-collapse: collapse; border: none;">
<td style="border-collapse: collapse; border: none;">
<a href="http://www.openairinterface.org/">
<img src="./images/oai_final_logo.png" alt="" border=3 height=50 width=150>
</img>
</a>
</td>
<td style="border-collapse: collapse; border: none; vertical-align: center;">
<b><font size = "5">OAI 7.2 Fronthaul Interface 5G SA Tutorial</font></b>
</td>
</tr>
</table>
**Table of Contents**
[[_TOC_]]
# Prerequisites
The hardware on which we have tried this tutorial:
| Hardware (CPU,RAM) |Operating System (kernel) | NIC (Vendor,Driver,Firmware) |
|----------------------------------------------------------------------------|----------------------------------|--------------------------------------------------|
| Gigabyte Edge E251-U70 (Intel Xeon Gold 6240R, 2.4GHz, 24C48T, 96GB DDR4) |Ubuntu 22.04.3 LTS (5.15.0-72-lowlatency)| NVIDIA ConnectX®-6 Dx 22.38.1002 |
| Dell PowerEdge R750 (Dual Intel Xeon Gold 6336Y CPU @ 2.4G, 24C/48T (185W), 512GB RDIMM, 3200MT/s) |Ubuntu 22.04.3 LTS (5.15.0-72-lowlatency)| NVIDIA Converged Accelerator A100X (24.39.2048) |
**NOTE**: These are not minimum hardware requirements. This is the configuration of our servers. The NIC card should support hardware PTP time stamping.
PTP enabled switches and grandmaster clock we have tested with:
| Vendor | Software Version |
|--------------------------|------------------|
| Fibrolan Falcon-RX/812/G | 8.0.25.4 |
| CISCO C93180YC-FX3 | 10.2(4) |
| Qulsar Qg2 (Grandmaster) | 12.1.27 |
These are the radio units we've used for testing:
| Vendor | Software Version |
|-------------|------------------|
| Foxconn RPQN-7801E RU | 2.6.9r254 |
| Foxconn RPQN-7801E RU | 3.1.15_0p4 |
The UEs that have been tested and confirmed working with Aerial are the following:
| Vendor | Model |
|-----------------|-------------------------------|
| Sierra Wireless | EM9191 |
| Quectel | RM500Q-GL |
| Apaltec | Tributo 5G-Dongle |
| OnePlus | Nord (AC2003) |
| Apple iPhone | 14 Pro (MQ0G3RX/A) (iOS 17.3) |
## Configure your server
The first step is to obtain the NVIDIA Aerial SDK, you'll need to request access [here](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/aerial-sdk).
After obtaining access to the SDK, you can refer to [this instructions page](https://docs.nvidia.com/aerial/aerial-research-cloud/current/index.html) to setup the L1 components using NVIDIAs' SDK manager, or to [this instructions page](https://developer.nvidia.com/docs/gputelecom/aerial-sdk/aerial-sdk-archive/aerial-sdk-23-2/index.html) in order to setup and install the components manually.
The currently used Aerial Version is 23-2, which is also the one currently used by the SDK Manager.
### CPU allocation
Currently, the CPU isolation is setup the following:
| Server brand | Model | Nº of CPU Cores | Isolated CPUs |
|--------------|-----------|:---------------:|:--------------:|
| Gigabyte | Edge E251-U70 | 24 | 2-10 |
**Gigabyte Edge E251-U70**
| Applicative Threads | Allocated CPUs |
|------------------------|----------------|
| Aerial L1 | 2,3,4,5,6,7,8 |
| PTP & PHC2SYS Services | 9 |
| OAI `nr-softmodem` | 13-20 |
## PTP configuration
1. You need to install the `linuxptp` debian package. It will install both ptp4l and phc2sys.
```bash
#Ubuntu
sudo apt install linuxptp -y
```
Once installed you can use this configuration file for ptp4l (`/etc/ptp4l.conf`). Here the clock domain is 24 so you can adjust it according to your PTP GM clock domain
```
[global]
domainNumber 24
slaveOnly 1
time_stamping hardware
tx_timestamp_timeout 1
logging_level 6
summary_interval 0
#priority1 127
[your_PTP_ENABLED_NIC]
network_transport L2
hybrid_e2e 0
```
The service of ptp4l (`/lib/systemd/system/ptp4l.service`) should be configured as below:
```
[Unit]
Description=Precision Time Protocol (PTP) service
Documentation=man:ptp4l
[Service]
Restart=always
RestartSec=5s
Type=simple
ExecStart=taskset -c 9 /usr/sbin/ptp4l -f /etc/ptp.conf
[Install]
WantedBy=multi-user.target
```
and service of phc2sys (`/lib/systemd/system/phc2sys.service`) should be configured as below:
```
[Unit]
Description=Synchronize system clock or PTP hardware clock (PHC)
Documentation=man:phc2sys
After=ntpdate.service
Requires=ptp4l.service
After=ptp4l.service
[Service]
Restart=always
RestartSec=5s
Type=simple
ExecStart=/usr/sbin/phc2sys -a -r -r -n 24
[Install]
WantedBy=multi-user.target
```
# Build OAI gNB
If installing with the Aerial SDK, you should already have the repository cloned in `~/openairinterface5g`, if
Clone OAI code base in a suitable repository, here we are cloning in `~/openairinterface5g` directory,
```bash
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git ~/openairinterface5g
cd ~/openairinterface5g/
git checkout Aerial_Integration
```
## Get nvIPC sources from the L1 container
The library used for communication between L1 and L2 components is called nvIPC, and was developed by NVIDIA, as such, it is not open-source and can't be freely distributed.
In order to be able to use this library to achieve communication, we need to obtain the nvIPC source files from the L1 container (cuBB) and place it in out gNB project directory `~/openairinterface5g`.
This allows us to build and install this library when building the L2 docker container.
Check whether your L1 container is running:
```bash
~$ docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a9681a0c4a10 14dca2002237 "/opt/nvidia/nvidia_…" 3 months ago Exited (137) 10 days ago cuBB
```
If it is not running, you may start it and logging into the container by running the following:
```bash
~$ docker start cuBB
cuBB
~$ docker exec -it cuBB bash
root@c_aerial_aerial:/opt/nvidia/cuBB#
```
After logging into the container, we need to pack the nvIPC sources and copy them to the host ( the command creates a tar.gz file with the following name format: nvipc_src.yyyy.mm.dd.tar.gz)
```bash
~$ docker exec -it cuBB bash
root@c_aerial_aerial:/opt/nvidia/cuBB# cd cuPHY-CP/gt_common_libs
root@c_aerial_aerial:/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs#./pack_nvipc.sh
nvipc_src.****.**.**/
...
---------------------------------------------
Pack nvipc source code finished:
/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs/nvipc_src.****.**.**.tar.gz
root@c_aerial_aerial:/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs# cp nvipc_src.****.**.**.tar.gz /opt/cuBB/share/
root@c_aerial_aerial:/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs# exit
```
The file should now be present in the `~/openairinterface5g/ci-scripts/yaml_files/sa_gnb_aerial/` directory, from where it is moved into `~/openairinterface5g`
```bash
~$ mv ~/openairinterface5g/ci-scripts/yaml_files/sa_gnb_aerial/nvipc_src.****.**.**.tar.gz ~/openairinterface5g/
```
With the nvIPC sources in the project directory, the docker image can be built.
## Building OAI gNB docker image
In order to build the final image, there is an intermediary image to be built (ran-base)
```bash
~$ cd ~/openairinterface5g/
~/openairinterface5g$ docker build . -f docker/Dockerfile.base.ubuntu20 --tag ran-base:latest
~/openairinterface5g$ docker build . -f docker/Dockerfile.gNB.aerial.ubuntu20 --tag oai-gnb-aerial:latest
```
## Running the setup
In order to use Docker compose to automatically start and stop the setup, we need to first create a ready-made image of the L1, after compiling the L1 software and making the necessary adjustments to its configuration files.
The process of preparing the L1 is covered on NVIDIAs' documentation, and falls outside the scope of this document.
### Prepare the L1 image
After preparing the L1 software, the container needs to be committed in order for an image in which the L1 is ready to be executed, and that can be referenced by a docker-compose.yaml file later:
```bash
~$ docker commit nv-cubb cubb-build:23-2
~$ docker image ls
..
cubb-build 23-2 824156e0334c 2 weeks ago 40.1GB
..
```
## Adapt the OAI-gNB configuration file to your system/workspace
Edit the sample OAI gNB configuration file and check following parameters:
* `gNBs` section
* The PLMN section shall match the one defined in the AMF
* `amf_ip_address` shall be the correct AMF IP address in your system
* `GNB_INTERFACE_NAME_FOR_NG_AMF` and `GNB_IPV4_ADDRESS_FOR_NG_AMF` shall match your DU N2 interface name and IP address
* `GNB_INTERFACE_NAME_FOR_NGU` and `GNB_IPV4_ADDRESS_FOR_NGU` shall match your DU N3 interface name and IP address
The default amf_ip_address:ipv4 value is 192.168.70.132, when installing the CN5G following [this tutorial](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop/doc/NR_SA_Tutorial_OAI_CN5G.md)
Both 'GNB_INTERFACE_NAME_FOR_NG_AMF' and 'GNB_INTERFACE_NAME_FOR_NGU' need to be set to the network interface name used by the gNB host to connect to the CN5G.
Both 'GNB_IPV4_ADDRESS_FOR_NG_AMF' and 'GNB_IPV4_ADDRESS_FOR_NGU' need to be set to the IP address of the NIC referenced previously.
### Running docker compose
#### Aerial L1 entrypoint script
Before running docker-compose, we can check which L1 configuration file is to be used by cuphycontroller_scf, this is set in the script [`aerial_l1_entrypoint.sh`](../ci-scripts/yaml_files/sa_gnb_aerial/aerial_l1_entrypoint.sh), which is used by the L1 container in order to start the L1 software, this begins by installing a module 'gdrcopy', setting up some environment variables, restarting NVIDIA MPS, and finally running cuphycontroller with an argument that represent which L1 configuration file is to be used, this argument may be changed by providing an argument in docker-compose.yaml.
When no argument is provided (this is the default behaviour), it uses "P5G_SCF_FXN" as a cuphycontroller_scf argument.
After building the gNB image, and preparing the configuration file, the setup can be run with the following command:
```bash
cd ci-scripts/yaml_files/sa_gnb_aerial/
docker compose up -d
```
This will start both containers, beginning with 'nv-cubb' and only after it being ready it starts 'oai-gnb-aerial'.
The gNB logs can be followed with:
```bash
docker logs -f oai-gnb-aerial
```
### Stopping the setup
Running the following command, will stop both containers, leaving the system ready to be run later:
```bash
cd ci-scripts/yaml_files/sa_gnb_aerial/
docker compose down
```
-1
View File
@@ -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 \
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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
```
+103
View File
@@ -0,0 +1,103 @@
#/*
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
# * contributor license agreements. See the NOTICE file distributed with
# * this work for additional information regarding copyright ownership.
# * The OpenAirInterface Software Alliance licenses this file to You under
# * the OAI Public License, Version 1.1 (the "License"); you may not use this file
# * except in compliance with the License.
# * You may obtain a copy of the License at
# *
# * http://www.openairinterface.org/?page_id=698
# *
# * Unless required by applicable law or agreed to in writing, software
# * distributed under the License is distributed on an "AS IS" BASIS,
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# * See the License for the specific language governing permissions and
# * limitations under the License.
# *-------------------------------------------------------------------------------
# * For more information about the OpenAirInterface (OAI) Software Alliance:
# * contact@openairinterface.org
# */
#---------------------------------------------------------------------
#
# Dockerfile for the Open-Air-Interface BUILD service
# Valid for Ubuntu 22.04
#
#---------------------------------------------------------------------
FROM ran-base:latest as ran-build
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
DEBIAN_FRONTEND=noninteractive apt-get install --yes \
wget \
ninja-build \
#unzip is needed for protobuf
unzip \
moreutils \
vim-tiny \
nano \
# To build libnvipc
cmake libpcap-dev libcunit1-dev libnuma-dev pkg-config
RUN rm -Rf /oai-ran
WORKDIR /oai-ran
COPY . .
RUN /bin/sh oaienv && \
tar -xvzf nvipc_src.*.tar.gz && \
cd nvipc_src.* && \
git init && \
git apply ../cmake_targets/tools/install_libraries_to_system.patch --verbose && \
rm -rf build && mkdir build && cd build && \
cmake .. -DNVIPC_DPDK_ENABLE=OFF -DNVIPC_DOCA_ENABLE=OFF -DNVIPC_CUDA_ENABLE=OFF -DENABLE_SLT_RSP=ON && \
make -j && make install
RUN /bin/sh oaienv && \
cd cmake_targets && \
mkdir -p log && \
./build_oai -w AERIAL --gNB --ninja
#start from scratch for target executable
FROM ubuntu:focal as oai-gnb-aerial
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Europe
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
DEBIAN_FRONTEND=noninteractive apt-get install --yes \
software-properties-common \
procps \
libsctp1 \
tzdata \
libatlas3-base \
libconfig9 \
openssl \
net-tools \
iperf \
iproute2 \
iputils-ping \
gdb \
libusb-1.0-0 && \
rm -rf /var/lib/apt/lists/*
WORKDIR /opt/oai-gnb/bin
COPY --from=ran-build \
/oai-ran/cmake_targets/ran_build/build/nr-softmodem ./
COPY ./docker/scripts/gnb_entrypoint.sh ./entrypoint.sh
COPY --from=ran-build /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so /usr/local/lib/
#copy files from nvIPC
COPY --from=ran-build \
/usr/local/lib/libfmtlog-shared.so \
/usr/local/lib/libnvlog.so \
/usr/local/lib/libnvipc.so \
/usr/local/lib/
WORKDIR /opt/oai-gnb
COPY --from=ran-build /tini /tini
ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"]
CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"]
@@ -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"]
+56
View File
@@ -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"
+3 -2
View File
@@ -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) {
+3 -5
View File
@@ -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++) {
+3 -3
View File
@@ -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 */
+3 -2
View File
@@ -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;
+6 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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, &timestamp, true);
trashed_frames+=2;
readFrame(UE, &sync_timestamp, true);
trashed_frames += 2;
}
} else {
readFrame(UE, &timestamp, 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, &timestamp, 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, &timestamp);
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,
&timestamp,
(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,
&timestamp,
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
+4 -7
View File
@@ -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) {
+2 -4
View File
@@ -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) {
+4 -4
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
#!/bin/sh
echo "building ctags for openair1 and openair2 ..."
ctags -e -R --exclude=openair1/DOCS/ --exclude=openair2/DOCS/ --exclude=openair1/SIMULATION/ --exclude=targets/DOCS/ --exclude=targets/PROJECTS/ openair1 openair2 openair3 targets cmake_targets common nfapi executables radio
ctags -e -R --exclude=openair1/DOCS/ --exclude=openair2/DOCS/ --exclude=openair1/SIMULATION/ --exclude=targets/DOCS/ --exclude=targets/PROJECTS/ openair1 openair2 openair3 targets cmake_targets common fapi nfapi executables radio
+1
View File
@@ -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()
+683
View File
@@ -0,0 +1,683 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file fapi/oai-integration/fapi_nvIPC.c
* \brief OAI MAC/Aerial L1 interface file using FAPI over shared memory
* \author Ruben S. Silva
* \date 2023
* \version 0.1
* \company OpenAirInterface Software Alliance
* \email: contact@openairinterface.org, rsilva@allbesmart.pt
* \note
* \warning
*/
#ifdef ENABLE_AERIAL
#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stdarg.h>
#include <errno.h>
#include <unistd.h>
#include <termios.h>
#include <stdatomic.h>
#include <sys/queue.h>
#include <sys/epoll.h>
#include "fapi_nvIPC.h"
#include "nfapi_interface.h"
#include "nfapi.h"
#include "nfapi_nr_interface_scf.h"
#include "nfapi/open-nFAPI/vnf/inc/vnf_p7.h"
#include "fapi_vnf_p5.h"
#include "fapi_vnf_p7.h"
#define MAX_EVENTS 10
#define RECV_BUF_LEN 8192
char cpu_buf_recv[RECV_BUF_LEN];
uint16_t sfn = 0, slot = 0;
nv_ipc_t *ipc;
nfapi_vnf_config_t *vnf_config = 0;
void set_config(nfapi_vnf_config_t *conf)
{
vnf_config = conf;
}
static uint16_t old_sfn = 0;
static uint16_t old_slot = 0;
////////////////////////////////////////////////////////////////////////
// Handle an RX message
static int ipc_handle_rx_msg(nv_ipc_t *ipc, nv_ipc_msg_t *msg)
{
if (msg == NULL) {
LOG_E(NFAPI_VNF, "%s: ERROR: buffer is empty\n", __func__);
return -1;
}
char *p_cpu_data = NULL;
if (msg->data_buf != NULL) {
int gpu;
if (msg->data_pool == NV_IPC_MEMPOOL_CUDA_DATA) {
gpu = 1;
} else {
gpu = 0;
}
#ifdef NVIPC_CUDA_ENABLE
// Test CUDA: call CUDA functions to change all string to lower case
test_cuda_to_lower_case(test_cuda_device_id, msg->data_buf, TEST_DATA_BUF_LEN, gpu);
#endif
if (gpu) {
p_cpu_data = cpu_buf_recv;
memset(cpu_buf_recv, 0, RECV_BUF_LEN);
ipc->cuda_memcpy_to_host(ipc, p_cpu_data, msg->data_buf, RECV_BUF_LEN);
} else {
p_cpu_data = msg->data_buf;
}
}
int messageBufLen = msg->msg_len;
int dataBufLen = msg->data_len;
uint8_t msgbuf[messageBufLen];
uint8_t databuf[dataBufLen];
memcpy(msgbuf, msg->msg_buf, messageBufLen);
memcpy(databuf, msg->data_buf, dataBufLen);
uint8_t *pReadPackedMessage = msgbuf;
uint8_t *pReadData = databuf;
uint8_t *end = msgbuf + messageBufLen;
uint8_t *data_end = databuf + dataBufLen;
// unpack FAPI messages and handle them
if (vnf_config != 0) {
// first, unpack the header
fapi_phy_api_msg *fapi_msg = calloc(1, sizeof(fapi_phy_api_msg));
if (!(pull8(&pReadPackedMessage, &fapi_msg->num_msg, end) && pull8(&pReadPackedMessage, &fapi_msg->opaque_handle, end)
&& pull16(&pReadPackedMessage, &fapi_msg->message_id, end)
&& pull32(&pReadPackedMessage, &fapi_msg->message_length, end))) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "FAPI message header unpack failed\n");
return -1;
}
switch (fapi_msg->message_id) {
case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
if (vnf_config->nr_param_resp) {
nfapi_nr_param_response_scf_t msg_param_resp;
aerial_unpack_nr_param_response(&pReadPackedMessage, end, &msg_param_resp, &vnf_config->codec_config);
(vnf_config->nr_param_resp)(vnf_config, vnf_config->pnf_list->p5_idx, &msg_param_resp);
}
break;
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE: {
// unpack message
nfapi_nr_config_response_scf_t msg_config_response;
aerial_unpack_nr_config_response(&pReadPackedMessage, end, &msg_config_response, &vnf_config->codec_config);
// Check the error code
if (msg_config_response.error_code == NFAPI_NR_CONFIG_MSG_OK) {
// Invoke the call back
if (vnf_config->nr_config_resp) {
(vnf_config->nr_config_resp)(vnf_config, vnf_config->pnf_list->p5_idx, &msg_config_response);
}
} else {
// Error code not OK (MSG_INVALID_CONFIG)
/* MSG_INVALID_CONFIG.response structure
* Error code uint8_t
* Number of invalid or unsupported TLVs uint8_t
* Number of invalid TLVs that can only be configured in IDLE state uint8_t
* Number of invalid TLVs that can only be configured in RUNNING state uint8_t
* Number of missing TLVs uint8_t
* List of invalid or unsupported TLVs
* List of invalid TLVs that can only be configured in IDLE state
* List of invalid TLVs that can only be configured in RUNNING state
* List of missing TLVs
* */
}
break;
}
case NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION: {
// TODO : ADD Support for NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION (0x06)
LOG_D(NFAPI_VNF,"Received NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION\n");
break;
}
case NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION: {
// TODO: Add Support for NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION (0x07)
LOG_D(NFAPI_VNF,"Received NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION\n");
//for (int i = 0; i < msg->msg_len; i++) {
// printf(" msg->msg_buf[%d] = 0x%02x\n", i, ((uint8_t *) msg->msg_buf)[i]);
//}
LOG_D(NFAPI_VNF,"old sfn %u\n", old_sfn);
LOG_D(NFAPI_VNF,"old slot %u\n", old_slot);
break;
}
// P7 Messages
// P7 Message Handlers -> ((vnf_info *)vnf_config->user_data)->p7_vnfs->config->
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION: {
nfapi_nr_slot_indication_scf_t ind;
aerial_unpack_nr_slot_indication(&pReadPackedMessage,
end,
&ind,
&((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config);
// check if the sfn/slot unpacked come wrong at any time, should be old + 1 (slot 0 -- 19, sfn 0 -- 1023)
// add 1 to current sfn number
uint16_t old_slot_plus = ((old_slot + 1) % 20);
uint16_t old_sfn_plus = old_slot_plus == 0 ? ((old_sfn + 1) % 1024) : old_sfn;
if (old_slot_plus != ind.slot || old_sfn_plus != ind.sfn) {
LOG_E(NFAPI_VNF,
"\n============================================================================\n"
"sfn slot doesn't match unpacked one! L2->L1 %d.%d vs L1->L2 %d.%d \n"
"============================================================================\n",
old_sfn,
old_slot,
ind.sfn,
ind.slot);
}
old_sfn = ind.sfn;
old_slot = ind.slot;
if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_slot_indication) {
(((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_slot_indication)(&ind);
}
break;
}
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION: {
nfapi_nr_rx_data_indication_t ind;
ind.header.message_id = fapi_msg->message_id;
ind.header.message_length = fapi_msg->message_length;
aerial_unpack_nr_rx_data_indication(
&pReadPackedMessage,
end,
&pReadData,
data_end,
&ind,
&((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config);
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s: Handling RX Indication\n", __FUNCTION__);
if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_rx_data_indication) {
(((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_rx_data_indication)(&ind);
}
break;
}
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION: {
nfapi_nr_crc_indication_t crc_ind;
crc_ind.header.message_id = fapi_msg->message_id;
crc_ind.header.message_length = fapi_msg->message_length;
aerial_unpack_nr_crc_indication(&pReadPackedMessage,
end,
&crc_ind,
&((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config);
if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_crc_indication) {
(((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_crc_indication)(&crc_ind);
}
break;
}
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION: {
nfapi_nr_uci_indication_t ind;
aerial_unpack_nr_uci_indication(&pReadPackedMessage,
end,
&ind,
&((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config);
if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_uci_indication) {
(((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_uci_indication)(&ind);
}
break;
}
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION: {
nfapi_nr_srs_indication_t ind;
aerial_unpack_nr_srs_indication(&pReadPackedMessage,
end,
&ind,
&((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config);
if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_srs_indication) {
(((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_srs_indication)(&ind);
}
break;
}
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION: {
nfapi_nr_rach_indication_t ind;
aerial_unpack_nr_rach_indication(&pReadPackedMessage,
end,
&ind,
&((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config);
if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_rach_indication) {
(((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_rach_indication)(&ind);
}
break;
}
default: {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s P5 Unknown message ID %d\n", __FUNCTION__, fapi_msg->message_id);
break;
}
}
}
return 0;
}
int8_t buf[1024];
nv_ipc_config_t nv_ipc_config;
int aerial_send_P5_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p4_p5_message_header_t *header)
{
if (ipc == NULL) {
return -1;
}
nv_ipc_msg_t send_msg = {0};
// look for the specific message
switch (header->message_id) {
case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE:
case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE:
case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE:
break;
default: {
if (header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
// if(config && config->pack_p4_p5_vendor_extension) {
// result = (config->pack_p4_p5_vendor_extension)(header, ppWritePackedMsg, end, config);
// } else {
// NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve ecoder provided\n", __FUNCTION__, header->message_id);
// }
} else {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id);
}
} break;
}
send_msg.msg_id = header->message_id;
send_msg.cell_id = 0;
send_msg.msg_len = packedMsgLength + 8; // adding 8 to account for the size of the FAPI header
send_msg.data_len = 0;
send_msg.data_buf = NULL;
send_msg.data_pool = NV_IPC_MEMPOOL_CPU_MSG;
// procedure is allocate->fill->send
int alloc_retval = ipc->tx_allocate(ipc, &send_msg, 0);
if (alloc_retval != 0) {
LOG_E(NFAPI_VNF, "%s error: allocate TX buffer failed Error: %d\n", __FUNCTION__, alloc_retval);
ipc->tx_release(ipc, &send_msg);
return alloc_retval;
}
memcpy(send_msg.msg_buf, packedBuf, send_msg.msg_len);
LOG_D(NFAPI_VNF,
"send: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n",
send_msg.cell_id,
send_msg.msg_id,
send_msg.msg_len,
send_msg.data_len,
send_msg.data_pool);
// Send the message
int send_retval = ipc->tx_send_msg(ipc, &send_msg);
if (send_retval < 0) {
LOG_E(NFAPI_VNF, "%s error: send TX message failed Error: %d\n", __FUNCTION__, send_retval);
ipc->tx_release(ipc, &send_msg);
return send_retval;
}
ipc->notify(ipc, 1); // notify that there's 1 message in queue
return 0;
}
int aerial_send_P7_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p7_message_header_t *header)
{
if (ipc == NULL) {
return -1;
}
nv_ipc_msg_t send_msg;
uint8_t *pPacketBodyField = &((uint8_t *)packedBuf)[8];
uint8_t *pPackMessageEnd = packedBuf + packedMsgLength + 8;
uint16_t present_sfn = 0;
uint16_t present_slot = 0;
pull16(&pPacketBodyField, &present_sfn, pPackMessageEnd);
pull16(&pPacketBodyField, &present_slot, pPackMessageEnd);
if (present_sfn != old_sfn || present_slot != old_slot) {
LOG_E(NFAPI_VNF,
"\n============================================================================\n"
"sfn slot doesn't match unpacked one! L2->L1 %d.%d vs L1->L2 %d.%d \n"
"============================================================================\n",
present_sfn,
present_slot,
old_sfn,
old_slot);
}
// look for the specific message
switch (header->message_id) {
case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
case NFAPI_UE_RELEASE_REQUEST:
case NFAPI_UE_RELEASE_RESPONSE:
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
case NFAPI_TIMING_INFO:
case 0x8f:
break;
default: {
if (header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
} else {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id);
}
} break;
}
send_msg.msg_id = header->message_id;
send_msg.cell_id = 0;
send_msg.msg_len = packedMsgLength + 8; // adding 8 to account for the size of the FAPI header
send_msg.data_len = 0;
send_msg.data_buf = NULL;
send_msg.data_pool = NV_IPC_MEMPOOL_CPU_MSG;
// procedure is allocate->fill->send
// Allocate buffer for TX message
int alloc_retval = ipc->tx_allocate(ipc, &send_msg, 0);
if (alloc_retval != 0) {
LOG_E(NFAPI_VNF, "%s error: allocate TX buffer failed Error: %d\n", __FUNCTION__, alloc_retval);
ipc->tx_release(ipc, &send_msg);
return alloc_retval;
}
memcpy(send_msg.msg_buf, packedBuf, send_msg.msg_len);
LOG_D(NFAPI_VNF,
"send: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n",
send_msg.cell_id,
send_msg.msg_id,
send_msg.msg_len,
send_msg.data_len,
send_msg.data_pool);
// Send the message
int send_retval = ipc->tx_send_msg(ipc, &send_msg);
if (send_retval < 0) {
LOG_E(NFAPI_VNF, "%s error: send TX message failed Error: %d\n", __FUNCTION__, send_retval);
ipc->tx_release(ipc, &send_msg);
return send_retval;
}
ipc->notify(ipc, 1); // notify that there's 1 message in queue
return 0;
}
int aerial_send_P7_msg_with_data(void *packedBuf,
uint32_t packedMsgLength,
void *dataBuf,
uint32_t dataLength,
nfapi_p7_message_header_t *header)
{
if (ipc == NULL) {
return -1;
}
nv_ipc_msg_t send_msg;
uint8_t *pPacketBodyField = &((uint8_t *)packedBuf)[8];
uint8_t *pPackMessageEnd = packedBuf + packedMsgLength + 8;
uint16_t present_sfn = 0;
uint16_t present_slot = 0;
pull16(&pPacketBodyField, &present_sfn, pPackMessageEnd);
pull16(&pPacketBodyField, &present_slot, pPackMessageEnd);
if (present_sfn != old_sfn || present_slot != old_slot) {
LOG_E(NFAPI_VNF,
"\n============================================================================\n"
"sfn slot doesn't match unpacked one! L2->L1 %d.%d vs L1->L2 %d.%d \n"
"============================================================================\n",
present_sfn,
present_slot,
old_sfn,
old_slot);
}
// look for the specific message
switch (header->message_id) {
case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
case NFAPI_UE_RELEASE_REQUEST:
case NFAPI_UE_RELEASE_RESPONSE:
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
case NFAPI_TIMING_INFO:
break;
default: {
if (header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
} else {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id);
}
} break;
}
send_msg.msg_id = header->message_id;
send_msg.cell_id = 0;
send_msg.msg_len = packedMsgLength + 8; // adding 8 to account for the size of the FAPI header
send_msg.data_len = dataLength;
send_msg.data_pool = NV_IPC_MEMPOOL_CPU_DATA;
// procedure is allocate->fill->send
// Allocate buffer for TX message
int alloc_retval = ipc->tx_allocate(ipc, &send_msg, 0);
if (alloc_retval != 0) {
LOG_E(NFAPI_VNF, "%s error: allocate TX buffer failed Error: %d\n", __FUNCTION__, alloc_retval);
ipc->tx_release(ipc, &send_msg);
return alloc_retval;
}
memcpy(send_msg.msg_buf, packedBuf, send_msg.msg_len);
memcpy(send_msg.data_buf, dataBuf, send_msg.data_len);
LOG_D(NFAPI_VNF,
"send: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n",
send_msg.cell_id,
send_msg.msg_id,
send_msg.msg_len,
send_msg.data_len,
send_msg.data_pool);
// Send the message
int send_retval = ipc->tx_send_msg(ipc, &send_msg);
if (send_retval != 0) {
LOG_E(NFAPI_VNF, "%s error: send TX message failed Error: %d\n", __FUNCTION__, send_retval);
ipc->tx_release(ipc, &send_msg);
return send_retval;
}
ipc->notify(ipc, 1); // notify that there's 1 message in queue
return 0;
}
// Always allocate message buffer, but allocate data buffer only when data_len > 0
static int aerial_recv_msg(nv_ipc_t *ipc, nv_ipc_msg_t *recv_msg)
{
if (ipc == NULL) {
return -1;
}
recv_msg->msg_buf = NULL;
recv_msg->data_buf = NULL;
// Allocate buffer for TX message
if (ipc->rx_recv_msg(ipc, recv_msg) < 0) {
LOG_D(NFAPI_VNF, "%s: no more message available\n", __func__);
return -1;
}
LOG_D(NFAPI_VNF,
"recv: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n",
recv_msg->cell_id,
recv_msg->msg_id,
recv_msg->msg_len,
recv_msg->data_len,
recv_msg->data_pool);
ipc_handle_rx_msg(ipc, recv_msg);
// Release buffer of RX message
int release_retval = ipc->rx_release(ipc, recv_msg);
if (release_retval != 0) {
LOG_E(NFAPI_VNF, "%s error: release RX buffer failed Error: %d\n", __FUNCTION__, release_retval);
return release_retval;
}
return 0;
}
bool recv_task_running = false;
int stick_this_thread_to_core(int core_id)
{
int num_cores = sysconf(_SC_NPROCESSORS_ONLN);
if (core_id < 0 || core_id >= num_cores)
return EINVAL;
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(core_id, &cpuset);
pthread_t current_thread = pthread_self();
return pthread_setaffinity_np(current_thread, sizeof(cpu_set_t), &cpuset);
}
void *epoll_recv_task(void *arg)
{
struct epoll_event ev, events[MAX_EVENTS];
stick_this_thread_to_core(10);
LOG_D(NFAPI_VNF,"Aerial recv task start \n");
int epoll_fd = epoll_create1(0);
if (epoll_fd == -1) {
LOG_E(NFAPI_VNF, "%s epoll_create failed\n", __func__);
}
int ipc_rx_event_fd = ipc->get_fd(ipc);
ev.events = EPOLLIN;
ev.data.fd = ipc_rx_event_fd;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, ev.data.fd, &ev) == -1) {
LOG_E(NFAPI_VNF, "%s epoll_ctl failed\n", __func__);
}
while (1) {
if (!recv_task_running) {
recv_task_running = true;
}
LOG_D(NFAPI_VNF, "%s: epoll_wait fd_rx=%d ...\n", __func__, ipc_rx_event_fd);
int nfds;
do {
// epoll_wait() may return EINTR when get unexpected signal SIGSTOP from system
nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
} while (nfds == -1 && errno == EINTR);
if (nfds < 0) {
LOG_E(NFAPI_VNF, "epoll_wait failed: epoll_fd=%d nfds=%d err=%d - %s\n", epoll_fd, nfds, errno, strerror(errno));
}
int n = 0;
for (n = 0; n < nfds; ++n) {
if (events[n].data.fd == ipc_rx_event_fd) {
ipc->get_value(ipc);
nv_ipc_msg_t recv_msg;
while (aerial_recv_msg(ipc, &recv_msg) == 0);
}
}
}
close(epoll_fd);
return NULL;
}
int create_recv_thread(void)
{
pthread_t thread_id;
void *(*recv_task)(void *);
recv_task = epoll_recv_task;
int ret = pthread_create(&thread_id, NULL, recv_task, NULL);
if (ret != 0) {
LOG_E(NFAPI_VNF, "%s failed, ret = %d\n", __func__, ret);
}
return ret;
}
int load_hard_code_config(nv_ipc_config_t *config, int module_type, nv_ipc_transport_t _transport)
{
// Create configuration
config->ipc_transport = _transport;
if (set_nv_ipc_default_config(config, module_type) < 0) {
LOG_E(NFAPI_VNF, "%s: set configuration failed\n", __func__);
return -1;
}
#ifdef NVIPC_CUDA_ENABLE
int test_cuda_device_id = get_cuda_device_id();
#else
int test_cuda_device_id = -1;
#endif
LOG_D(NFAPI_VNF,"CUDA device ID configured : %d \n", test_cuda_device_id);
config->transport_config.shm.cuda_device_id = test_cuda_device_id;
if (test_cuda_device_id >= 0) {
config->transport_config.shm.mempool_size[NV_IPC_MEMPOOL_CUDA_DATA].pool_len = 128;
config->transport_config.shm.mempool_size[NV_IPC_MEMPOOL_CPU_DATA].pool_len = 1024;
config->transport_config.shm.mempool_size[NV_IPC_MEMPOOL_CPU_MSG].pool_len = 4096;
}
return 0;
}
int nvIPC_Init() {
// Want to use transport SHM, type epoll, module secondary (reads the created shm from cuphycontroller)
load_hard_code_config(&nv_ipc_config, NV_IPC_MODULE_SECONDARY, NV_IPC_TRANSPORT_SHM);
// Create nv_ipc_t instance
if ((ipc = create_nv_ipc_interface(&nv_ipc_config)) == NULL) {
LOG_E(NFAPI_VNF, "%s: create IPC interface failed\n", __func__);
return -1;
}
LOG_I(NFAPI_VNF, "%s: create IPC interface successful\n", __func__);
sleep(1);
create_recv_thread();
while(!recv_task_running){usleep(100000);}
aerial_pnf_nr_connection_indication_cb(vnf_config, 1);
return 0;
}
#endif
+61
View File
@@ -0,0 +1,61 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file fapi/oai-integration/fapi_nvIPC.h
* \brief Header file for fapi_nvIPC.c
* \author Ruben S. Silva
* \date 2023
* \version 0.1
* \company OpenAirInterface Software Alliance
* \email: contact@openairinterface.org, rsilva@allbesmart.pt
* \note
* \warning
*/
#ifdef ENABLE_AERIAL
#ifndef OPENAIRINTERFACE_FAPI_NVIPC_H
#define OPENAIRINTERFACE_FAPI_NVIPC_H
#include "nv_ipc.h"
#include "nv_ipc_utils.h"
#include "nvlog.h"
#include "nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h"
#include "openair1/PHY/defs_gNB.h"
#include "debug.h"
typedef struct {
uint8_t num_msg;
uint8_t opaque_handle;
uint16_t message_id;
uint32_t message_length;
} fapi_phy_api_msg;
int aerial_send_P5_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p4_p5_message_header_t *header);
int aerial_send_P7_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p7_message_header_t *header);
int aerial_send_P7_msg_with_data(void *packedBuf,
uint32_t packedMsgLength,
void *dataBuf,
uint32_t dataLength,
nfapi_p7_message_header_t *header);
void set_config(nfapi_vnf_config_t *conf);
int nvIPC_Init();
#endif // OPENAIRINTERFACE_FAPI_NVIPC_H
#endif
+765
View File
@@ -0,0 +1,765 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file fapi/oai-integration/fapi_vnf_p5.c
* \brief OAI FAPI VNF P5 message handler procedures
* \author Ruben S. Silva
* \date 2023
* \version 0.1
* \company OpenAirInterface Software Alliance
* \email: contact@openairinterface.org, rsilva@allbesmart.pt
* \note
* \warning
*/
#ifdef ENABLE_AERIAL
#include "fapi_vnf_p5.h"
#include "fapi_vnf_p7.h"
#include "nfapi/open-nFAPI/nfapi/src/nfapi_p5.c"
#include "nfapi/open-nFAPI/vnf/inc/vnf_p7.h"
extern RAN_CONTEXT_t RC;
extern UL_RCC_IND_t UL_RCC_INFO;
extern int single_thread_flag;
extern uint16_t sf_ahead;
extern uint16_t slot_ahead;
static pthread_t vnf_aerial_p7_start_pthread;
void *aerial_vnf_nr_aerial_p7_start_thread(void *ptr)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__);
pthread_setname_np(pthread_self(), "VNF_P7_AERIAL");
nfapi_vnf_p7_config_t *config = (nfapi_vnf_p7_config_t *)ptr;
aerial_nfapi_nr_vnf_p7_start(config);
return config;
}
void *aerial_vnf_nr_p7_thread_start(void *ptr)
{
// set_thread_priority(79);
int s;
cpu_set_t cpuset;
CPU_SET(8, &cpuset);
s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
if (s != 0)
printf("failed to set afinity\n");
set_priority(79);
pthread_attr_t ptAttr;
if (pthread_attr_setschedpolicy(&ptAttr, SCHED_RR) != 0) {
printf("Failed to set pthread sched policy SCHED_RR\n");
}
pthread_attr_setinheritsched(&ptAttr, PTHREAD_EXPLICIT_SCHED);
struct sched_param thread_params;
thread_params.sched_priority = 20;
if (pthread_attr_setschedparam(&ptAttr, &thread_params) != 0) {
printf("failed to set sched param\n");
}
init_queue(&gnb_rach_ind_queue);
init_queue(&gnb_rx_ind_queue);
init_queue(&gnb_crc_ind_queue);
init_queue(&gnb_uci_ind_queue);
init_queue(&gnb_slot_ind_queue);
vnf_p7_info *p7_vnf = (vnf_p7_info *)ptr;
p7_vnf->config->port = p7_vnf->local_port;
p7_vnf->config->sync_indication = &aerial_phy_sync_indication;
p7_vnf->config->slot_indication = &aerial_phy_slot_indication;
p7_vnf->config->harq_indication = &aerial_phy_harq_indication;
p7_vnf->config->nr_crc_indication = &aerial_phy_nr_crc_indication;
p7_vnf->config->nr_rx_data_indication = &aerial_phy_nr_rx_data_indication;
p7_vnf->config->nr_rach_indication = &aerial_phy_nr_rach_indication;
p7_vnf->config->nr_uci_indication = &aerial_phy_nr_uci_indication;
p7_vnf->config->srs_indication = &aerial_phy_srs_indication;
p7_vnf->config->sr_indication = &aerial_phy_sr_indication;
p7_vnf->config->cqi_indication = &aerial_phy_cqi_indication;
p7_vnf->config->lbt_dl_indication = &aerial_phy_lbt_dl_indication;
p7_vnf->config->nb_harq_indication = &aerial_phy_nb_harq_indication;
p7_vnf->config->nrach_indication = &aerial_phy_nrach_indication;
p7_vnf->config->nr_slot_indication = &aerial_phy_nr_slot_indication;
p7_vnf->config->nr_srs_indication = &aerial_phy_nr_srs_indication;
p7_vnf->config->malloc = &aerial_vnf_allocate;
p7_vnf->config->free = &aerial_vnf_deallocate;
p7_vnf->config->vendor_ext = &aerial_phy_vendor_ext;
p7_vnf->config->user_data = p7_vnf;
p7_vnf->mac->user_data = p7_vnf;
p7_vnf->config->codec_config.unpack_p7_vendor_extension = &aerial_phy_unpack_p7_vendor_extension;
p7_vnf->config->codec_config.pack_p7_vendor_extension = &aerial_phy_pack_p7_vendor_extension;
p7_vnf->config->codec_config.unpack_vendor_extension_tlv = &aerial_phy_unpack_vendor_extension_tlv;
p7_vnf->config->codec_config.pack_vendor_extension_tlv = &aerial_phy_pack_vendor_extension_tlv;
p7_vnf->config->codec_config.allocate = &aerial_vnf_allocate;
p7_vnf->config->codec_config.deallocate = &aerial_vnf_deallocate;
p7_vnf->config->allocate_p7_vendor_ext = &aerial_phy_allocate_p7_vendor_ext;
p7_vnf->config->deallocate_p7_vendor_ext = &aerial_phy_deallocate_p7_vendor_ext;
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI P7 start thread %s\n", __FUNCTION__);
pthread_create(&vnf_aerial_p7_start_pthread, NULL, &aerial_vnf_nr_aerial_p7_start_thread, p7_vnf->config);
return 0;
}
int aerial_pnf_nr_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx)
{
printf("[VNF] pnf connection indication idx:%d\n", p5_idx);
// in aerial, send first CONFIG.request, not PARAM.request
nfapi_nr_config_request_scf_t conf_req;
memset(&conf_req, 0, sizeof(conf_req));
conf_req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST;
printf("Try to send first CONFIG.request\n");
aerial_nr_send_config_request(config, p5_idx);
return 0;
}
int aerial_pnf_disconnection_indication_cb(nfapi_vnf_config_t *config, int p5_idx)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] pnf disconnection indication idx:%d\n", p5_idx);
vnf_info *vnf = (vnf_info *)(config->user_data);
pnf_info *pnf = vnf->pnfs;
phy_info *phy = pnf->phys;
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
nfapi_vnf_p7_del_pnf((p7_vnf->config), phy->id);
return 0;
}
int aerial_pnf_nr_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_param_response_t *resp)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] pnf param response idx:%d error:%d\n", p5_idx, resp->error_code);
vnf_info *vnf = (vnf_info *)(config->user_data);
pnf_info *pnf = vnf->pnfs;
for (int i = 0; i < resp->pnf_phy.number_of_phys; ++i) {
phy_info phy;
memset(&phy, 0, sizeof(phy));
phy.index = resp->pnf_phy.phy[i].phy_config_index;
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] (PHY:%d) phy_config_idx:%d\n", i, resp->pnf_phy.phy[i].phy_config_index);
nfapi_vnf_allocate_phy(config, p5_idx, &(phy.id));
for (int j = 0; j < resp->pnf_phy.phy[i].number_of_rfs; ++j) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] (PHY:%d) (RF%d) %d\n", i, j, resp->pnf_phy.phy[i].rf_config[j].rf_config_index);
phy.rfs[0] = resp->pnf_phy.phy[i].rf_config[j].rf_config_index;
}
pnf->phys[0] = phy;
}
nfapi_nr_pnf_config_request_t req;
memset(&req, 0, sizeof(req));
req.header.message_id = NFAPI_PNF_CONFIG_REQUEST;
req.pnf_phy_rf_config.tl.tag = NFAPI_PNF_PHY_RF_TAG;
req.pnf_phy_rf_config.number_phy_rf_config_info = 2; // DJP pnf.phys.size();
NFAPI_TRACE(NFAPI_TRACE_INFO, "DJP:Hard coded num phy rf to 2\n");
for (unsigned i = 0; i < 2; ++i) {
req.pnf_phy_rf_config.phy_rf_config[i].phy_id = pnf->phys[i].id;
req.pnf_phy_rf_config.phy_rf_config[i].phy_config_index = pnf->phys[i].index;
req.pnf_phy_rf_config.phy_rf_config[i].rf_config_index = pnf->phys[i].rfs[0];
}
nfapi_nr_vnf_pnf_config_req(config, p5_idx, &req);
return 0;
}
int aerial_pnf_nr_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_config_response_t *resp)
{
NFAPI_TRACE(NFAPI_TRACE_INFO,
"[VNF] pnf config response idx:%d resp[header[phy_id:%u message_id:%02x message_length:%u]]\n",
p5_idx,
resp->header.phy_id,
resp->header.message_id,
resp->header.message_length);
if (1) {
nfapi_nr_pnf_start_request_t req;
memset(&req, 0, sizeof(req));
req.header.phy_id = resp->header.phy_id;
req.header.message_id = NFAPI_PNF_START_REQUEST;
nfapi_nr_vnf_pnf_start_req(config, p5_idx, &req);
} else {
// Rather than send the pnf_start_request we will demonstrate
// sending a vendor extention message. The start request will be
// send when the vendor extension response is received
// vnf_info* vnf = (vnf_info*)(config->user_data);
vendor_ext_p5_req req;
memset(&req, 0, sizeof(req));
req.header.message_id = P5_VENDOR_EXT_REQ;
req.dummy1 = 45;
req.dummy2 = 1977;
nfapi_vnf_vendor_extension(config, p5_idx, &req.header);
}
return 0;
}
int aerial_pnf_nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_start_response_t *resp)
{
vnf_info *vnf = (vnf_info *)(config->user_data);
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
pnf_info *pnf = vnf->pnfs;
nfapi_nr_param_request_scf_t req;
NFAPI_TRACE(NFAPI_TRACE_INFO,
"[VNF] pnf start response idx:%d config:%p user_data:%p p7_vnf[config:%p thread_started:%d]\n",
p5_idx,
config,
config->user_data,
vnf->p7_vnfs[0].config,
vnf->p7_vnfs[0].thread_started);
if (p7_vnf->thread_started == 0) {
pthread_t vnf_p7_thread;
pthread_create(&vnf_p7_thread, NULL, &aerial_vnf_nr_p7_thread_start, p7_vnf);
p7_vnf->thread_started = 1;
} else {
// P7 thread already running.
}
// start all the phys in the pnf.
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Sending NFAPI_VNF_PARAM_REQUEST phy_id:%d\n", pnf->phys[0].id);
memset(&req, 0, sizeof(req));
req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST;
req.header.phy_id = pnf->phys[0].id;
nfapi_nr_vnf_param_req(config, p5_idx, &req);
return 0;
}
int aerial_nr_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_param_response_scf_t *resp)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Received NFAPI_PARAM_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
vnf_info *vnf = (vnf_info *)(config->user_data);
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
pnf_info *pnf = vnf->pnfs;
phy_info *phy = pnf->phys;
struct sockaddr_in pnf_p7_sockaddr;
nfapi_nr_config_request_scf_t *req = &RC.nrmac[0]->config[0]; // check
phy->remote_port = resp->nfapi_config.p7_pnf_port.value;
// phy->remote_port = 32123;//resp->nfapi_config.p7_pnf_port.value;
memcpy(&pnf_p7_sockaddr.sin_addr.s_addr, &(resp->nfapi_config.p7_pnf_address_ipv4.address[0]), 4);
phy->remote_addr = inet_ntoa(pnf_p7_sockaddr.sin_addr);
// for now just 1
NFAPI_TRACE(NFAPI_TRACE_INFO,
"[VNF] %d.%d pnf p7 %s:%d timing %u %u %u %u\n",
p5_idx,
phy->id,
phy->remote_addr,
phy->remote_port,
p7_vnf->timing_window,
p7_vnf->periodic_timing_period,
p7_vnf->aperiodic_timing_enabled,
p7_vnf->periodic_timing_period);
req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST;
req->header.phy_id = phy->id;
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Send NFAPI_CONFIG_REQUEST\n");
// NFAPI_TRACE(NFAPI_TRACE_INFO, "\n NR bandP =%d\n",req->nfapi_config.rf_bands.rf_band[0]);
req->nfapi_config.p7_vnf_port.tl.tag = NFAPI_NR_NFAPI_P7_VNF_PORT_TAG;
req->nfapi_config.p7_vnf_port.value = p7_vnf->local_port;
req->num_tlv++;
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] DJP local_port:%d\n", ntohs(p7_vnf->local_port));
req->nfapi_config.p7_vnf_address_ipv4.tl.tag = NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG;
struct sockaddr_in vnf_p7_sockaddr;
vnf_p7_sockaddr.sin_addr.s_addr = inet_addr(p7_vnf->local_addr);
memcpy(&(req->nfapi_config.p7_vnf_address_ipv4.address[0]), &vnf_p7_sockaddr.sin_addr.s_addr, 4);
req->num_tlv++;
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] DJP local_addr:%s\n", p7_vnf->local_addr);
req->nfapi_config.timing_window.tl.tag = NFAPI_NR_NFAPI_TIMING_WINDOW_TAG;
req->nfapi_config.timing_window.value = p7_vnf->timing_window;
NFAPI_TRACE(NFAPI_TRACE_INFO,
"\n[VNF]Timing window tag : %d Timing window:%u\n",
NFAPI_NR_NFAPI_TIMING_WINDOW_TAG,
p7_vnf->timing_window);
req->num_tlv++;
if (p7_vnf->periodic_timing_enabled || p7_vnf->aperiodic_timing_enabled) {
req->nfapi_config.timing_info_mode.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG;
req->nfapi_config.timing_info_mode.value = (p7_vnf->aperiodic_timing_enabled << 1) | (p7_vnf->periodic_timing_enabled);
req->num_tlv++;
if (p7_vnf->periodic_timing_enabled) {
req->nfapi_config.timing_info_period.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG;
req->nfapi_config.timing_info_period.value = p7_vnf->periodic_timing_period;
req->num_tlv++;
}
}
// TODO: Assign tag and value for P7 message offsets
req->nfapi_config.dl_tti_timing_offset.tl.tag = NFAPI_NR_NFAPI_DL_TTI_TIMING_OFFSET;
req->nfapi_config.ul_tti_timing_offset.tl.tag = NFAPI_NR_NFAPI_UL_TTI_TIMING_OFFSET;
req->nfapi_config.ul_dci_timing_offset.tl.tag = NFAPI_NR_NFAPI_UL_DCI_TIMING_OFFSET;
req->nfapi_config.tx_data_timing_offset.tl.tag = NFAPI_NR_NFAPI_TX_DATA_TIMING_OFFSET;
vendor_ext_tlv_2 ve2;
memset(&ve2, 0, sizeof(ve2));
ve2.tl.tag = VENDOR_EXT_TLV_2_TAG;
ve2.dummy = 2016;
req->vendor_extension = &ve2.tl;
nfapi_nr_vnf_config_req(config, p5_idx, req);
printf("[VNF] Sent NFAPI_VNF_CONFIG_REQ num_tlv:%u\n", req->num_tlv);
return 0;
}
int aerial_nr_send_config_request(nfapi_vnf_config_t *config, int p5_idx)
{
vnf_info *vnf = (vnf_info *)(config->user_data);
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
pnf_info *pnf = vnf->pnfs;
phy_info *phy = pnf->phys;
nfapi_nr_config_request_scf_t *req = &RC.nrmac[0]->config[0]; //&RC.gNB[0]->gNB_config; // check
NFAPI_TRACE(NFAPI_TRACE_INFO,
"[VNF] %d.%d pnf p7 %s:%d timing %u %u %u %u\n",
p5_idx,
phy->id,
phy->remote_addr,
phy->remote_port,
p7_vnf->timing_window,
p7_vnf->periodic_timing_period,
p7_vnf->aperiodic_timing_enabled,
p7_vnf->periodic_timing_period);
req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST;
req->header.phy_id = phy->id;
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Send NFAPI_CONFIG_REQUEST\n");
vnf_t *_this = (vnf_t *)(config);
nfapi_vnf_phy_info_t *vnf_phy = nfapi_vnf_phy_info_list_find(config, req->header.phy_id);
if (vnf_phy == NULL) {
printf("%s failed to find phy information phy_id:%d\n", __FUNCTION__, req->header.phy_id);
return -1;
}
nfapi_p4_p5_message_header_t *msg = &req->header;
uint16_t msg_len = sizeof(nfapi_nr_config_request_scf_t);
nfapi_p4_p5_message_header_t *msgFAPI = calloc(1, msg_len);
memcpy(msgFAPI, &req->header, msg_len);
uint8_t tx_messagebufferFAPI[sizeof(_this->tx_message_buffer)];
int packedMessageLengthFAPI = -1;
packedMessageLengthFAPI =
fapi_nr_p5_message_pack(msgFAPI, msg_len, tx_messagebufferFAPI, sizeof(tx_messagebufferFAPI), &_this->_public.codec_config);
aerial_send_P5_msg(tx_messagebufferFAPI, packedMessageLengthFAPI, msg);
return 0;
}
int aerial_nr_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_config_response_scf_t *resp)
{
nfapi_nr_start_request_scf_t req;
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Received NFAPI_CONFIG_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
LOG_I(NFAPI_VNF, "Received CONFIG.response, gNB is ready! \n");
memset(&req, 0, sizeof(req));
req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_START_REQUEST;
req.header.phy_id = resp->header.phy_id;
nfapi_nr_vnf_start_req(config, p5_idx, &req);
return 0;
}
int aerial_nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_start_response_scf_t *resp)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Received NFAPI_START_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
vnf_info *vnf = (vnf_info *)(config->user_data);
pnf_info *pnf = vnf->pnfs;
phy_info *phy = pnf->phys;
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
nfapi_vnf_p7_add_pnf((p7_vnf->config), phy->remote_addr, phy->remote_port, phy->id);
return 0;
}
int aerial_vendor_ext_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_p4_p5_message_header_t *msg)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s\n", __FUNCTION__);
switch (msg->message_id) {
case P5_VENDOR_EXT_RSP: {
vendor_ext_p5_rsp *rsp = (vendor_ext_p5_rsp *)msg;
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] P5_VENDOR_EXT_RSP error_code:%d\n", rsp->error_code);
// send the start request
nfapi_pnf_start_request_t req;
memset(&req, 0, sizeof(req));
req.header.message_id = NFAPI_PNF_START_REQUEST;
nfapi_vnf_pnf_start_req(config, p5_idx, &req);
} break;
}
return 0;
}
int aerial_vnf_unpack_vendor_extension_tlv(nfapi_tl_t *tl,
uint8_t **ppReadPackedMessage,
uint8_t *end,
void **ve,
nfapi_p4_p5_codec_config_t *codec)
{
return -1;
}
int aerial_vnf_pack_vendor_extension_tlv(void *vext, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *codec)
{
nfapi_tl_t *tlv = (nfapi_tl_t *)vext;
switch (tlv->tag) {
case VENDOR_EXT_TLV_2_TAG: {
vendor_ext_tlv_2 *ve = (vendor_ext_tlv_2 *)tlv;
if (!push32(ve->dummy, ppWritePackedMsg, end))
return 0;
return 1;
} break;
}
return -1;
}
int aerial_vnf_unpack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header,
uint8_t **ppReadPackedMessage,
uint8_t *end,
nfapi_p4_p5_codec_config_t *codec)
{
if (header->message_id == P5_VENDOR_EXT_RSP) {
vendor_ext_p5_rsp *req = (vendor_ext_p5_rsp *)(header);
return (!pull16(ppReadPackedMessage, &req->error_code, end));
}
return 0;
}
int aerial_vnf_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header,
uint8_t **ppWritePackedMsg,
uint8_t *end,
nfapi_p4_p5_codec_config_t *codec)
{
if (header->message_id == P5_VENDOR_EXT_REQ) {
vendor_ext_p5_req *req = (vendor_ext_p5_req *)(header);
return (!(push16(req->dummy1, ppWritePackedMsg, end) && push16(req->dummy2, ppWritePackedMsg, end)));
}
return 0;
}
nfapi_p4_p5_message_header_t *aerial_vnf_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t *msg_size)
{
if (message_id == P5_VENDOR_EXT_RSP) {
*msg_size = sizeof(vendor_ext_p5_rsp);
return (nfapi_p4_p5_message_header_t *)malloc(sizeof(vendor_ext_p5_rsp));
}
return 0;
}
void aerial_vnf_deallocate_p4_p5_vendor_ext(nfapi_p4_p5_message_header_t *header)
{
free(header);
}
void *aerial_vnf_p5_allocate(size_t size)
{
// return (void*)memory_pool::allocate(size);
return (void *)malloc(size);
}
void aerial_vnf_p5_deallocate(void *ptr)
{
// memory_pool::deallocate((uint8_t*)ptr);
free(ptr);
}
static vnf_info aerial_vnf;
void aerial_configure_nr_fapi_vnf()
{
// TODO: Implement for FAPI
// nfapi_setmode(NFAPI_MODE_VNF);
memset(&aerial_vnf, 0, sizeof(aerial_vnf));
memset(aerial_vnf.p7_vnfs, 0, sizeof(aerial_vnf.p7_vnfs));
aerial_vnf.p7_vnfs[0].timing_window = 30;
aerial_vnf.p7_vnfs[0].periodic_timing_enabled = 0;
aerial_vnf.p7_vnfs[0].aperiodic_timing_enabled = 0;
aerial_vnf.p7_vnfs[0].periodic_timing_period = 10;
aerial_vnf.p7_vnfs[0].config = nfapi_vnf_p7_config_create();
aerial_vnf.p7_vnfs[0].mac = (mac_t *)malloc(sizeof(mac_t));
nfapi_vnf_config_t *config = nfapi_vnf_config_create();
config->malloc = malloc;
config->free = free;
config->vnf_ipv4 = 1;
config->vnf_ipv6 = 0;
config->pnf_list = 0;
config->phy_list = 0;
config->pnf_nr_connection_indication = &aerial_pnf_nr_connection_indication_cb;
config->pnf_disconnect_indication = &aerial_pnf_disconnection_indication_cb;
config->pnf_nr_param_resp = &aerial_pnf_nr_param_resp_cb;
config->pnf_nr_config_resp = &aerial_pnf_nr_config_resp_cb;
config->pnf_nr_start_resp = &aerial_pnf_nr_start_resp_cb;
config->nr_param_resp = &aerial_nr_param_resp_cb;
config->nr_config_resp = &aerial_nr_config_resp_cb;
config->nr_start_resp = &aerial_nr_start_resp_cb;
config->vendor_ext = &aerial_vendor_ext_cb;
config->user_data = &aerial_vnf;
// To allow custom vendor extentions to be added to nfapi
config->codec_config.unpack_vendor_extension_tlv = &aerial_vnf_unpack_vendor_extension_tlv;
config->codec_config.pack_vendor_extension_tlv = &aerial_vnf_pack_vendor_extension_tlv;
config->codec_config.unpack_p4_p5_vendor_extension = &aerial_vnf_unpack_p4_p5_vendor_extension;
config->codec_config.pack_p4_p5_vendor_extension = &aerial_vnf_pack_p4_p5_vendor_extension;
config->allocate_p4_p5_vendor_ext = &aerial_vnf_allocate_p4_p5_vendor_ext;
config->deallocate_p4_p5_vendor_ext = &aerial_vnf_deallocate_p4_p5_vendor_ext;
config->codec_config.allocate = &aerial_vnf_allocate;
config->codec_config.deallocate = &aerial_vnf_deallocate;
memset(&UL_RCC_INFO, 0, sizeof(UL_RCC_IND_t));
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI start thread %s\n", __FUNCTION__);
set_config(config);
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Created VNF NFAPI start thread %s\n", __FUNCTION__);
nfapi_vnf_pnf_info_t *pnf = (nfapi_vnf_pnf_info_t *)malloc(sizeof(nfapi_vnf_pnf_info_t));
NFAPI_TRACE(NFAPI_TRACE_INFO, "MALLOC nfapi_vnf_pnf_info_t for pnf_list pnf:%p\n", pnf);
memset(pnf, 0, sizeof(nfapi_vnf_pnf_info_t));
pnf->p5_idx = 1;
pnf->connected = 1;
// Add needed parameters
vnf_info *vnf = (vnf_info *)(config->user_data);
pnf_info *pnf_info = vnf->pnfs;
for (int i = 0; i < 1; ++i) {
phy_info phy;
memset(&phy, 0, sizeof(phy));
phy.index = 0;
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] (PHY:%d) phy_config_idx:%d\n", i, 0);
nfapi_vnf_allocate_phy(config, 1, &(phy.id));
for (int j = 0; j < 1; ++j) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] (PHY:%d) (RF%d) %d\n", i, j, 0);
phy.rfs[0] = 0;
}
pnf_info->phys[0] = phy;
}
nfapi_vnf_pnf_list_add(config, pnf);
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
NFAPI_TRACE(NFAPI_TRACE_INFO,
"[VNF] pnf start response idx:%d config:%p user_data:%p p7_vnf[config:%p thread_started:%d]\n",
1,
config,
config->user_data,
vnf->p7_vnfs[0].config,
vnf->p7_vnfs[0].thread_started);
if (p7_vnf->thread_started == 0) {
pthread_t vnf_p7_thread;
pthread_create(&vnf_p7_thread, NULL, &aerial_vnf_nr_p7_thread_start, p7_vnf);
p7_vnf->thread_started = 1;
} else {
// P7 thread already running.
}
}
uint8_t aerial_unpack_nr_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config)
{
return unpack_nr_param_response(ppReadPackedMsg, end, msg, config);
}
uint8_t aerial_unpack_nr_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config)
{
return unpack_nr_config_response(ppReadPackedMsg, end, msg, config);
}
// monitor the p7 endpoints and the timing loop and
// send indications to mac
int aerial_nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t *config)
{
if (config == 0)
return -1;
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__);
vnf_p7_t *vnf_p7 = (vnf_p7_t *)config;
// Create p7 receive udp port
// todo : this needs updating for Ipv6
NFAPI_TRACE(NFAPI_TRACE_INFO, "Initialising VNF P7 port:%u\n", config->port);
struct timespec ref_time;
clock_gettime(CLOCK_MONOTONIC, &ref_time);
uint8_t setup_done = 0;
while (vnf_p7->terminate == 0) {
if (setup_done == 0) {
struct timespec curr_time;
clock_gettime(CLOCK_MONOTONIC, &curr_time);
uint8_t setup_time = curr_time.tv_sec - ref_time.tv_sec;
if (setup_time > 3) {
setup_done = 1;
}
}
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p7 socket\n");
close(vnf_p7->socket);
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() returning\n", __FUNCTION__);
return 0;
}
int fapi_nr_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t *config){
nfapi_p4_p5_message_header_t *pMessageHeader = pMessageBuf;
uint8_t *pWritePackedMessage = pPackedBuf;
uint32_t packedMsgLen;
//uint16_t packedMsgLen16;
if (pMessageBuf == NULL || pPackedBuf == NULL) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 Pack supplied pointers are null\n");
return -1;
}
uint8_t *pPackMessageEnd = pPackedBuf + packedBufLen;
uint8_t *pPackedLengthField = &pWritePackedMessage[4];
uint8_t *pPacketBodyField = &pWritePackedMessage[8];
uint8_t *pPacketBodyFieldStart = &pWritePackedMessage[8];
pack_nr_p5_message_body(pMessageHeader, &pPacketBodyField, pPackMessageEnd, config);
// PHY API message header
push8(1, &pWritePackedMessage, pPackMessageEnd); // Number of messages
push8(0, &pWritePackedMessage, pPackMessageEnd); // Opaque handle
// PHY API Message structure
push16(pMessageHeader->message_id, &pWritePackedMessage, pPackMessageEnd); // Message type ID
if(1==1) {
// check for a valid message length
packedMsgLen = get_packed_msg_len((uintptr_t)pPacketBodyFieldStart, (uintptr_t)pPacketBodyField);
packedMsgLen-=1;
if(pMessageHeader->message_id == NFAPI_NR_PHY_MSG_TYPE_START_REQUEST){
//START.request doesn't have a body, length is 0
packedMsgLen = 0;
}else if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message 0x%02x length error %d, buffer supplied %d\n",pMessageHeader->message_id, packedMsgLen, packedBufLen);
return -1;
} else {
}
// Update the message length in the header
if(!push32(packedMsgLen, &pPackedLengthField, pPackMessageEnd))
return -1;
// return the packed length
return (packedMsgLen);
} else {
// Failed to pack the meassage
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 Failed to pack message\n");
return -1;
}
}
int oai_fapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req)
{
nfapi_vnf_p7_config_t *p7_config = aerial_vnf.p7_vnfs[0].config;
ul_tti_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
ul_tti_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST;
// int retval = nfapi_vnf_p7_ul_tti_req(p7_config, ul_tti_req);
int retval = fapi_nr_pack_and_send_p7_message((vnf_p7_t *)p7_config, &ul_tti_req->header);
if (retval != 0) {
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
} else {
// Reset number of PDUs so that it is not resent
ul_tti_req->n_pdus = 0;
ul_tti_req->n_group = 0;
ul_tti_req->n_ulcch = 0;
ul_tti_req->n_ulsch = 0;
}
return retval;
}
int oai_fapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req)
{
nfapi_vnf_p7_config_t *p7_config = aerial_vnf.p7_vnfs[0].config;
ul_dci_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
ul_dci_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST;
// int retval = nfapi_vnf_p7_ul_dci_req(p7_config, ul_dci_req);
int retval = fapi_nr_pack_and_send_p7_message((vnf_p7_t *)p7_config, &ul_dci_req->header);
if (retval != 0) {
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
} else {
ul_dci_req->numPdus = 0;
}
return retval;
}
int oai_fapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req)
{
nfapi_vnf_p7_config_t *p7_config = aerial_vnf.p7_vnfs[0].config;
tx_data_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
tx_data_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST;
// LOG_D(PHY, "[VNF] %s() TX_REQ sfn_sf:%d number_of_pdus:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(tx_data_req->SFN),
// tx_data_req->Number_of_PDUs); int retval = nfapi_vnf_p7_tx_data_req(p7_config, tx_data_req);
int retval = fapi_nr_pack_and_send_p7_message((vnf_p7_t *)p7_config, &tx_data_req->header);
if (retval != 0) {
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
} else {
tx_data_req->Number_of_PDUs = 0;
}
return retval;
}
int oai_fapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req)
{
nfapi_vnf_p7_config_t *p7_config = aerial_vnf.p7_vnfs[0].config;
dl_config_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST;
dl_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
int retval = fapi_nr_pack_and_send_p7_message((vnf_p7_t *)p7_config, &dl_config_req->header);
dl_config_req->dl_tti_request_body.nPDUs = 0;
dl_config_req->dl_tti_request_body.nGroup = 0;
if (retval != 0) {
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
}
return retval;
}
int oai_fapi_send_end_request(int cell, uint32_t frame, uint32_t slot){
nfapi_vnf_p7_config_t *p7_config = aerial_vnf.p7_vnfs[0].config;
nfapi_nr_slot_indication_scf_t *nr_slot_resp = CALLOC(1, sizeof(*nr_slot_resp));
nr_slot_resp->header.message_id = 0x8F;
nr_slot_resp->sfn = frame;
nr_slot_resp->slot = slot;
int retval = fapi_nr_pack_and_send_p7_message((vnf_p7_t *)p7_config, &nr_slot_resp->header);
if (retval != 0) {
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
}
return retval;
}
#endif
@@ -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
+243
View File
@@ -0,0 +1,243 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file fapi/oai-integration/fapi_vnf_p7.h
* \brief Header file for fapi_vnf_p7.c
* \author Ruben S. Silva
* \date 2023
* \version 0.1
* \company OpenAirInterface Software Alliance
* \email: contact@openairinterface.org, rsilva@allbesmart.pt
* \note
* \warning
*/
#ifdef ENABLE_AERIAL
#ifndef OPENAIRINTERFACE_FAPI_VNF_P7_H
#define OPENAIRINTERFACE_FAPI_VNF_P7_H
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "nfapi_nr_interface_scf.h"
#include "nfapi_vnf_interface.h"
#include "nfapi_vnf.h"
#include "nfapi.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include "fapi_nvIPC.h"
#include "PHY/defs_eNB.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
#include "lte-softmodem.h"
#include "common/ran_context.h"
#include "openair2/PHY_INTERFACE/queue_t.h"
#include "gnb_ind_vars.h"
#include "nfapi/open-nFAPI/vnf/inc/vnf.h"
#include "nfapi/open-nFAPI/vnf/inc/vnf_p7.h"
typedef struct {
uint8_t enabled;
uint32_t rx_port;
uint32_t tx_port;
char tx_addr[80];
} udp_data;
typedef struct {
uint16_t index;
uint16_t id;
uint8_t rfs[2];
uint8_t excluded_rfs[2];
udp_data udp;
char local_addr[80];
int local_port;
char *remote_addr;
int remote_port;
uint8_t duplex_mode;
uint16_t dl_channel_bw_support;
uint16_t ul_channel_bw_support;
uint8_t num_dl_layers_supported;
uint8_t num_ul_layers_supported;
uint16_t release_supported;
uint8_t nmm_modes_supported;
uint8_t dl_ues_per_subframe;
uint8_t ul_ues_per_subframe;
uint8_t first_subframe_ind;
// timing information recevied from the vnf
uint8_t timing_window;
uint8_t timing_info_mode;
uint8_t timing_info_period;
} phy_info;
typedef struct {
uint16_t index;
uint16_t band;
int16_t max_transmit_power;
int16_t min_transmit_power;
uint8_t num_antennas_supported;
uint32_t min_downlink_frequency;
uint32_t max_downlink_frequency;
uint32_t max_uplink_frequency;
uint32_t min_uplink_frequency;
} rf_info;
typedef struct {
int release;
phy_info phys[2];
rf_info rfs[2];
uint8_t sync_mode;
uint8_t location_mode;
uint8_t location_coordinates[6];
uint32_t dl_config_timing;
uint32_t ul_config_timing;
uint32_t tx_timing;
uint32_t hi_dci0_timing;
uint16_t max_phys;
uint16_t max_total_bw;
uint16_t max_total_dl_layers;
uint16_t max_total_ul_layers;
uint8_t shared_bands;
uint8_t shared_pa;
int16_t max_total_power;
uint8_t oui;
uint8_t wireshark_test_mode;
} pnf_info;
typedef struct mac mac_t;
typedef struct mac {
void *user_data;
void (*dl_config_req)(mac_t *mac, nfapi_dl_config_request_t *req);
void (*ul_config_req)(mac_t *mac, nfapi_ul_config_request_t *req);
void (*hi_dci0_req)(mac_t *mac, nfapi_hi_dci0_request_t *req);
void (*tx_req)(mac_t *mac, nfapi_tx_request_t *req);
} mac_t;
typedef struct {
int local_port;
char local_addr[80];
unsigned timing_window;
unsigned periodic_timing_enabled;
unsigned aperiodic_timing_enabled;
unsigned periodic_timing_period;
// This is not really the right place if we have multiple PHY,
// should be part of the phy struct
udp_data udp;
uint8_t thread_started;
nfapi_vnf_p7_config_t *config;
mac_t *mac;
} vnf_p7_info;
typedef struct {
uint8_t wireshark_test_mode;
pnf_info pnfs[2];
vnf_p7_info p7_vnfs[2];
} vnf_info;
int aerial_wake_gNB_rxtx(PHY_VARS_gNB *gNB, uint16_t sfn, uint16_t slot);
int aerial_wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf);
int aerial_phy_sync_indication(struct nfapi_vnf_p7_config *config, uint8_t sync);
int aerial_phy_slot_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, uint16_t sfn, uint16_t slot);
int aerial_phy_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_harq_indication_t *ind);
int aerial_phy_nr_crc_indication(nfapi_nr_crc_indication_t *ind);
int aerial_phy_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind);
int aerial_phy_nr_rach_indication(nfapi_nr_rach_indication_t *ind);
int aerial_phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind);
int aerial_phy_srs_indication(struct nfapi_vnf_p7_config *config, nfapi_srs_indication_t *ind);
int aerial_phy_sr_indication(struct nfapi_vnf_p7_config *config, nfapi_sr_indication_t *ind);
int aerial_phy_cqi_indication(struct nfapi_vnf_p7_config *config, nfapi_cqi_indication_t *ind);
int aerial_phy_lbt_dl_indication(struct nfapi_vnf_p7_config *config, nfapi_lbt_dl_indication_t *ind);
int aerial_phy_nb_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_nb_harq_indication_t *ind);
int aerial_phy_nrach_indication(struct nfapi_vnf_p7_config *config, nfapi_nrach_indication_t *ind);
int aerial_phy_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind);
int aerial_phy_nr_srs_indication(nfapi_nr_srs_indication_t *ind);
void *aerial_vnf_allocate(size_t size);
void aerial_vnf_deallocate(void *ptr);
int aerial_phy_vendor_ext(struct nfapi_vnf_p7_config *config, nfapi_p7_message_header_t *msg);
int aerial_phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t *header,
uint8_t **ppReadPackedMessage,
uint8_t *end,
nfapi_p7_codec_config_t *config);
int aerial_phy_pack_p7_vendor_extension(nfapi_p7_message_header_t *header,
uint8_t **ppWritePackedMsg,
uint8_t *end,
nfapi_p7_codec_config_t *config);
int aerial_phy_unpack_vendor_extension_tlv(nfapi_tl_t *tl,
uint8_t **ppReadPackedMessage,
uint8_t *end,
void **ve,
nfapi_p7_codec_config_t *codec);
int aerial_phy_pack_vendor_extension_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *codec);
nfapi_p7_message_header_t *aerial_phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t *msg_size);
void aerial_phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t *header);
uint8_t aerial_unpack_nr_slot_indication(uint8_t **ppReadPackedMsg,
uint8_t *end,
nfapi_nr_slot_indication_scf_t *msg,
nfapi_p7_codec_config_t *config);
uint8_t aerial_unpack_nr_rx_data_indication(uint8_t **ppReadPackedMsg,
uint8_t *end,
uint8_t **pDataMsg,
uint8_t *data_end,
nfapi_nr_rx_data_indication_t *msg,
nfapi_p7_codec_config_t *config);
uint8_t aerial_unpack_nr_crc_indication(uint8_t **ppReadPackedMsg,
uint8_t *end,
nfapi_nr_crc_indication_t *msg,
nfapi_p7_codec_config_t *config);
uint8_t aerial_unpack_nr_uci_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
uint8_t aerial_unpack_nr_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
uint8_t aerial_unpack_nr_rach_indication(uint8_t **ppReadPackedMsg,
uint8_t *end,
nfapi_nr_rach_indication_t *msg,
nfapi_p7_codec_config_t *config);
// int fapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config);
int fapi_nr_pack_and_send_p7_message(vnf_p7_t *vnf_p7, nfapi_p7_message_header_t *header);
#endif // OPENAIRINTERFACE_FAPI_VNF_P7_H
#endif
+2 -1
View File
@@ -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) {
+1
View File
@@ -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
+1
View File
@@ -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;
+40 -1
View File
@@ -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;
}
+136 -77
View File
@@ -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,
+25 -15
View File
@@ -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;
+5 -3
View File
@@ -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
+43 -14
View File
@@ -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;
}
}
+3 -1
View File
@@ -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]++;
+1
View File
@@ -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--) {
+8 -3
View File
@@ -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);
+2
View File
@@ -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???
+3 -3
View File
@@ -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;
+1 -1
View File
@@ -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;
+7 -7
View File
@@ -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);
}
}
+10 -11
View File
@@ -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;
+1
View File
@@ -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,
+1
View File
@@ -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
+5 -2
View File
@@ -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;
+7 -2
View File
@@ -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;
+26 -15
View File
@@ -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) {
+9 -10
View File
@@ -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;
+1
View File
@@ -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);
}
//==============================================================================================
+185 -205
View File
@@ -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
+7
View File
@@ -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++) {
+3 -2
View File
@@ -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;
+7 -7
View File
@@ -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;
+1 -1
View File
@@ -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;
+3 -9
View File
@@ -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 {
-2
View File
@@ -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;
+33 -7
View File
@@ -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 */
-1
View File
@@ -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
+22 -86
View File
@@ -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;
+1 -1
View File
@@ -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);
+6 -11
View File
@@ -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