Merge branch 'integration_2025_w46' into 'develop'

Integration `2025.w46`

* !3754 NR UE: correctly provide measured SSB SINR value from PHY to MAC
* !3666 NTN: Fixing variable ULDLduplex issue for NTN bands
* !3747 SDAP: guard RX header parsing with enable_sdap and init per-entity
* !3729 DCI 00 alt size fix
* !3753 gNB: fix MAC TA command scheduling if measurement gaps are configured
* !3722 [NGAP] Fix incorrect AMF Set ID type (uint8 → uint16) causing AMF lookup failure
* !3745 Collection of small fixes
* !3755 CI: Increase tested UL throughput on Aerial pipeline using 2L UL
* !3752 [MAC] Add UL total/used aggregated MAC stats; [E2 agent] Properly calculate used UE PRBs in KPM
* !3707 Cleanup phy_procedures_gNB_uespec_RX
* !3750 Handling newly opened UE issues
* !3751 Update log header format to align log output
* !3757 Remove schedule response and update L1 threading documentation
* !3748 Refactor imscope
* !3760 gNB: modify RLC configuration applied for SRB1 during RRCReestablishment
* !3684 PDU Session Release

Closes #867, #960, #1025, #1024, #1026, #1031, #1030, and #1012

See merge request oai/openairinterface5g!3756
This commit is contained in:
Robert Schmidt
2025-11-16 07:21:47 +00:00
135 changed files with 2951 additions and 2674 deletions
+1
View File
@@ -62,6 +62,7 @@ ForEachMacros:
- BOOST_FOREACH
- RB_FOREACH
- UE_iterator
- FOR_EACH_SEQ_ARR
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^<ext/.*\.h>'
+1 -10
View File
@@ -652,7 +652,6 @@ add_library(SCHED_LIB ${SCHED_SRC})
target_link_libraries(SCHED_LIB PRIVATE asn1_lte_rrc_hdrs)
set(SCHED_NR_SRC
${OPENAIR1_DIR}/SCHED_NR/fapi_nr_l1.c
${OPENAIR1_DIR}/SCHED_NR/phy_procedures_nr_gNB.c
${OPENAIR1_DIR}/SCHED_NR/nr_prach_procedures.c
${OPENAIR1_DIR}/SCHED_NR/phy_frame_config_nr.c
@@ -939,7 +938,6 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dci.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dci_tools.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch_tools.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch_coding.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch.c
@@ -1215,7 +1213,6 @@ set (MAC_SRC
set (MAC_NR_SRC
${NR_PHY_INTERFACE_DIR}/NR_IF_Module.c
${NR_PHY_INTERFACE_DIR}/nr_sched_response.c
${NR_GNB_MAC_DIR}/main.c
${NR_GNB_MAC_DIR}/config.c
${NR_GNB_MAC_DIR}/gNB_scheduler.c
@@ -1283,12 +1280,6 @@ set (MISC_NFAPI_LTE
add_library(MISC_NFAPI_LTE_LIB ${MISC_NFAPI_LTE})
set (MISC_NFAPI_NR
${OPENAIR1_DIR}/SCHED/nfapi_nr_dummy.c
)
add_library(MISC_NFAPI_NR_LIB ${MISC_NFAPI_NR})
add_library(L2
${L2_SRC}
${MAC_SRC}
@@ -2091,7 +2082,7 @@ if (${T_TRACER})
oai_eth_transpro HASHTABLE UTIL
SECURITY SCHED_LIB SCHED_NR_LIB SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB
NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB NFAPI_USER_LIB
MISC_NFAPI_LTE_LIB MISC_NFAPI_NR_LIB
MISC_NFAPI_LTE_LIB
PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU
L2 L2_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE MAC_NR_COMMON MAC_UE_NR ngap
GTPV1U SCTP_CLIENT MME_APP LIB_NAS_UE SIMU
+74 -22
View File
@@ -47,6 +47,7 @@ import helpreadme as HELP
import constants as CONST
import cls_oaicitest
from cls_ci_helper import archiveArtifact
from collections import deque
#-----------------------------------------------------------
# Helper functions used here and in other classes
@@ -165,25 +166,26 @@ def CopyinServiceLog(ssh, lSourcePath, svcName, wd_yaml, ctx):
ssh.run(f'docker compose -f {wd_yaml} logs {svcName} --no-log-prefix &> {remote_filename}')
return archiveArtifact(ssh, ctx, remote_filename)
def GetRunningServices(ssh, file):
def GetDeployedServices(ssh, file):
ret = ssh.run(f'docker compose -f {file} config --services')
if ret.returncode != 0:
logging.error("could not get services")
return None
allServices = ret.stdout.splitlines()
running_services = []
deployed_services = []
for s in allServices:
# outputs the hash if the container is running
ret = ssh.run(f'docker compose -f {file} ps --all --quiet -- {s}')
# outputs the hash if the container has been deployed (but might be stopped)
ret = ssh.run(f'docker compose -f {file} ps --all --quiet -- {s}', silent=True)
if ret.returncode != 0:
logging.info(f"service {s}: {ret.stdout}")
# error: should not happen as we iterate over docker-provided service list
logging.error(f"service {s}: {ret.stdout}")
elif ret.stdout == "":
logging.warning(f"could not retrieve information for service {s}")
logging.info(f"service {s} not deployed")
else:
c = ret.stdout
logging.debug(f'running service {s} with container id {c}')
running_services.append((s, c))
logging.info(f'stopping services: {running_services}')
return running_services
logging.info(f'service {s} with container id {c}')
deployed_services.append(s)
return deployed_services
def CheckLogs(self, filename, HTML, RAN):
success = True
@@ -215,6 +217,24 @@ def CheckLogs(self, filename, HTML, RAN):
else:
HTML.CreateHtmlTestRowQueue(opt, 'OK', [HTML.htmleNBFailureMsg])
HTML.htmleNBFailureMsg = ""
elif 'xapp' in name:
opt = f"Undeploy {name}"
with open(f'{filename}', "r") as f:
last_line = deque(f, maxlen=1).pop()
if ('Test xApp run SUCCESSFULLY' in last_line):
HTML.CreateHtmlTestRowQueue(opt, 'OK', ["xApp run successfully"])
else:
HTML.CreateHtmlTestRowQueue(opt, 'KO', ["xApp didn't run successfully"])
success = False
elif 'RIC' in name:
opt = f"Undeploy {name}"
with open(f'{filename}', 'r') as f:
last_line = deque(f, maxlen=1).pop()
if ('Removing E2 Node' in last_line):
HTML.CreateHtmlTestRowQueue(opt, 'OK', ["nearRT-RIC run successfully"])
else:
HTML.CreateHtmlTestRowQueue(opt, 'KO', ["nearRT-RIC didn't run successfully"])
success = False
else:
logging.info(f"Skipping analysis of log '{filename}': no submatch for xNB/UE")
logging.debug(f"log check: file {filename} passed analysis {success}")
@@ -715,7 +735,6 @@ class Containerize():
def DeployObject(self, ctx, node, HTML):
num_attempts = self.num_attempts
lSourcePath = self.eNBSourceCodePath
logging.debug(f'Deploying OAI Object on server: {node}')
yaml = self.yamlPath.strip('/')
wd = f'{lSourcePath}/{yaml}'
wd_yaml = f'{wd}/docker-compose.y*ml'
@@ -726,6 +745,7 @@ class Containerize():
logging.error(msg)
HTML.CreateHtmlTestRowQueue('N/A', 'KO', [msg])
return False
logging.info(f'\u001B[1mDeploying object(s) "{services}" on server {node}\u001B[0m')
ExistEnvFilePrint(ssh, wd)
WriteEnvFile(ssh, services, wd, self.deploymentTag, self.flexricTag)
if num_attempts <= 0:
@@ -750,36 +770,68 @@ class Containerize():
imagesInfo = info.stdout.splitlines()[1:]
logging.debug(f'{info.stdout.splitlines()[1:]}')
if deployed:
HTML.CreateHtmlTestRowQueue('N/A', 'OK', ['\n'.join(imagesInfo)])
HTML.CreateHtmlTestRowQueue(self.services, 'OK', ['\n'.join(imagesInfo)])
logging.info('\u001B[1m Deploying objects Pass\u001B[0m')
else:
HTML.CreateHtmlTestRowQueue('N/A', 'KO', ['\n'.join(imagesInfo)])
HTML.CreateHtmlTestRowQueue(self.services, 'KO', ['\n'.join(imagesInfo)])
logging.error('\u001B[1m Deploying objects Failed\u001B[0m')
return deployed
def StopObject(self, ctx, node, HTML):
lSourcePath = self.eNBSourceCodePath
if not self.services:
raise ValueError(f'no services provided')
logging.info(f'\u001B[1m Stopping objects "{self.services}" from server: {node}\u001B[0m')
reqServices = self.services.split()
yaml = self.yamlPath.strip('/')
wd = f'{lSourcePath}/{yaml}'
wd_yaml = f'{wd}/docker-compose.y*ml'
with cls_cmd.getConnection(node) as ssh:
ExistEnvFilePrint(ssh, wd)
services = GetDeployedServices(ssh, wd_yaml)
success = []
fail = []
for s in reqServices:
if s in services:
ssh.run(f'docker compose -f {wd_yaml} stop -- {s}')
success.append(s)
else:
logging.error(f"no such service {s}")
fail.append(s)
if success == reqServices:
logging.info('\u001B[1m Stopping object Pass\u001B[0m')
HTML.CreateHtmlTestRowQueue(self.services, 'OK', [f'Stopped {self.services}'])
else:
logging.error('\u001B[1m Stopping object Failed\u001B[0m')
HTML.CreateHtmlTestRowQueue(self.services, 'KO', [f'Failed stopping {" ".join(fail)}, succeeded {" ".join(success)}'])
return success
def UndeployObject(self, ctx, node, HTML, RAN):
lSourcePath = self.eNBSourceCodePath
logging.debug(f'\u001B[1m Undeploying OAI Object from server: {node}\u001B[0m')
logging.info(f'\u001B[1m Undeploying all objects from server {node}\u001B[0m')
yaml = self.yamlPath.strip('/')
wd = f'{lSourcePath}/{yaml}'
wd_yaml = f'{wd}/docker-compose.y*ml'
with cls_cmd.getConnection(node) as ssh:
ExistEnvFilePrint(ssh, wd)
services = GetRunningServices(ssh, f"{wd}/docker-compose.y*ml")
services = GetDeployedServices(ssh, wd_yaml)
copyin_res = None
ssh.run(f'docker compose -f {wd_yaml} stop')
if services is not None:
all_serv = " ".join([s for s, _ in services])
ssh.run(f'docker compose -f {wd}/docker-compose.y*ml stop -- {all_serv}')
copyin_res = [CopyinServiceLog(ssh, lSourcePath, s, f"{wd}/docker-compose.y*ml", ctx) for s, _ in services]
copyin_res = [CopyinServiceLog(ssh, lSourcePath, s, wd_yaml, ctx) for s in services]
else:
logging.warning('could not identify services to stop => no log file')
ssh.run(f'docker compose -f {wd}/docker-compose.y*ml down -v')
ssh.run(f'docker compose -f {wd_yaml} down -v')
ssh.run(f'rm {wd}/.env')
if not copyin_res:
HTML.CreateHtmlTestRowQueue('N/A', 'KO', ['Could not copy logfile(s)'])
return False
logging.error(f"could not copy all files: {copyin_res=} {services=}")
success = False
else:
log_results = [CheckLogs(self, f, HTML, RAN) for f in copyin_res]
success = all(log_results)
if success:
logging.info('\u001B[1m Undeploying OAI Object Pass\u001B[0m')
logging.info('\u001B[1m Undeploying objects Pass\u001B[0m')
else:
logging.error('\u001B[1m Undeploying OAI Object Failed\u001B[0m')
logging.error('\u001B[1m Undeploying objects Failed\u001B[0m')
return success
@@ -32,7 +32,7 @@ gNBs =
pdsch_AntennaPorts_N1 = 2;
pusch_AntennaPorts = 2;
do_CSIRS = 1;
do_SRS = 0;
do_SRS = 1;
min_rxtxtime = 2;
servingCellConfigCommon = (
@@ -155,7 +155,7 @@ gNBs =
nrofUplinkSlots = 3; #1;
nrofUplinkSymbols = 0;
ssPBCH_BlockPower = -25;
ssPBCH_BlockPower = -15;
}
);
@@ -195,7 +195,7 @@ MACRLCs = (
remote_s_portd = 50010; // pnf p7 port [!]
tr_s_preference = "aerial";
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 200; # 150;
pusch_TargetSNRx10 = 280; # 150;
pucch_TargetSNRx10 = 200; #200;
dl_max_mcs = 28;
ul_max_mcs = 28;
@@ -24,9 +24,9 @@ gNBs =
pdsch_AntennaPorts_N1 = 2;
pusch_AntennaPorts = 2;
do_CSIRS = 1;
do_SRS = 0;
do_SRS = 1;
min_rxtxtime = 2;
force_UL256qam_off = 1;
servingCellConfigCommon = (
{
#spCellConfigCommon
@@ -187,7 +187,7 @@ MACRLCs = (
remote_s_portd = 50010; // pnf p7 port [!]
tr_s_preference = "aerial";
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 220; # 150;
pusch_TargetSNRx10 = 260; # 150;
pucch_TargetSNRx10 = 200; #200;
dl_max_mcs = 28;
ul_max_mcs = 28;
-2
View File
@@ -15,7 +15,6 @@ Ref :
DLSCH encoding : 200.0
L1 Rx processing : 530.0
PUSCH inner-receiver : 360.0
Schedule Response : 1.0
DL & UL scheduling timing : 17.0
UL Indication : 1.0
Slot Indication : 13.0
@@ -31,7 +30,6 @@ DeviationThreshold :
DLSCH encoding : 0.25
L1 Rx processing : 0.25
PUSCH inner-receiver : 0.25
Schedule Response : 1.00
DL & UL scheduling timing : 0.25
UL Indication : 1.00
Slot Indication : 0.50
-2
View File
@@ -15,7 +15,6 @@ Ref :
DLSCH encoding : 110.0
L1 Rx processing : 345.0
PUSCH inner-receiver : 150.0
Schedule Response : 1.0
DL & UL scheduling timing : 5.0
UL Indication : 1.0
Slot Indication : 6.0
@@ -31,7 +30,6 @@ DeviationThreshold :
DLSCH encoding : 0.25
L1 Rx processing : 0.25
PUSCH inner-receiver : 0.25
Schedule Response : 1.00
DL & UL scheduling timing : 0.50
UL Indication : 1.00
Slot Indication : 0.50
-2
View File
@@ -15,7 +15,6 @@ Ref :
DLSCH encoding : 230.0
L1 Rx processing : 175.0
PUSCH inner-receiver : 100.0
Schedule Response : 3.0
DL & UL scheduling timing : 11.0
UL Indication : 3.0
Slot Indication : 14.0
@@ -28,7 +27,6 @@ DeviationThreshold :
DLSCH encoding : 0.25
L1 Rx processing : 0.25
PUSCH inner-receiver : 0.25
Schedule Response : 1.00
DL & UL scheduling timing : 0.50
UL Indication : 1.00
Slot Indication : 0.25
-2
View File
@@ -15,7 +15,6 @@ Ref :
DLSCH encoding : 140.0
L1 Rx processing : 345.0
PUSCH inner-receiver : 155.0
Schedule Response : 1.0
DL & UL scheduling timing : 8.0
UL Indication : 3.0
Slot Indication : 9.0
@@ -31,7 +30,6 @@ DeviationThreshold :
DLSCH encoding : 0.25
L1 Rx processing : 0.25
PUSCH inner-receiver : 0.25
Schedule Response : 1.00
DL & UL scheduling timing : 0.35
UL Indication : 1.00
Slot Indication : 0.35
-2
View File
@@ -15,7 +15,6 @@ Ref :
DLSCH encoding : 90.0
L1 Rx processing : 290.0
PUSCH inner-receiver : 115.0
Schedule Response : 1.0
DL & UL scheduling timing : 4.0
UL Indication : 2.0
Slot Indication : 5.0
@@ -31,7 +30,6 @@ DeviationThreshold :
DLSCH encoding : 0.25
L1 Rx processing : 0.25
PUSCH inner-receiver : 0.25
Schedule Response : 1.00
DL & UL scheduling timing : 0.50
UL Indication : 1.00
Slot Indication : 0.50
+3 -1
View File
@@ -214,7 +214,7 @@ def ExecuteActionWithParam(action, ctx, node):
core_op = getattr(cls_oaicitest.OaiCiTest, action)
success = core_op(cn_id, ctx, HTML)
elif action == 'Deploy_Object' or action == 'Undeploy_Object' or action == "Create_Workspace":
elif action == 'Deploy_Object' or action == 'Undeploy_Object' or action == "Create_Workspace" or action == "Stop_Object":
CONTAINERS.yamlPath = test.findtext('yaml_path')
string_field=test.findtext('d_retx_th')
if (string_field is not None):
@@ -227,6 +227,8 @@ def ExecuteActionWithParam(action, ctx, node):
CONTAINERS.deploymentTag = cls_containerize.CreateTag(CONTAINERS.ranCommitID, CONTAINERS.ranBranch, CONTAINERS.ranAllowMerge)
if action == 'Deploy_Object':
success = CONTAINERS.DeployObject(ctx, node, HTML)
elif action == 'Stop_Object':
success = CONTAINERS.StopObject(ctx, node, HTML)
elif action == 'Undeploy_Object':
success = CONTAINERS.UndeployObject(ctx, node, HTML, RAN)
elif action == 'Create_Workspace':
+27
View File
@@ -60,6 +60,33 @@ class TestDeploymentMethods(unittest.TestCase):
self.assertTrue(deploy)
self.assertTrue(undeploy)
def test_stop_services(self):
self.cont.yamlPath = 'tests/simple-undep/'
self.cont.deploymentTag = "noble"
# should deploy both testA and testB
deploy = self.cont.DeployObject(self.ctx, self.node, self.html)
# should fail (no such service)
self.cont.services = "testC"
stopC = self.cont.StopObject(self.ctx, self.node, self.html)
# should stop testA
self.cont.services = "testA"
stopA = self.cont.StopObject(self.ctx, self.node, self.html)
# should (re-)stop testA (no-op)
self.cont.services = "testA"
stopA2 = self.cont.StopObject(self.ctx, self.node, self.html)
# should deploy testB
self.cont.services = "testB"
stopB = self.cont.StopObject(self.ctx, self.node, self.html)
# should not undeploy anything (everything already stopped)
self.cont.services = None
undeployAll = self.cont.UndeployObject(self.ctx, self.node, self.html, self.ran)
self.assertTrue(deploy)
self.assertFalse(stopC)
self.assertTrue(stopA)
self.assertTrue(stopA2)
self.assertTrue(stopB)
self.assertTrue(undeployAll)
def test_deployfails(self):
# fails reliably
old = self.cont.yamlPath
@@ -0,0 +1,23 @@
services:
testA:
image: ubuntu:${TAG:-jammy}
container_name: test_container_A
cap_drop:
- ALL
entrypoint: /bin/bash -c "sleep infinity"
healthcheck:
test: /bin/bash -c "true"
interval: 1s
timeout: 1s
retries: 1
testB:
image: ubuntu:${TAG:-jammy}
container_name: test_container_B
cap_drop:
- ALL
entrypoint: /bin/bash -c "sleep infinity"
healthcheck:
test: /bin/bash -c "true"
interval: 1s
timeout: 1s
retries: 1
+1
View File
@@ -20,6 +20,7 @@
- Build_Image
- Build_Run_Tests
- Deploy_Object
- Stop_Object
- Undeploy_Object
- Cppcheck_Analysis
- Deploy_Run_OC_PhySim
@@ -42,6 +42,13 @@
002006
444444
100002
100003
100004
100005
100006
100007
100008
100009
100001
222221
222222
@@ -95,10 +102,10 @@
<testCase id="000002">
<class>Deploy_Object</class>
<desc>Deploy OAI FlexRIC</desc>
<desc>Deploy OAI nearRT-RIC</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_flexric</yaml_path>
<services>oai-flexric</services>
<services>nearRT-RIC</services>
</testCase>
<testCase id="000003">
@@ -151,16 +158,72 @@
</testCase>
<testCase id="100002">
<class>Stop_Object</class>
<desc>Stop RC monitoring xApp</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_flexric</yaml_path>
<services>xapp-rc-moni</services>
</testCase>
<testCase id="100003">
<class>Stop_Object</class>
<desc>Stop KPM monitoring xApp</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_flexric</yaml_path>
<services>xapp-kpm-moni</services>
</testCase>
<testCase id="100004">
<class>Stop_Object</class>
<desc>Stop KPM monitoring and RC control xApp</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_flexric</yaml_path>
<services>xapp-kpm-rc</services>
</testCase>
<testCase id="100005">
<class>Stop_Object</class>
<desc>Stop custom SMs monitoring xApp</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_flexric</yaml_path>
<services>xapp-gtp-mac-rlc-pdcp-moni</services>
</testCase>
<testCase id="100006">
<class>Stop_Object</class>
<desc>Stop OAI UEs</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_flexric</yaml_path>
<services>oai-nr-ue oai-nr-ue2</services>
</testCase>
<testCase id="100007">
<class>Stop_Object</class>
<desc>Stop OAI gNB</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_flexric</yaml_path>
<services>oai-gnb</services>
</testCase>
<testCase id="100008">
<class>Stop_Object</class>
<desc>Stop nearRT-RIC</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_flexric</yaml_path>
<services>nearRT-RIC</services>
</testCase>
<testCase id="100009">
<class>Undeploy_Object</class>
<desc>Undeploy RAN and Flexric</desc>
<desc>Undeploy RAN and FlexRIC</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_flexric</yaml_path>
<always_exec>true</always_exec>
</testCase>
</testCase>
<testCase id="010000">
<class>Deploy_Object</class>
<desc>RC monitoring</desc>
<desc>Deploy RC monitoring</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_flexric</yaml_path>
<services>xapp-rc-moni</services>
@@ -168,7 +231,7 @@
<testCase id="010001">
<class>Deploy_Object</class>
<desc>KPM monitoring</desc>
<desc>Deploy KPM monitoring</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_flexric</yaml_path>
<services>xapp-kpm-moni</services>
@@ -176,7 +239,7 @@
<testCase id="010002">
<class>Deploy_Object</class>
<desc>KPM monitoring and RC control</desc>
<desc>Deploy KPM monitoring and RC control</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_flexric</yaml_path>
<services>xapp-kpm-rc</services>
@@ -184,7 +247,7 @@
<testCase id="010003">
<class>Deploy_Object</class>
<desc>Custom SMs monitoring</desc>
<desc>Deploy custom SMs monitoring</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_flexric</yaml_path>
<services>xapp-gtp-mac-rlc-pdcp-moni</services>
@@ -36,6 +36,11 @@
020003
030001
030002
050001
050002
050003
020001
020002
100001
222222
</TestCaseRequestedList>
@@ -139,12 +144,32 @@
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
<testCase id="050001">
<class>Custom_Command</class>
<desc>Trigger PDU Session Release via gNB telnet</desc>
<node>acamas</node>
<command>echo ci pdu_session_release 2 | ncat 192.168.71.140 9090</command>
</testCase>
<testCase id="050002">
<class>Custom_Command</class>
<desc>Add PDU Session via UE telnet</desc>
<node>acamas</node>
<command>echo ci add_pdu_session 6,7 | ncat 192.168.71.150 8091</command>
</testCase>
<testCase id="050003">
<class>Custom_Command</class>
<desc>Trigger PDU Session Release via gNB telnet</desc>
<node>acamas</node>
<command>echo ci pdu_session_release 6 | ncat 192.168.71.140 9090</command>
</testCase>
<testCase id="100001">
<class>Undeploy_Object</class>
<always_exec>true</always_exec>
<desc>Undeploy all OAI 5G stack</desc>
<node>localhost</node>
<services>oai-vnf oai-pnf</services>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_u0_25prb</yaml_path>
<d_retx_th>1,0,0,0</d_retx_th>
<u_retx_th>1,0,0,0</u_retx_th>
@@ -88,8 +88,8 @@
<testCase id="000022">
<class>Iperf</class>
<desc>iperf (DL/UDP/500M)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 500M -t 30 -R</iperf_args>
<desc>iperf (DL/UDP/800M)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 800M -t 30 -R</iperf_args>
<svr_id>oc-cn5g-20897-aerial</svr_id>
<id>up2-aerial</id>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
@@ -98,8 +98,8 @@
<testCase id="000033">
<class>Iperf</class>
<desc>iperf (UL/UDP/40M)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 40M -t 30 -l 1428</iperf_args>
<desc>iperf (UL/UDP/150M)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 150M -t 30 -l 1428</iperf_args>
<svr_id>oc-cn5g-20897-aerial</svr_id>
<id>up2-aerial</id>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
@@ -119,9 +119,9 @@
<testCase id="300033">
<class>Iperf</class>
<desc>Optional iperf (UL/UDP/90M)(30 sec)(single-ue profile)</desc>
<desc>Optional iperf (UL/UDP/200M)(30 sec)(single-ue profile)</desc>
<may_fail>true</may_fail>
<iperf_args>-u -b 90M -t 30 -l 1428</iperf_args>
<iperf_args>-u -b 200M -t 30 -l 1428</iperf_args>
<svr_id>oc-cn5g-20897-aerial</svr_id>
<id>up2-aerial</id>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
@@ -97,8 +97,8 @@
<testCase id="000032">
<class>Iperf</class>
<desc>iperf (UL/UDP/200M)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 200M -t 30 -l 1428</iperf_args>
<desc>iperf (UL/UDP/300M)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 300M -t 30 -l 1428</iperf_args>
<svr_id>oc-cn5g-20897-aerial</svr_id>
<id>up2-aerial</id>
<iperf_packetloss_threshold>10</iperf_packetloss_threshold>
@@ -107,9 +107,9 @@
<testCase id="000033">
<class>Iperf</class>
<desc>iperf (UL/UDP/220M)(30 sec)(single-ue profile)</desc>
<desc>iperf (UL/UDP/380M)(30 sec)(single-ue profile)</desc>
<may_fail>true</may_fail>
<iperf_args>-u -b 220M -t 30 -l 1428</iperf_args>
<iperf_args>-u -b 380M -t 30 -l 1428</iperf_args>
<svr_id>oc-cn5g-20897-aerial</svr_id>
<id>up2-aerial</id>
<iperf_packetloss_threshold>10</iperf_packetloss_threshold>
@@ -146,7 +146,6 @@
<desc>Undeploy gNB</desc>
<node>matix</node>
<yaml_path>ci-scripts/yaml_files/5g_sa_n310_2x2_100MHz</yaml_path>
<services>oai-gnb</services>
<d_retx_th>10,100,100,100</d_retx_th>
<u_retx_th>10,100,100,100</u_retx_th>
</testCase>
@@ -146,7 +146,6 @@
<desc>Undeploy gNB</desc>
<node>matix</node>
<yaml_path>ci-scripts/yaml_files/5g_sa_n310_2x2_60MHz</yaml_path>
<services>oai-gnb</services>
<d_retx_th>15,100,100,100</d_retx_th>
<u_retx_th>20,100,100,100</u_retx_th>
</testCase>
@@ -146,7 +146,6 @@
<desc>Undeploy VNF-PNF</desc>
<node>matix</node>
<yaml_path>ci-scripts/yaml_files/5g_sa_n310_4x4_60MHz</yaml_path>
<services>oai-vnf oai-pnf</services>
<d_retx_th>10,100,100,100</d_retx_th>
<u_retx_th>10,100,100,100</u_retx_th>
</testCase>
@@ -1,7 +1,7 @@
services:
oai-flexric:
nearRT-RIC:
image: ${REGISTRY-oaisoftwarealliance/}oai-flexric:${FLEXRIC_TAG:-develop}
container_name: oai-flexric
container_name: nearRT-RIC
networks:
public_net:
ipv4_address: 192.168.70.150
@@ -17,7 +17,7 @@ services:
command: "stdbuf -o0 /usr/local/flexric/xApp/c/monitor/xapp_rc_moni"
container_name: xapp-rc-moni
depends_on:
- oai-flexric
- nearRT-RIC
- oai-gnb
networks:
public_net:
@@ -34,7 +34,7 @@ services:
command: "stdbuf -o0 /usr/local/flexric/xApp/c/monitor/xapp_kpm_moni"
container_name: xapp-kpm-moni
depends_on:
- oai-flexric
- nearRT-RIC
- oai-gnb
networks:
public_net:
@@ -51,7 +51,7 @@ services:
command: "stdbuf -o0 /usr/local/flexric/xApp/c/kpm_rc/xapp_kpm_rc"
container_name: xapp-kpm-rc
depends_on:
- oai-flexric
- nearRT-RIC
- oai-gnb
networks:
public_net:
@@ -68,7 +68,7 @@ services:
command: "stdbuf -o0 /usr/local/flexric/xApp/c/monitor/xapp_gtp_mac_rlc_pdcp_moni"
container_name: xapp-gtp-mac-rlc-pdcp-moni
depends_on:
- oai-flexric
- nearRT-RIC
- oai-gnb
networks:
public_net:
@@ -88,7 +88,7 @@ services:
USE_ADDITIONAL_OPTIONS: -E --rfsim --log_config.global_log_options level,nocolor,time
ASAN_OPTIONS: detect_leaks=0
depends_on:
- oai-flexric
- nearRT-RIC
networks:
public_net:
ipv4_address: 192.168.70.151
@@ -97,8 +97,9 @@ services:
- ALL
environment:
USE_ADDITIONAL_OPTIONS: --nfapi VNF --log_config.global_log_options level,nocolor,time
--telnetsrv --telnetsrv.listenaddr 192.168.71.140 --telnetsrv.shrmod ci
NFAPI_TRACE_LEVEL: info
ASAN_OPTIONS: detect_leaks=0
ASAN_OPTIONS: detect_leaks=0:detect_odr_violation=0
depends_on:
- oai-ext-dn
networks:
@@ -122,7 +123,7 @@ services:
environment:
USE_ADDITIONAL_OPTIONS: --nfapi PNF --rfsim --log_config.global_log_options level,nocolor,time
NFAPI_TRACE_LEVEL: info
ASAN_OPTIONS: detect_leaks=0
ASAN_OPTIONS: detect_leaks=0:detect_odr_violation=0
depends_on:
- oai-vnf
networks:
@@ -147,7 +148,10 @@ services:
- NET_ADMIN # for interface bringup
- NET_RAW # for ping
environment:
USE_ADDITIONAL_OPTIONS: --rfsim -r 25 --numerology 0 --uicc0.imsi 208990100001100 --band 66 -C 2152680000 --CO -400000000 --ssb 48 --rfsimulator.serveraddr 192.168.71.141 --extra-pdu-id 2 --log_config.global_log_options level,nocolor,time
USE_ADDITIONAL_OPTIONS: --rfsim -r 25 --numerology 0 --uicc0.imsi 208990100001100 --band 66 -C 2152680000 --CO -400000000 --ssb 48
--rfsimulator.serveraddr 192.168.71.141 --extra-pdu-id 2 --log_config.global_log_options level,nocolor,time
--telnetsrv --telnetsrv.shrmod ciUE --telnetsrv.listenaddr 192.168.71.150 --telnetsrv.listenport 8091
ASAN_OPTIONS: detect_leaks=0:detect_odr_violation=0
depends_on:
- oai-pnf
networks:
+28 -17
View File
@@ -461,9 +461,15 @@ int register_log_component(const char *name, const char *fext, int compidx)
}
if (computed_compidx >= 0 && computed_compidx <MAX_LOG_COMPONENTS) {
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;
log_component_t *c = &g_log->log_component[computed_compidx];
c->name = strdup(name);
int n = snprintf(c->headerName, sizeof(c->headerName), "[%s", c->name);
if (n >= sizeof(c->headerName) - 1) // snprintf() truncated
n = sizeof(c->headerName) - 2;
c->headerName[n] = ']';
c->headerName[n + 1] = 0;
c->stream = stdout;
c->filelog = 0;
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);
@@ -509,12 +515,15 @@ int logInit (void)
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->filelog_name = "/tmp/openair.log";
log_getconfig(g_log);
for (int i = 0; log_level_names[i].name != NULL; i++)
if (g_log->flag & FLAG_LEVEL)
snprintf(g_log->level2string[i], sizeof g_log->level2string[i], " %c ", toupper(log_level_names[i].name[0]));
else
snprintf(g_log->level2string[i], sizeof g_log->level2string[i], " ");
// set all unused component items to 0, they are for non predefined components
for (int i=MAX_LOG_PREDEF_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
memset(&(g_log->log_component[i]),0,sizeof(log_component_t));
@@ -575,8 +584,7 @@ static inline int log_header(log_component_t *c,
struct tm utc_time;
if (gmtime_r(&t.tv_sec, &utc_time) == NULL)
abort();
snprintf(timeString, sizeof(timeString), "%04d-%02d-%02d %02d:%02d:%02d.%06lu UTC ",
utc_time.tm_year + 1900, utc_time.tm_mon + 1, utc_time.tm_mday,
snprintf(timeString, sizeof(timeString), "[%02d:%02d:%02d.%06lu] ",
utc_time.tm_hour, utc_time.tm_min, utc_time.tm_sec, t.tv_nsec / 1000);
} else {
snprintf(timeString, sizeof(timeString), "%lu.%06lu ",
@@ -593,15 +601,18 @@ static inline int log_header(log_component_t *c,
} else {
threadIdString[0] = 0;
}
return snprintf(log_buffer, buffsize, "%s%s%s[%s] %c %s%s",
flag & FLAG_NOCOLOR ? "" : log_level_highlight_start[level],
timeString,
threadIdString,
c->name,
flag & FLAG_LEVEL ? g_log->level2string[level] : ' ',
l,
threadname
);
return snprintf(log_buffer,
buffsize,
"%s%s%s%-8s%s%-*s%s",
flag & FLAG_NOCOLOR ? "" : log_level_highlight_start[level],
timeString,
threadIdString,
c->headerName,
g_log->level2string[level], // will print space if no level selected
l[0] == 0 ? 0 : 32,
l,
threadname);
}
void logRecord_mt(const char *file,
+2 -1
View File
@@ -206,6 +206,7 @@ typedef struct {
typedef struct {
const char *name;
char headerName[19];
int level;
int filelog;
FILE *stream;
@@ -217,7 +218,7 @@ typedef struct {
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];
char level2string[NUM_LOG_LEVEL][4];
int flag;
char *filelog_name;
debug_flags_t debug_mask;
+47 -13
View File
@@ -459,12 +459,50 @@ bool compare_relative_ul_channel_bw(int nr_band, int scs, int channel_bandwidth,
return rel_bw > limit;
}
uint16_t get_band(uint64_t downlink_frequency, int32_t delta_duplex)
static bool check_delta_duplex(int index, uint64_t dlfreq_khz, uint64_t ulfreq_khz, int64_t dlbw, int64_t ulbw)
{
int uldl_min_offset = nr_bandtable[index].dl_min - nr_bandtable[index].ul_min;
int txrx_offset = dlfreq_khz - ulfreq_khz;
LOG_I(NR_PHY, "dlfreq:%ld ulfreq:%ld deltaduplex:%d khz, uldl_min_offset:%d khz\n",
dlfreq_khz, ulfreq_khz, txrx_offset, uldl_min_offset);
if (txrx_offset == uldl_min_offset)
return true;
int band = nr_bandtable[index].band;
// Refer to section 5.4.4 in spec 38.101-5
if (band == 256 && txrx_offset >= 165000 && txrx_offset <= 215000)
return true;
if (band == 255 && txrx_offset >= -130500 && txrx_offset <= -72500)
return true;
if (band == 254 && txrx_offset >= 862000 && txrx_offset <= 885000)
return true;
// Refer to section 5.4.4 in spec 38.101-1 for these bands 24, 91-94, 109
if (band == 24 && (txrx_offset == -101500 || txrx_offset == -120500))
return true;
//Delta duplex is also a range for these bands n91-n94, n109.
if ((band >= 91 && band <= 94) || band == 109) {
dlbw = ((dlbw / 1000) + 1) * 1000;
ulbw = ((ulbw / 1000) + 1) * 1000;
int lower_limit = nr_bandtable[index].dl_min - nr_bandtable[index].ul_max + ((dlbw + ulbw) >> 1);
int upper_limit = nr_bandtable[index].dl_max - nr_bandtable[index].ul_min - ((dlbw + ulbw) >> 1);
LOG_I(NR_PHY, "Band %d dlbw:%ld Khz, ulbw: %ld Khz RXTX lower limit:%d khz, upper limit:%d khz\n",
band, dlbw, ulbw, lower_limit, upper_limit);
if (txrx_offset >= lower_limit && txrx_offset <= upper_limit)
return true;
}
return false;
}
uint16_t get_band(uint64_t downlink_frequency, int32_t delta_duplex, int64_t dlbw, int64_t ulbw)
{
const int64_t dl_freq_khz = downlink_frequency / 1000;
const int32_t delta_duplex_khz = delta_duplex / 1000;
const int64_t ul_freq_khz = dl_freq_khz + delta_duplex_khz;
uint64_t center_freq_diff_khz = UINT64_MAX; // 2^64
uint16_t current_band = 0;
for (int ind = 0; ind < sizeofArray(nr_bandtable); ind++) {
@@ -472,17 +510,13 @@ uint16_t get_band(uint64_t downlink_frequency, int32_t delta_duplex)
if (dl_freq_khz < nr_bandtable[ind].dl_min || dl_freq_khz > nr_bandtable[ind].dl_max)
continue;
int32_t current_offset_khz = nr_bandtable[ind].ul_min - nr_bandtable[ind].dl_min;
if (current_offset_khz != delta_duplex_khz)
if (ul_freq_khz < nr_bandtable[ind].ul_min || ul_freq_khz > nr_bandtable[ind].ul_max)
continue;
int64_t center_frequency_khz = (nr_bandtable[ind].dl_max + nr_bandtable[ind].dl_min) / 2;
if (!check_delta_duplex(ind, dl_freq_khz, ul_freq_khz, dlbw, ulbw))
continue;
if (labs(dl_freq_khz - center_frequency_khz) < center_freq_diff_khz){
current_band = nr_bandtable[ind].band;
center_freq_diff_khz = labs(dl_freq_khz - center_frequency_khz);
}
current_band = nr_bandtable[ind].band;
}
printf("DL frequency %"PRIu64": band %d, UL frequency %"PRIu64"\n",
@@ -541,8 +575,8 @@ int cce_to_reg_interleaving(const int R, int k, int n_shift, const int C, int L,
return f;
}
void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset) {
void get_coreset_rballoc(const uint8_t *FreqDomainResource, int *n_rb, int *rb_offset)
{
uint8_t count=0, start=0, start_set=0;
uint64_t bitmap = (((uint64_t)FreqDomainResource[0])<<37)|
@@ -565,7 +599,7 @@ void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset) {
}
// According to 38.211 7.3.2.2
int get_coreset_num_cces(uint8_t *FreqDomainResource, int duration)
int get_coreset_num_cces(const uint8_t *FreqDomainResource, int duration)
{
int num_rbs;
int rb_offset;
+3 -3
View File
@@ -280,12 +280,12 @@ uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, ui
int cce_to_reg_interleaving(const int R, int k, int n_shift, const int C, int L, const int N_regs);
int get_SLIV(uint8_t S, uint8_t L);
void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset);
int get_coreset_num_cces(uint8_t *FreqDomainResource, int duration);
void get_coreset_rballoc(const uint8_t *FreqDomainResource, int *n_rb, int *rb_offset);
int get_coreset_num_cces(const uint8_t *FreqDomainResource, int duration);
int get_nr_table_idx(int nr_bandP, uint8_t scs_index);
int32_t get_delta_duplex(int nr_bandP, uint8_t scs_index);
frame_type_t get_frame_type(uint16_t nr_bandP, uint8_t scs_index);
uint16_t get_band(uint64_t downlink_frequency, int32_t delta_duplex);
uint16_t get_band(uint64_t downlink_frequency, int32_t delta_duplex, int64_t dlbw, int64_t ulbw);
int NRRIV2BW(int locationAndBandwidth,int N_RB);
int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB);
int PRBalloc_to_locationandbandwidth0(int NPRB,int RBstart,int BWPsize);
+1 -1
View File
@@ -62,7 +62,7 @@ add_dependencies(telnetsrv telnetsrv_ci)
message(STATUS "Add CI specific telnet functions for nrUE in telnetsrv_ciUE.so")
add_library(telnetsrv_ciUE MODULE telnetsrv_ciUE.c)
target_link_libraries(telnetsrv_ciUE PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs UTIL)
target_link_libraries(telnetsrv_ciUE PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs UTIL NR_L2_UE nr_nas)
add_dependencies(telnetsrv telnetsrv_ciUE)
message(STATUS "Add bearer specific telnet functions in libtelnetsrv_bearer.so")
+82
View File
@@ -39,6 +39,7 @@
#include "openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h"
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
#include "openair2/RRC/NR/rrc_gNB_mobility.h"
#include "openair3/NGAP/ngap_gNB_ue_context.h"
#define TELNETSERVERCODE
#include "telnetsrv.h"
@@ -284,6 +285,86 @@ static int get_current_bwp(char *buf, int debug, telnet_printfunc_t prnt)
return 0;
}
/** @brief Trigger NGAP PDU Session Release for one or more PDU sessions associated with a UE ID/
* Syntax: trigger_pdu_session_release [ue_id=gNB_ue_ngap_id(int,opt)],pdusession_id(int)[,pdusession_id(int)...]
* - If the gNB_ue_ngap_id is omitted, it is fetched from the only UE present in the RRC layer
* - At least one valid PDU session ID must be provided
* @param[in] buf Comma-separated input string: [ue_id=gNB_ue_ngap_id(int,opt)],PDU1[,PDU2,...]
* @param[in] debug Not used.
* @param[in] prnt Callback for telnet output printing.
* @return 0 on success; negative value on error. */
static int trigger_ngap_pdu_session_release(char *buf, int debug, telnet_printfunc_t prnt)
{
if (buf == NULL) {
ERROR_MSG_RET("Missing input. Usage: trigger_pdu_session_release [ue_id=gNB_ue_ngap_id(int,opt)],pdusession_id(int)[,pdusession_id(int)...]\n");
}
char *tokens[NGAP_MAX_PDU_SESSION + 1];
int count = 0;
for (char *tok = strtok(buf, ","); tok != NULL && count < (int)sizeofArray(tokens); tok = strtok(NULL, ",")) {
tokens[count++] = tok;
}
if (count < 1) {
ERROR_MSG_RET("Invalid input. Usage: trigger_pdu_session_release [ue_id=gNB_ue_ngap_id(int,opt)],pdusession_id(int)[,pdusession_id(int)...]\n");
}
int gNB_ue_ngap_id = -1;
int pdu_start_index = 0;
if (strncmp(tokens[0], "ue_id=", 6) == 0) {
gNB_ue_ngap_id = atoi(tokens[0] + 6);
pdu_start_index = 1;
} else {
// No UE ID: infer it
if (!RC.nrrrc)
ERROR_MSG_RET("No RRC present\n");
rrc_gNB_ue_context_t *ue = get_single_rrc_ue();
if (!ue)
ERROR_MSG_RET("No single UE in RRC present\n");
gNB_ue_ngap_id = ue->ue_context.rrc_ue_id;
}
if (pdu_start_index >= count) {
ERROR_MSG_RET("No pdusession_id(int) provided\n");
}
ngap_gNB_ue_context_t *ngap = ngap_get_ue_context(gNB_ue_ngap_id);
if (!ngap) {
ERROR_MSG_RET("No NGAP UE context for gNB_ue_ngap_id %d\n", gNB_ue_ngap_id);
}
MessageDef *message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_PDUSESSION_RELEASE_COMMAND);
ngap_pdusession_release_command_t *msg = &NGAP_PDUSESSION_RELEASE_COMMAND(message_p);
memset(msg, 0, sizeof(*msg));
msg->amf_ue_ngap_id = ngap->amf_ue_ngap_id;
msg->gNB_ue_ngap_id = ngap->gNB_ue_ngap_id;
int nb_sessions = 0;
for (int i = pdu_start_index; i < count; ++i) {
int sid = atoi(tokens[i]);
if (sid < 1 || sid > 255) {
ERROR_MSG_RET("Invalid pdusession_id(int): %s (must be between 1 and 255)\n", tokens[i]);
}
msg->pdusession_release_params[nb_sessions++].pdusession_id = sid;
}
msg->nb_pdusessions_torelease = nb_sessions;
if (prnt) {
prnt("Triggering NGAP PDU Session Release for gNB_ue_ngap_id=%d: releasing pdusession_id=%d", gNB_ue_ngap_id);
for (int i = 0; i < nb_sessions; ++i) {
prnt(" %d,", msg->pdusession_release_params[i].pdusession_id);
}
prnt("\n");
}
itti_send_msg_to_task(TASK_RRC_GNB, 0, message_p);
return 0;
}
static telnetshell_cmddef_t cicmds[] = {
{"get_single_rnti", "", get_single_rnti},
{"force_reestab", "[rnti(hex,opt)]", trigger_reestab},
@@ -294,6 +375,7 @@ static telnetshell_cmddef_t cicmds[] = {
{"fetch_du_by_ue_id", "[rrc_ue_id(int,opt)]", fetch_du_by_ue_id},
{"get_current_bwp", "[rnti(hex,opt)]", get_current_bwp},
{"trigger_n2_ho", "[neighbour_pci(uint32_t),ueId(uint32_t)]", rrc_gNB_trigger_n2_ho},
{"pdu_session_release", "[gNB_ue_ngap_id(int,opt)]", trigger_ngap_pdu_session_release},
{"", "", NULL},
};
+44
View File
@@ -39,6 +39,7 @@
#include "openair2/RRC/NR_UE/rrc_proto.h"
#include "openair1/PHY/phy_extern_nr_ue.h"
#include "openair1/PHY/defs_nr_common.h"
#include "openair3/NAS/NR_UE/nr_nas_msg.h"
#define TELNETSERVERCODE
#include "telnetsrv.h"
@@ -52,6 +53,14 @@ const char* NR_UE_L2_STATE_STR[] = {
#undef UE_STATE
};
static int get_default_ue_id(void)
{
NR_UE_RRC_INST_t *rrc = get_NR_UE_rrc_inst(0);
if (!rrc)
return -1;
return rrc->ue_id;
}
/**
* Get the synchronization state of a UE.
*
@@ -132,6 +141,40 @@ static int get_dl_toa(char *buf, int debug, telnet_printfunc_t prnt)
return 0;
}
static int add_pdu_session(char *buf, int debug, telnet_printfunc_t prnt)
{
int ue_id = -1;
int pdusession_id = -1;
if (!buf) {
ERROR_MSG_RET("Missing argument: expected PDUSessionID[,UE_ID]\n");
}
// Try parsing values in the form: "PDUSessionID[,UE_ID]"
int n = sscanf(buf, "%d,%d", &pdusession_id, &ue_id);
if (n == 1) {
// Only PDUSessionID provided: use default UE ID
ue_id = get_default_ue_id();
if (ue_id < 0)
ERROR_MSG_RET("No default UE context found\n");
} else if (n != 2) {
ERROR_MSG_RET("Invalid format: expected PDUSessionID[,UE_ID]\n");
}
if (pdusession_id < 0 || pdusession_id > 255)
ERROR_MSG_RET("PDUSessionID must be in range [0,255]\n");
if (ue_id < 0)
ERROR_MSG_RET("UE_ID must be >= 0\n");
nr_ue_nas_t *nas = get_ue_nas_info(ue_id);
if (!nas)
ERROR_MSG_RET("No NAS context found for UE_ID %d\n", ue_id);
request_pdusession(nas, pdusession_id);
prnt("Triggered PDU session request for UE %d with ID %d\n", ue_id, pdusession_id);
return 0;
}
/* Telnet shell command definitions */
static telnetshell_cmddef_t cicmds[] = {
{"sync_state", "[UE_ID(int,opt)]", get_sync_state},
@@ -140,6 +183,7 @@ static telnetshell_cmddef_t cicmds[] = {
{"force_crnti_ra", "", force_crnti_ra},
{"deregistration", "", force_deregistration},
{"get_max_dl_toa", "[ant]", get_dl_toa},
{"add_pdu_session", "[PDUSessionID(int)],[UE_ID(int,opt)]", add_pdu_session},
{"", "", NULL},
};
+4 -4
View File
@@ -105,10 +105,10 @@ static int get_stats(char *buf, int debug, telnet_printfunc_t prnt)
int bw_index = get_supported_band_index(scs, fr, nrb);
int bw_mhz = get_supported_bw_mhz(fr, bw_index);
const mac_stats_t *stat = &mac->mac_stats;
static mac_stats_t last = {0};
int diff_used = stat->used_prb_aggregate - last.used_prb_aggregate;
int diff_total = stat->total_prb_aggregate - last.total_prb_aggregate;
const dlul_mac_stats_t *stat = &mac->mac_stats;
static dlul_mac_stats_t last = {0};
int diff_used = stat->dl.used_prb_aggregate - last.dl.used_prb_aggregate;
int diff_total = stat->dl.total_prb_aggregate - last.dl.total_prb_aggregate;
int load = diff_total > 0 ? 100 * diff_used / diff_total : 0;
last = *stat;
-5
View File
@@ -1916,8 +1916,6 @@ INPUT = \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/E1AP/e1ap_api.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/E1AP/e1ap_setup.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/E1AP/e1ap_asnc.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/NR_PHY_INTERFACE/nr_sched_response.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/NR_PHY_INTERFACE/nr_sched_response.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/NR_PHY_INTERFACE/NR_IF_Module.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/NR_PHY_INTERFACE/NR_IF_Module.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/SDAP/nr_sdap/nr_sdap.h \
@@ -2012,7 +2010,6 @@ INPUT = \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_TRANSPORT/nr_sss.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_TRANSPORT/nr_uci_tools_common.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_TRANSPORT/nr_prach.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_TRANSPORT/nr_scrambling.c \
@@ -2294,10 +2291,8 @@ INPUT = \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SCHED_NR/phy_frame_config_nr.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SCHED_NR/phy_frame_config_nr.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SCHED_NR/nr_prach_procedures.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SCHED_NR/fapi_nr_l1.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SCHED_NR/phy_procedures_nr_gNB.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SCHED_NR/sched_nr.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SCHED_NR/fapi_nr_l1.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/SCHED_NR/nr_ru_procedures.c \
@CMAKE_CURRENT_SOURCE_DIR@/../radio/ETHERNET/if_defs.h \
@CMAKE_CURRENT_SOURCE_DIR@/../radio/ETHERNET/ethernet_lib.h \
+33
View File
@@ -72,3 +72,36 @@ sequenceDiagram
u->>c: BEARER CONTEXT MODIFICATION RESPONSE
Note over c: e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_RESPONSE
```
## PDU Session Release
```mermaid
sequenceDiagram
participant AMF
participant CUCP
participant CUUP
participant DU
participant UE
AMF->>CUCP: NG PDU SESSION RESOURCE RELEASE COMMAND
Note over CUCP: ngap_gNB_handle_pdusession_release_command
CUCP->>CUCP: rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND
Note over CUCP: set status PDU_SESSION_STATUS_TORELEASE
CUCP->>CUUP: E1 Bearer Context Modification Request
Note over CUUP: release_gtpu_tunnel (GTP tunnel, PDCP, SDAP)
CUUP->>CUCP: E1 Bearer Context Modification Response
Note over CUCP: rrc_gNB_send_f1_drb_release_request
CUCP->>DU: F1 UE Context Modification Request
Note over DU: handle_ue_context_drbs_release (release in MAC/RLC)
DU->>CUCP: F1 UE Context Modification Response
Note over CUCP: rrc_CU_process_ue_context_modification_response
Note over CUCP: replace existing CellGroupConfig
Note over CUCP: rrc_gNB_generate_dedicatedRRCReconfiguration
CUCP->>UE: RRCReconfiguration (DRB release list, NAS PDU)
UE->>CUCP: RRCReconfigurationComplete
Note over CUCP: handle_rrcReconfigurationComplete
Note over CUCP: rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE
CUCP->>AMF: NG PDU SESSION RESOURCE RELEASE RESPONSE
Note over CUCP: rm_drbs_by_pdusession (from stored RRC list)
Note over CUCP: rm_pduSession (from stored RRC list)
```
+3 -3
View File
@@ -161,9 +161,9 @@ unpack function is called.
## P7 DL Transmission by VNF
DL messages are scheduled at the VNF, through gNB_dlsch_ulsch_scheduler(). gNB_dlsch_ulsch_scheduler() is called when
handling a SLOT.indication message in trigger_scheduler().
handling a SLOT.indication message in phy_nr_slot_indication().
The function trigger_scheduler(nfapi_nr_slot_indication_scf_t *slot_ind) calls the functions oai_nfapi_[DL P7 msg]_
The function phy_nr_slot_indication(nfapi_nr_slot_indication_scf_t *slot_ind) calls the functions oai_nfapi_[DL P7 msg]_
req(), calling in turn call the send_p7_msg function pointer, which contain the logic to pack the message into a buffer
and send it to the PNF.
Finally, NR_UL_indication is called to process the other P7 messages received from the PNF that were put in theire
@@ -215,7 +215,7 @@ bool nfapi_vnf_p7_tx_data_req(nfapi_vnf_p7_config_t* config, nfapi_nr_tx_data_re
graph TD
softmodem_start[nr-softmodem init] --> P5_configuration[configure_nr_nfapi_vnf] --> transport_init[Transport mechanism init] --> send_first_msg[Send first P5 message to PNF]
transport_init[Transport mechanism init] --> P5_recv_loop[P5 receive loop] -- P5 Message processing --> P5_recv_loop[P5 receive loop]
P5_recv_loop[P5 receive loop] -- Start.response callback called --> P7_config[P7 Configuration] --> P7_loop[P7 Loop] --> P7_msg_recv[P7 message received] --> call_vnf_handle_p7[Call vnf_nr_handle_p7_msg] --> hdr_unpack[Unpack header] --> call_specific_p7_handler[Call specific P7 message handler] --> slot_ind[Is a SLOT.indication?] -- Yes --> trig_scheduler[Call trigger_scheduler] --> gNB_ulsch_dlsch_sched[Call gNB_dlsch_ulsch_scheduler] --> send_p7_dl[Process and send P7 messages to PNF] --> call_ul_ind[Call NR_UL_indication] --> proc_p7[Process P7 messages in queue] --> P7_loop[P7 Loop]
P5_recv_loop[P5 receive loop] -- Start.response callback called --> P7_config[P7 Configuration] --> P7_loop[P7 Loop] --> P7_msg_recv[P7 message received] --> call_vnf_handle_p7[Call vnf_nr_handle_p7_msg] --> hdr_unpack[Unpack header] --> call_specific_p7_handler[Call specific P7 message handler] --> slot_ind[Is a SLOT.indication?] -- Yes --> trig_scheduler[Call phy_nr_slot_indication] --> gNB_ulsch_dlsch_sched[Call gNB_dlsch_ulsch_scheduler] --> send_p7_dl[Process and send P7 messages to PNF] --> call_ul_ind[Call NR_UL_indication] --> proc_p7[Process P7 messages in queue] --> P7_loop[P7 Loop]
slot_ind[Is a SLOT.indication?] -- No --> put_queue[Put message in queue] --> P7_loop[P7 Loop];
+94 -71
View File
@@ -1,74 +1,97 @@
This document is a high-level overview over the L1 threading mechanism.
```mermaid
flowchart TB
A[ru_thread] --> RFin>block rx_rf] --> feprx
feprx --> half-slot --> end_feprx
feprx --> second-thread -- block_end_feprx --> end_feprx>feprx]
end_feprx --> rx_nr_prach_ru
rx_nr_prach_ru -- block_queue_singleton --> resp_L1>resp L1]
resp_L1 -- async launch --> rx_func
resp_L1 -- immediate return --> RFin
subgraph rxfunc
rx_func_implem[rx_func]
subgraph rxfuncbeg
handle_nr_slot_ind
--> rnti_to_remove-mgmt
--> L1_nr_prach_procedures
--> apply_nr_rotation_RX
end
subgraph phy_procedures_gNB_uespec_RX
fill_ul_rb_mask
--> pucch(decode each gNB->pucch)
-->nr_fill_ul_indication
--> nr_ulsch_procedures
--> nr_ulsch_decoding
--> segInParallel[[all segments decode in parallel]]
--> barrier_end_of_ulsch_decoding
end
subgraph NR_UL_indication
handle_nr_rach
--> handle_nr_uci
--> handle_nr_ulsch
subgraph gNB_dlsch_ulsch_scheduler
run_pdcp
--> schedule_xxxx
end
handle_nr_ulsch --> gNB_dlsch_ulsch_scheduler
subgraph NR_Schedule_response
L1_tx_free3>L1_tx_free]
--> handle_nr_nfapi_xxx_pdu
--> sendTxFilled((L1_tx_filled))
--> nr_fill_ul_xxx
--> nr_schedule_rx_prach()
end
gNB_dlsch_ulsch_scheduler --> NR_Schedule_response
end
rx_func_implem --> rxfuncbeg
rxfuncbeg --> phy_procedures_gNB_uespec_RX
phy_procedures_gNB_uespec_RX --> NR_UL_indication
-- block_queue_block_PNF_monolithic --> L1_tx_free2>L1 tx filled]
-- async launch --> tx_func
L1_tx_free2 -- send_msg --> rsp((resp_L1))
end
rx_func --> rxfunc
subgraph tx_func
direction LR
subgraph phy_procedures_gNB_TX
dcitop[nr_generate dci top]
--> nr_generate_csi_rs
--> apply_nr_rotation_TX
-- send_msg --> end_tx_func((L1_tx_out))
end
subgraph tx_reorder_thread
L1_tx_out>L1_tx_out]
--> reorder{re order} --> reorder
reorder --> ru_tx_func
reorder --> L1_tx_free((L1_tx_free))
ru_tx_func --> feptx_prec
--> feptx_ofdm
end
end
ru_thread --> RFin[block rx_rf] --> UL{is UL slot?}
UL -- yes --> wait_free_rx_tti --> fep_rx --> rx_nr_prach_ru --> msg:L1_tx_out
UL -- no --> msg:L1_tx_out
msg:L1_tx_out -- asnyc launch --> L1_tx_thread
msg:L1_tx_out --> RFin
```
The main thread is `ru_thread()`. It blocks on reception of radio samples
(either time domain or frequency domain). In the case of an UL slot, it waits
that no more than N UL jobs are scheduled (via `wait_free_rx_tti()`, which
waits on queue `L1_rx_out`, cf. the RX L1 processing further below). Then:
- if the radio is time domain-based, it performs RX front-end processing (RX
FEP -> `fep_rx()`, i.e. DFT) to reach a frequency domain representation of
the RX signal, as well as does DFT for PRACH.
- if the radio is frequency domain-based, nothing is done.
Afterwards, it triggers TX processing by pushing a message into the FIFO queue
`L1_tx_out`, which asynchronously starts a TX job in `L1_tx_thread()` (see
below). After that, it blocks again on reception on the radio.
```mermaid
flowchart TB
L1_tx_thread --> TX_in[block L1_tx_out] --> NR_slot_indication
subgraph tx_func
NR_slot_indication --> msg:resp_L1 --> phy_procedures_gNB_tx --> ru_tx_func
NR_slot_indication["run the scheduler:
- monolithic: run_scheduler_monolithic()
- nFAPI: send indication via pnf_send_slot_ind()"]
msg:resp_L1 -- async launch --> L1_RX_thread
end
ru_tx_func --> TX_in
```
The `L1_tx_thread()` processes individual TX jobs sequentially, by waiting for
new messages on queue `L1_tx_out`, signalling individual TX jobs. For each
message, it calls `tx_func()` which does in order:
- run the scheduler through `NR_slot_indication`, which corresponds to a
"Slot.indication" in FAPI parlance. This runs the scheduler, and schedules a
given slot (either downlink, uplink, or both).
- trigger RX processing by pushing a message into the FIFO queue `resp_L1`,
asynchronously starting an RX job in `L1_rx_thread()` (see below).
- process the current L1 TX job through `phy_procedures_gNB_tx()`
- write to the radio board via `ru_tx_func()`.
After these steps, `tx_func()` return to `L1_tx_thread()`, which will wait for
the next TX job.
```mermaid
flowchart TB
L1_rx_thread --> RX_in[block resp_L1] --> L1_nr_prach_proc
subgraph rx_func
L1_nr_prach_proc --> phase_comp{apply phase comp.?}
phase_comp -- yes --> apply_nr_rotation --> phy_procedures_gNB_uespec_RX
phase_comp -- no --> phy_procedures_gNB_uespec_RX
phy_procedures_gNB_uespec_RX --> NR_ul_indication --> msg:L1_rx_out
NR_ul_indication["run the scheduler: NR_UL_indication()"]
msg:L1_rx_out -- async signal free --> ru_thread
end
msg:L1_rx_out --> RX_in
```
The `L1_rx_thread()` processes individual RX jobs sequentially. It waits for a
new RX job through the queue `resp_L1`, and then calls `rx_func()`, which does
in order:
- run PRACH processing via `L1_nr_prach_proc()`
- optionally apply rotation to the RX signal if phase compensation is to be
applied
- run the current L1 RX job through (`phy_procedures_gNB_uespec_RX()`), which
notably includes PUCCH, PUSCH, SRS processing
- call the scheduler through `NR_ul_indication()`, which corresponds to FAPI
uplink messages (e.g., `RX_data.indication`, `CRC.indication`,
`UCI.indication` etc.)
- signal completion via FIFO queue `L1_rx_out()`, which tells `ru_thread()`
that RX processing finished.
The signalling of scheduler data is done through a variable `UL_INFO`, which is
filled by `L1_nr_prach_proc()` (for PRACH) and `phy_procedures_gNB_uespec_RX()`
(for PUCCH, PUSCH, SRS).
After these steps, `rx_func()` returns to `L1_rx_thread()`, which will wait the
next RX job.
Note that while individual TX (RX) jobs are run sequentially through
`L1_tx_thread()` (`L1_rx_thread()`), both TX and RX processing run in
parallel.
+1 -1
View File
@@ -177,7 +177,7 @@ it would be better to call **NR_UL_indication()** now instead of before (on prev
* nr_common_signal_procedures()
generate common signals
{: .func4}
* nr_generate_dci_top()
* nr_generate_dci()
generate DCI: the scheduling informtion for each UE in both DL and UL
{: .func4}
* nr_generate_pdsch()
+2 -2
View File
@@ -242,10 +242,10 @@ To see the (any) periodical output at the PNF, define `NFAPI_TRACE_LEVEL=info`.
This output shows:
```
41056.739654 [I] 3556767424: pnf_p7_slot_ind: [P7:1] msgs ontime 489 thr DL 0.06 UL 0.01 msg late 0 (vtime)
41056.739654 [I] 3556767424: nr_pnf_p7_get_msgs: [P7:1] msgs ontime 489 thr DL 0.06 UL 0.01 msg late 0 (vtime)
```
The first numbers are timestamps. `pnf_p7_slot_ind` is the name of the
The first numbers are timestamps. `nr_pnf_p7_get_msgs` is the name of the
functions that prints the output. `[P7:1]` refers to the fact that these are
information on P7, of PHY ID 1. Finally, `msgs ontime 489` means that in the
last window (since the last print), 489 messages arrived at the PNF in total.
-6
View File
@@ -194,13 +194,7 @@ void handle_nr_srs_measurements(const module_id_t module_id,
void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]);
/* TODO these declarations are to be removed */
void nr_schedule_dl_tti_req(void) {};
void nr_schedule_ul_dci_req() {};
void nr_schedule_tx_req() {};
void nr_schedule_ul_tti_req() {};
void nr_slot_select() {};
void NR_UL_indication(NR_UL_IND_t *UL_INFO) {};
void gNB_dlsch_ulsch_scheduler() {};
/*------------------------------------------------------------------------*/
-4
View File
@@ -156,10 +156,6 @@ extern char uecap_xer[1024];
char uecap_xer_in=0;
/* TODO these declarations are to be removed */
void nr_schedule_dl_tti_req(void) {};
void nr_schedule_ul_dci_req() {};
void nr_schedule_tx_req() {};
void nr_schedule_ul_tti_req() {};
void nr_slot_select() {};
/* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed
+3 -2
View File
@@ -51,8 +51,9 @@ static void initialize_agent(ngran_node_t node_type, e2_agent_args_t oai_args)
printf("After RCconfig_NR_E2agent %s %s \n",oai_args.sm_dir, oai_args.ip );
fr_args_t args = { .ip = oai_args.ip }; // init_fr_args(0, NULL);
memcpy(args.libs_dir, oai_args.sm_dir, 128);
fr_args_t args = {0};
memcpy(args.ip, oai_args.ip, FR_IP_ADDRESS_LEN);
memcpy(args.libs_dir, oai_args.sm_dir, FR_CONF_FILE_LEN);
sleep(1);
+17 -27
View File
@@ -55,7 +55,6 @@
#include "PHY/defs_gNB.h"
#include "PHY/defs_nr_common.h"
#include "PHY/impl_defs_nr.h"
#include "SCHED_NR/fapi_nr_l1.h"
#include "SCHED_NR/phy_frame_config_nr.h"
#include "SCHED_NR/sched_nr.h"
#include "assertions.h"
@@ -65,7 +64,6 @@
#include "nfapi/oai_integration/vendor_ext.h"
#include "nfapi_nr_interface_scf.h"
#include "notified_fifo.h"
#include "openair2/NR_PHY_INTERFACE/nr_sched_response.h"
#include "thread-pool.h"
#include "time_meas.h"
#include "utils.h"
@@ -82,8 +80,6 @@ static void tx_func(processingData_L1tx_t *info)
int slot_rx = info->slot_rx;
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;
uint8_t CC_id = gNB->CC_id;
NR_IF_Module_t *ifi = gNB->if_inst;
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
@@ -94,15 +90,22 @@ static void tx_func(processingData_L1tx_t *info)
reset_active_ulsch(gNB, frame_rx);
}
clear_slot_beamid(gNB, slot_tx);
nfapi_nr_slot_indication_scf_t ind = {.sfn = frame_tx, .slot = slot_tx};
start_meas(&gNB->slot_indication_stats);
ifi->NR_slot_indication(module_id, CC_id, frame_tx, slot_tx);
// this variable is very big (multiple MB), so we put it into static storage
// to not overflow the stack while still having it in local (function) scope
// also, tx_func() is only executed by one thread, serially
static NR_Sched_Rsp_t sched_response;
ifi->NR_slot_indication(&ind, &sched_response);
stop_meas(&gNB->slot_indication_stats);
gNB->msgDataTx->timestamp_tx = info->timestamp_tx;
info = gNB->msgDataTx;
info->gNB = gNB;
// At this point, MAC scheduler just ran, including scheduling
// PRACH/PUCCH/PUSCH, so trigger RX chain processing
nr_save_ul_tti_req(gNB, &sched_response.UL_tti_req);
LOG_D(NR_PHY, "Trigger RX for %d.%d\n", frame_rx, slot_rx);
notifiedFIFO_elt_t *res = newNotifiedFIFO_elt(sizeof(processingData_L1_t), 0, &gNB->resp_L1, NULL);
processingData_L1_t *syncMsg = NotifiedFifoData(res);
@@ -119,7 +122,13 @@ static void tx_func(processingData_L1tx_t *info)
if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT || get_softmodem_params()->continuous_tx || IS_SOFTMODEM_RFSIM
|| cfg->analog_beamforming_ve.analog_beam_list) {
start_meas(&info->gNB->phy_proc_tx);
phy_procedures_gNB_TX(info, frame_tx, slot_tx, 1);
phy_procedures_gNB_TX(info->gNB,
&sched_response.DL_req,
&sched_response.TX_req,
&sched_response.UL_dci_req,
frame_tx,
slot_tx,
1);
PHY_VARS_gNB *gNB = info->gNB;
processingData_RU_t syncMsgRU;
@@ -131,14 +140,6 @@ static void tx_func(processingData_L1tx_t *info)
ru_tx_func((void *)&syncMsgRU);
stop_meas(&info->gNB->phy_proc_tx);
}
if (NFAPI_MODE == NFAPI_MONOLITHIC) {
/* this thread is done with the sched_info, decrease the reference counter.
* This only applies for monolithic; in the PNF, the memory is allocated in
* a ring buffer that should never be overwritten (one frame duration). */
LOG_D(NR_PHY, "Calling deref_sched_response for id %d (tx_func) in %d.%d\n", info->sched_response_id, frame_tx, slot_tx);
deref_sched_response(info->sched_response_id);
}
}
void *L1_rx_thread(void *arg)
@@ -248,7 +249,6 @@ static size_t dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output, size
output += print_meas_log(&gNB->ul_indication_stats, "UL Indication", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->slot_indication_stats, "Slot Indication", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->rx_pusch_stats, "PUSCH inner-receiver", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->schedule_response_stats, "Schedule Response", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->rx_prach, "PRACH RX", NULL, NULL, output, end - output);
if (ru->feprx)
output += print_meas_log(&ru->ofdm_demod_stats, "feprx", NULL, NULL, output, end - output);
@@ -310,7 +310,6 @@ void *nrL1_stats_thread(void *param) {
reset_meas(&gNB->ul_indication_stats);
reset_meas(&gNB->slot_indication_stats);
reset_meas(&gNB->rx_pusch_stats);
reset_meas(&gNB->schedule_response_stats);
reset_meas(&gNB->dlsch_scrambling_stats);
reset_meas(&gNB->dlsch_modulation_stats);
reset_meas(&gNB->dlsch_resource_mapping_stats);
@@ -358,14 +357,6 @@ void init_gNB_Tpool(int inst)
// create the TX thread responsible for TX processing start event (L1_tx_out msg queue), then launch tx_func()
threadCreate(&gNB->L1_tx_thread, L1_tx_thread, (void *)gNB, "L1_tx_thread", gNB->L1_tx_thread_core, OAI_PRIORITY_RT_MAX);
notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t), 0, &gNB->L1_tx_out, NULL);
processingData_L1tx_t *msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx);
memset(msgDataTx, 0, sizeof(processingData_L1tx_t));
init_DLSCH_struct(gNB, msgDataTx);
memset(msgDataTx->ssb, 0, 64 * sizeof(NR_gNB_SSB_t));
// this will be removed when the msgDataTx is not necessary anymore
gNB->msgDataTx = msgDataTx;
if (!IS_SOFTMODEM_NOSTATS)
threadCreate(&proc->L1_stats_thread, nrL1_stats_thread, (void *)gNB, "L1_stats", -1, OAI_PRIORITY_RT_LOW);
}
@@ -442,7 +433,6 @@ void init_gNB()
AssertFatal((gNB->if_inst = NR_IF_Module_init(inst)) != NULL, "Cannot register interface");
LOG_I(NR_PHY, "Registered with MAC interface module (%p)\n", gNB->if_inst);
gNB->if_inst->NR_Schedule_response = nr_schedule_response;
gNB->if_inst->NR_PHY_config_req = nr_phy_config_request;
gNB->prach_energy_counter = 0;
+3 -4
View File
@@ -423,8 +423,6 @@ int start_L1L2(module_id_t gnb_id)
/* block threads */
oai_exit = 0;
sync_var = -1;
extern void init_sched_response(void);
init_sched_response();
/* update config */
gNB_MAC_INST *mac = RC.nrmac[0];
@@ -473,8 +471,9 @@ static void initialize_agent(ngran_node_t node_type, e2_agent_args_t oai_args)
printf("After RCconfig_NR_E2agent %s %s \n",oai_args.sm_dir, oai_args.ip );
fr_args_t args = { .ip = oai_args.ip }; // init_fr_args(0, NULL);
memcpy(args.libs_dir, oai_args.sm_dir, 128);
fr_args_t args = {0};
memcpy(args.ip, oai_args.ip, FR_IP_ADDRESS_LEN);
memcpy(args.libs_dir, oai_args.sm_dir, FR_CONF_FILE_LEN);
sleep(1);
const gNB_RRC_INST* rrc = RC.nrrrc[0];
+13 -62
View File
@@ -55,7 +55,6 @@
#include "PHY/INIT/phy_init.h"
#include "PHY/INIT/nr_phy_init.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
#include "openair1/SCHED_NR/fapi_nr_l1.h"
#include "openair1/PHY/NR_TRANSPORT/nr_dlsch.h"
#include "openair1/PHY/defs_gNB.h"
#include <openair1/SCHED/fapi_l1.h>
@@ -1108,17 +1107,6 @@ void pnf_nr_phy_deallocate_p7_vendor_ext(void *header)
free(header);
}
extern void nr_schedule_ul_dci_req(PHY_VARS_gNB *gNB, nfapi_nr_ul_dci_request_t *UL_dci_req);
int pnf_phy_ul_dci_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_nr_ul_dci_request_t *req)
{
DevAssert(RC.gNB != NULL && RC.gNB[0] != NULL);
PHY_VARS_gNB *gNB = RC.gNB[0]; // phy_inst?
nr_schedule_ul_dci_req(gNB, req);
return 0;
}
int pnf_phy_hi_dci0_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_hi_dci0_request_t *req) {
if (req->hi_dci0_request_body.number_of_dci == 0 && req->hi_dci0_request_body.number_of_hi == 0)
@@ -1149,21 +1137,6 @@ int pnf_phy_hi_dci0_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfa
}
// from dl_tti_req_fn fptr
extern void nr_schedule_dl_tti_req(PHY_VARS_gNB *gNB, nfapi_nr_dl_tti_request_t *DL_req);
int pnf_phy_dl_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_nr_dl_tti_request_t *DL_req)
{
DevAssert(proc == NULL);
DevAssert(sync_var == 0);
DevAssert(RC.gNB != NULL && RC.gNB[0] != NULL);
PHY_VARS_gNB *gNB = RC.gNB[0]; // phy_inst?
nr_schedule_dl_tti_req(gNB, DL_req);
return 0;
}
int pnf_phy_dl_config_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_dl_config_request_t *req) {
if (RC.eNB == 0) {
@@ -1256,18 +1229,6 @@ int pnf_phy_dl_config_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, n
}
extern void nr_schedule_tx_req(PHY_VARS_gNB *gNB, nfapi_nr_tx_data_request_t *TX_req);
int pnf_phy_tx_data_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_nr_tx_data_request_t *req)
{
DevAssert(RC.gNB != NULL && RC.gNB[0] != NULL);
PHY_VARS_gNB *gNB = RC.gNB[0]; // phy_inst?
nr_schedule_tx_req(gNB, req);
return 0;
}
int pnf_phy_tx_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_tx_request_t *req) {
uint16_t sfn = NFAPI_SFNSF2SFN(req->sfn_sf);
uint16_t sf = NFAPI_SFNSF2SF(req->sfn_sf);
@@ -1293,16 +1254,6 @@ int pnf_phy_tx_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_tx_request_t *req) {
return 0;
}
extern void nr_schedule_ul_tti_req(PHY_VARS_gNB *gNB, nfapi_nr_ul_tti_request_t *UL_tti_req);
int pnf_phy_ul_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_nr_ul_tti_request_t *req)
{
DevAssert(RC.gNB != NULL && RC.gNB[0] != NULL);
PHY_VARS_gNB *gNB = RC.gNB[0]; // phy_inst?
nr_schedule_ul_tti_req(gNB, req);
return 0;
}
int pnf_phy_ul_config_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_ul_config_request_t *req) {
if (0)LOG_D(PHY,"[PNF] UL_CONFIG_REQ %s() sfn_sf:%d pdu:%d rach_prach_frequency_resources:%d srs_present:%u\n",
__FUNCTION__,
@@ -1711,10 +1662,10 @@ int nr_start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nf
}
// NR
p7_config->dl_tti_req_fn = &pnf_phy_dl_tti_req;
p7_config->ul_tti_req_fn = &pnf_phy_ul_tti_req;
p7_config->ul_dci_req_fn = &pnf_phy_ul_dci_req;
p7_config->tx_data_req_fn = &pnf_phy_tx_data_req;
p7_config->dl_tti_req_fn = NULL;
p7_config->ul_tti_req_fn = NULL;
p7_config->ul_dci_req_fn = NULL;
p7_config->tx_data_req_fn = NULL;
// LTE
p7_config->dl_config_req = &pnf_phy_dl_config_req;
@@ -1825,13 +1776,6 @@ int nr_start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nf
nfapi_nr_send_pnf_start_resp(config, p7_config->phy_id);
printf("[PNF] Sending first P7 slot indication\n");
#endif
#if 1
nfapi_pnf_p7_slot_ind(p7_config, p7_config->phy_id, 0, 0);
printf("[PNF] Sent first P7 slot ind\n");
#else
nfapi_pnf_p7_subframe_ind(p7_config, p7_config->phy_id, 0); // SFN_SF set to zero - correct???
printf("[PNF] Sent first P7 subframe ind\n");
#endif
return 0;
}
@@ -2321,7 +2265,7 @@ static void maybe_slow_down_pnf(int mu)
last_execution = current_execution;
}
void handle_nr_slot_ind(uint16_t sfn, uint16_t slot)
void handle_nr_slot_ind(uint16_t sfn, uint16_t slot, NR_Sched_Rsp_t *sched_resp)
{
nfapi_pnf_p7_config_t *config = p7_config_g;
pnf_p7_t *_this = (pnf_p7_t *)(config);
@@ -2352,7 +2296,14 @@ void handle_nr_slot_ind(uint16_t sfn, uint16_t slot)
oai_nfapi_nr_slot_indication(&ind);
// copy data from appropriate p7 slot buffers into channel structures for PHY processing
nfapi_pnf_p7_slot_ind(config, config->phy_id, sfn, slot);
nfapi_pnf_p7_get_msgs(config,
config->phy_id,
sfn,
slot,
&sched_resp->DL_req,
&sched_resp->UL_tti_req,
&sched_resp->UL_dci_req,
&sched_resp->TX_req);
return;
}
+2 -1
View File
@@ -28,7 +28,8 @@ void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr,
void configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);
void oai_subframe_ind(uint16_t sfn, uint16_t sf);
void handle_nr_slot_ind(uint16_t sfn, uint16_t slot);
struct NR_Sched_Rsp;
void handle_nr_slot_ind(uint16_t sfn, uint16_t slot, struct NR_Sched_Rsp *resp);
void sfnslot_add_slot(int mu, uint16_t *sfn, uint16_t *slot, int offset);
int oai_nfapi_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind);
+50 -140
View File
@@ -124,7 +124,6 @@ int vnf_nr_unpack_vendor_extension_tlv(nfapi_tl_t *tl,
{
return -1;
}
void install_nr_schedule_handlers(NR_IF_Module_t *if_inst);
void install_schedule_handlers(IF_Module_t *if_inst);
extern int sf_ahead;
@@ -326,71 +325,6 @@ int pnf_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_config_
return 0;
}
int wake_gNB_rxtx(PHY_VARS_gNB *gNB, uint16_t sfn, uint16_t slot) {
struct timespec curr_t;
clock_gettime(CLOCK_MONOTONIC,&curr_t);
//NFAPI_TRACE(NFAPI_TRACE_INFO, "\n wake_gNB_rxtx before assignment sfn:%d slot:%d TIME %d.%d",sfn,slot,curr_t.tv_sec,curr_t.tv_nsec);
gNB_L1_proc_t *proc=&gNB->proc;
gNB_L1_rxtx_proc_t *L1_proc= (slot&1)? &proc->L1_proc : &proc->L1_proc_tx;
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(eNB:%p, sfn:%d, sf:%d)\n", __FUNCTION__, eNB, sfn, sf);
//int i;
struct timespec wait;
clock_gettime(CLOCK_REALTIME, &wait);
wait.tv_sec = 0;
wait.tv_nsec +=5000L;
//wait.tv_nsec = 0;
// wake up TX for subframe n+sf_ahead
// lock the TX mutex and make sure the thread is ready
AssertFatal(gNB->if_inst->sl_ahead==6,"gNB->if_inst->sl_ahead %d : This is hard-coded to 6 in nfapi P7!!!\n",gNB->if_inst->sl_ahead);
if (pthread_mutex_timedlock(&L1_proc->mutex,&wait) != 0) {
LOG_E( PHY, "[gNB] ERROR pthread_mutex_lock for gNB RXTX thread %d (IC %d)\n", L1_proc->slot_rx&1,L1_proc->instance_cnt );
exit_fun( "error locking mutex_rxtx" );
return(-1);
}
{
static uint16_t old_slot = 0;
static uint16_t old_sfn = 0;
proc->slot_rx = old_slot;
proc->frame_rx = old_sfn;
// Try to be 1 frame back
old_slot = slot;
old_sfn = sfn;
//NFAPI_TRACE(NFAPI_TRACE_INFO, "\n wake_gNB_rxtx after assignment sfn:%d slot:%d",proc->frame_rx,proc->slot_rx);
if (old_slot == 0 && old_sfn % 100 == 0) LOG_W( PHY,"[gNB] sfn/slot:%d%d old_sfn/slot:%d%d proc[rx:%d%d]\n", sfn, slot, old_sfn, old_slot, proc->frame_rx, proc->slot_rx);
}
++L1_proc->instance_cnt;
//LOG_D( PHY,"[VNF-subframe_ind] sfn/sf:%d:%d proc[frame_rx:%d subframe_rx:%d] L1_proc->instance_cnt_rxtx:%d \n", sfn, sf, proc->frame_rx, proc->subframe_rx, L1_proc->instance_cnt_rxtx);
// We have just received and processed the common part of a subframe, say n.
// TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired
// transmitted timestamp of the next TX slot (first).
// The last (TS_rx mod samples_per_frame) was n*samples_per_tti,
// we want to generate subframe (n+N), so TS_tx = TX_rx+N*samples_per_tti,
// and proc->subframe_tx = proc->subframe_rx+sf_ahead
L1_proc->timestamp_tx = proc->timestamp_rx + (gNB->if_inst->sl_ahead *fp->samples_per_subframe);
L1_proc->frame_rx = proc->frame_rx;
L1_proc->slot_rx = proc->slot_rx;
L1_proc->frame_tx = (L1_proc->slot_rx > (19-gNB->if_inst->sl_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
L1_proc->slot_tx = (L1_proc->slot_rx + gNB->if_inst->sl_ahead)%20;
//LOG_D(PHY, "sfn/sf:%d%d proc[rx:%d%d] rx:%d%d] About to wake rxtx thread\n\n", sfn, slot, proc->frame_rx, proc->slot_rx, L1_proc->frame_rx, L1_proc->slot_rx);
//NFAPI_TRACE(NFAPI_TRACE_INFO, "\nEntering wake_gNB_rxtx sfn %d slot %d\n",L1_proc->frame_rx,L1_proc->slot_rx);
// the thread can now be woken up
if (pthread_cond_signal(&L1_proc->cond) != 0) {
LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB RXn-TXnp4 thread\n");
exit_fun( "ERROR pthread_clond_signal" );
return(-1);
}
//LOG_D(PHY,"%s() About to attempt pthread_mutex_unlock\n", __FUNCTION__);
pthread_mutex_unlock( &L1_proc->mutex );
//LOG_D(PHY,"%s() UNLOCKED pthread_mutex_unlock\n", __FUNCTION__);
return(0);
}
int wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf) {
L1_proc_t *proc=&eNB->proc;
L1_rxtx_proc_t *L1_proc= (sf&1)? &proc->L1_proc : &proc->L1_proc_tx;
@@ -498,28 +432,6 @@ int phy_sync_indication(struct nfapi_vnf_p7_config *config, uint8_t sync) {
}
int phy_slot_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, uint16_t sfn, uint16_t slot) {
static uint8_t first_time = 1;
if (first_time) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] slot indication %d.%d\n", sfn, slot);
first_time = 0;
}
if (RC.gNB && RC.gNB[0]->configured) {
// uint16_t sfn = NFAPI_SFNSF2SFN(sfn_sf);
// uint16_t sf = NFAPI_SFNSF2SF(sfn_sf);
LOG_D(PHY,"[VNF] slot indication sfn:%d slot:%d\n", sfn, slot);
wake_gNB_rxtx(RC.gNB[0], sfn, slot); // DONE: find NR equivalent
} else {
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s() RC.gNB:%p\n", __FUNCTION__, RC.gNB);
if (RC.gNB) NFAPI_TRACE(NFAPI_TRACE_INFO, "RC.gNB[0]->configured:%d\n", RC.gNB[0]->configured);
}
return 0;
}
int phy_subframe_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, uint16_t sfn_sf) {
static uint8_t first_time = 1;
@@ -971,65 +883,63 @@ int phy_cqi_indication(struct nfapi_vnf_p7_config *config, nfapi_cqi_indication_
//NR phy indication
NR_Sched_Rsp_t g_sched_resp;
void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, slot_t slot, NR_Sched_Rsp_t* sched_info);
int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req);
int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req);
int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t* tx_data_req);
int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t* ul_dci_req);
int trigger_scheduler(nfapi_nr_slot_indication_scf_t *slot_ind)
{
// Call into the scheduler (this is hardcoded and should be init properly!)
// memset(sched_resp, 0, sizeof(*sched_resp));
gNB_dlsch_ulsch_scheduler(0, slot_ind->sfn, slot_ind->slot, &g_sched_resp);
#ifdef ENABLE_AERIAL
bool send_slt_resp = false;
if (g_sched_resp.DL_req.dl_tti_request_body.nPDUs> 0) {
oai_fapi_dl_tti_req(&g_sched_resp.DL_req);
send_slt_resp = true;
}
if (g_sched_resp.UL_tti_req.n_pdus > 0) {
oai_fapi_ul_tti_req(&g_sched_resp.UL_tti_req);
send_slt_resp = true;
}
if (g_sched_resp.TX_req.Number_of_PDUs > 0) {
oai_fapi_tx_data_req(&g_sched_resp.TX_req);
send_slt_resp = true;
}
if (g_sched_resp.UL_dci_req.numPdus > 0) {
oai_fapi_ul_dci_req(&g_sched_resp.UL_dci_req);
send_slt_resp = true;
}
if (send_slt_resp) {
oai_fapi_send_end_request(0,slot_ind->sfn, slot_ind->slot);
}
#else
if (g_sched_resp.DL_req.dl_tti_request_body.nPDUs > 0)
oai_nfapi_dl_tti_req(&g_sched_resp.DL_req);
if (g_sched_resp.UL_tti_req.n_pdus > 0)
oai_nfapi_ul_tti_req(&g_sched_resp.UL_tti_req);
if (g_sched_resp.TX_req.Number_of_PDUs > 0)
oai_nfapi_tx_data_req(&g_sched_resp.TX_req);
if (g_sched_resp.UL_dci_req.numPdus > 0)
oai_nfapi_ul_dci_req(&g_sched_resp.UL_dci_req);
#endif
NR_UL_IND_t ind = {.frame = slot_ind->sfn, .slot = slot_ind->slot, };
NR_UL_indication(&ind);
return 1;
}
int phy_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind)
{
LOG_D(MAC, "VNF SFN/Slot %d.%d \n", ind->sfn, ind->slot);
trigger_scheduler(ind);
// this variable is very big (multiple MB), so we put it into static storage
// to not overflow the stack while still having it in local (function) scope
// also, phy_nr_slot_indication() is only executed by one thread, serially
static NR_Sched_Rsp_t sched_response;
NR_IF_Module_t *ifi = RC.nrmac[0]->if_inst;
ifi->NR_slot_indication(ind, &sched_response);
#ifdef ENABLE_AERIAL
bool send_slt_resp = false;
if (sched_response.DL_req.dl_tti_request_body.nPDUs> 0) {
oai_fapi_dl_tti_req(&sched_response.DL_req);
send_slt_resp = true;
}
if (sched_response.UL_tti_req.n_pdus > 0) {
oai_fapi_ul_tti_req(&sched_response.UL_tti_req);
send_slt_resp = true;
}
if (sched_response.TX_req.Number_of_PDUs > 0) {
oai_fapi_tx_data_req(&sched_response.TX_req);
send_slt_resp = true;
}
if (sched_response.UL_dci_req.numPdus > 0) {
oai_fapi_ul_dci_req(&sched_response.UL_dci_req);
send_slt_resp = true;
}
if (send_slt_resp) {
oai_fapi_send_end_request(0, ind->sfn, ind->slot);
}
#else
if (sched_response.DL_req.dl_tti_request_body.nPDUs > 0)
oai_nfapi_dl_tti_req(&sched_response.DL_req);
if (sched_response.UL_tti_req.n_pdus > 0)
oai_nfapi_ul_tti_req(&sched_response.UL_tti_req);
if (sched_response.TX_req.Number_of_PDUs > 0)
oai_nfapi_tx_data_req(&sched_response.TX_req);
if (sched_response.UL_dci_req.numPdus > 0)
oai_nfapi_ul_dci_req(&sched_response.UL_dci_req);
#endif
/* the below works because the function behind the callback collects
* messages from queue into which messages have been copied.
* TODO we should have different callbacks for received messages and call
* into the scheduler separately for each message instead of one big one. */
NR_UL_IND_t ul_ind = {.frame = ind->sfn, .slot = ind->slot, };
ifi->NR_UL_indication(&ul_ind);
return 1;
}
@@ -1305,7 +1215,7 @@ void *configure_nr_p7_vnf(void *ptr)
p7_vnf->config->port = p7_vnf->local_port;
#ifndef ENABLE_AERIAL
p7_vnf->config->sync_indication = &phy_sync_indication;
p7_vnf->config->slot_indication = &phy_slot_indication;
p7_vnf->config->slot_indication = NULL;
p7_vnf->config->harq_indication = &phy_harq_indication;
#endif
p7_vnf->config->nr_crc_indication = &phy_nr_crc_indication;
@@ -1367,7 +1277,7 @@ void *vnf_p7_thread_start(void *ptr) {
p7_vnf->config->port = p7_vnf->local_port;
p7_vnf->config->sync_indication = &phy_sync_indication;
p7_vnf->config->subframe_indication = &phy_subframe_indication;
p7_vnf->config->slot_indication = &phy_slot_indication;
p7_vnf->config->slot_indication = NULL;
p7_vnf->config->harq_indication = &phy_harq_indication;
p7_vnf->config->crc_indication = &phy_crc_indication;
+8 -2
View File
@@ -145,8 +145,14 @@ int pnf_nr_p7_message_pump(pnf_p7_t* pnf_p7);
int pnf_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t* msg, uint32_t msg_len);
int pnf_p7_send_message(pnf_p7_t* pnf_p7, uint8_t* msg, uint32_t msg_len);
int pnf_p7_slot_ind(pnf_p7_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot);
int nr_pnf_p7_get_msgs(pnf_p7_t* pnf_p7,
uint16_t phy_id,
uint16_t sfn,
uint16_t slot,
nfapi_nr_dl_tti_request_t* ret_dl_tti,
nfapi_nr_ul_tti_request_t* ret_ul_tti,
nfapi_nr_ul_dci_request_t* ret_ul_dci,
nfapi_nr_tx_data_request_t* ret_tx_data);
int pnf_p7_subframe_ind(pnf_p7_t* config, uint16_t phy_id, uint16_t sfn_sf);
int nfapi_pnf_p7_nr_slot_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_slot_indication_scf_t* ind);
int nfapi_pnf_p7_nr_rx_data_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rx_data_indication_t* ind);
@@ -856,7 +856,7 @@ int nfapi_pnf_p7_start(nfapi_pnf_p7_config_t* config);
*/
int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config);
/*! NR Slot indication
/*! NR get stuff
* message copied from nfapi_pnf_p7_subframe_ind
* \param config A pointer to a PNF P7 config
* \param phy_id The phy_id for the phy instance
@@ -868,8 +868,14 @@ int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config);
*
* If messages are not in the subframe buffer, they dummy subframe messages will be sent
*/
int nfapi_pnf_p7_slot_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot);
int nfapi_pnf_p7_get_msgs(nfapi_pnf_p7_config_t* config,
uint16_t phy_id,
uint16_t sfn,
uint16_t slot,
nfapi_nr_dl_tti_request_t* ret_dl_tti,
nfapi_nr_ul_tti_request_t* ret_ul_tti,
nfapi_nr_ul_dci_request_t* ret_ul_dci,
nfapi_nr_tx_data_request_t* ret_tx_data);
/*! Subframe indication
* \param config A pointer to a PNF P7 config
+113 -101
View File
@@ -672,145 +672,157 @@ void send_dummy_subframe(pnf_p7_t* pnf_p7, uint16_t sfn_sf)
}
}
int nr_pnf_p7_get_msgs(pnf_p7_t* pnf_p7,
uint16_t phy_id,
uint16_t sfn,
uint16_t slot,
nfapi_nr_dl_tti_request_t* ret_dl_tti,
nfapi_nr_ul_tti_request_t* ret_ul_tti,
nfapi_nr_ul_dci_request_t* ret_ul_dci,
nfapi_nr_tx_data_request_t* ret_tx_data)
{
if (pthread_mutex_lock(&(pnf_p7->mutex)) != 0) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n");
return -1;
}
int pnf_p7_slot_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn, uint16_t slot)
{
//This function is aligned with rx sfn/slot
// save the curren time, sfn and slot
// TODO useful?
pnf_p7->slot_start_time_hr = pnf_get_current_time_hr();
// We could either send an event to the p7 thread have have it run the
// subframe or we could handle it here and lock access to the subframe
// buffers. If we do it on the p7 thread then we run the risk of blocking
// on the udp send.
// todo : consider a more efficent lock mechasium
//uint16_t NUM_SLOTS = 20;//10* 2^mu
if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n");
return -1;
}
// We align the pnf_p7 sfn/slot with tx sfn/slot, and vnf is synced with pnf_p7 sfn/slot. This is so that the scheduler runs
// slot_ahead from rx thread.
pnf_p7->sfn = sfn;
pnf_p7->slot = slot;
// save the curren time, sfn and slot
pnf_p7->slot_start_time_hr = pnf_get_current_time_hr();
uint32_t tx_slot_dec = NFAPI_SFNSLOT2DEC(pnf_p7->mu, sfn, slot);
uint8_t buffer_index_tx = tx_slot_dec % NFAPI_SLOTNUM(pnf_p7->mu);
//We align the pnf_p7 sfn/slot with tx sfn/slot, and vnf is synced with pnf_p7 sfn/slot. This is so that the scheduler runs slot_ahead from rx thread.
// If the subframe_buffer has been configured
if (pnf_p7->_public.slot_buffer_size != 0) // for now value is same as sf_buffer_size
{
// apply the shift to the incoming sfn_sf
if (pnf_p7->slot_shift != 0) // see in vnf_build_send_dl_node_sync
{
uint16_t shifted_slot = slot + pnf_p7->slot_shift;
pnf_p7->sfn = sfn;
pnf_p7->slot = slot;
// adjust for wrap-around
if (shifted_slot < 0)
shifted_slot += NFAPI_MAX_SFNSLOTDEC(pnf_p7->mu);
else if (shifted_slot > NFAPI_MAX_SFNSLOTDEC(pnf_p7->mu))
shifted_slot -= NFAPI_MAX_SFNSLOTDEC(pnf_p7->mu);
uint32_t tx_slot_dec = NFAPI_SFNSLOT2DEC(pnf_p7->mu, sfn,slot);
uint8_t buffer_index_tx = tx_slot_dec % NFAPI_SLOTNUM(pnf_p7->mu);
//NFAPI_TRACE(NFAPI_TRACE_INFO, "Applying shift %d to sfn/slot (%d -> %d)\n", pnf_p7->sfn_slot_shift,
//NFAPI_SFNSF2DEC(sfn_slot), shifted_sfn_slot);
slot = shifted_slot;
// If the subframe_buffer has been configured
if(pnf_p7->_public.slot_buffer_size!= 0) // for now value is same as sf_buffer_size
{
//
// why does the shift not apply to pnf_p7->sfn_sf???
//
// apply the shift to the incoming sfn_sf
if(pnf_p7->slot_shift != 0) // see in vnf_build_send_dl_node_sync
{
uint16_t shifted_slot = slot + pnf_p7->slot_shift;
pnf_p7->slot_shift = 0;
}
// adjust for wrap-around
if(shifted_slot < 0)
shifted_slot += NFAPI_MAX_SFNSLOTDEC(pnf_p7->mu);
else if(shifted_slot > NFAPI_MAX_SFNSLOTDEC(pnf_p7->mu))
shifted_slot -= NFAPI_MAX_SFNSLOTDEC(pnf_p7->mu);
// NFAPI_TRACE(NFAPI_TRACE_INFO, "Applying shift %d to sfn/slot (%d -> %d)\n", pnf_p7->sfn_slot_shift, NFAPI_SFNSF2DEC(sfn_slot), shifted_sfn_slot);
slot = shifted_slot;
//
// why does the shift not apply to pnf_p7->sfn_sf???
//
pnf_p7->slot_shift = 0;
}
nfapi_pnf_p7_slot_buffer_t* tx_slot_buffer = &(pnf_p7->slot_buffer[buffer_index_tx]);
nfapi_pnf_p7_slot_buffer_t* tx_slot_buffer = &(pnf_p7->slot_buffer[buffer_index_tx]);
ret_dl_tti->SFN = sfn;
ret_dl_tti->Slot = slot;
ret_dl_tti->dl_tti_request_body.nPDUs = 0;
ret_tx_data->SFN = sfn;
ret_tx_data->Slot = slot;
ret_tx_data->Number_of_PDUs = 0;
nfapi_nr_dl_tti_request_t* dl_tti_req = &tx_slot_buffer->dl_tti_req;
nfapi_nr_tx_data_request_t* tx_data_req = &tx_slot_buffer->tx_data_req;
if (dl_tti_req->dl_tti_request_body.nPDUs > 0 && dl_tti_req->SFN == sfn && dl_tti_req->Slot == slot) {
DevAssert(pnf_p7->_public.dl_tti_req_fn != NULL);
DevAssert(pnf_p7->_public.tx_data_req_fn != NULL);
if (tx_data_req->Number_of_PDUs > 0 && tx_data_req->SFN == sfn && tx_data_req->Slot == slot) {
(pnf_p7->_public.dl_tti_req_fn)(NULL, &(pnf_p7->_public), dl_tti_req);
(pnf_p7->_public.tx_data_req_fn)(&(pnf_p7->_public), tx_data_req);
} else {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%4d.%2d no corresponding tx_data.request for dl_tti.request, dropping\n", sfn, slot);
nfapi_nr_tx_data_request_t* txd = &tx_slot_buffer->tx_data_req;
if (dl_tti_req->SFN == sfn && dl_tti_req->Slot == slot && txd->SFN == sfn && txd->Slot == slot) {
nfapi_nr_dl_tti_request_body_t* p_tti = &dl_tti_req->dl_tti_request_body;
int ret_idx = 0;
for (int i = 0; i < p_tti->nPDUs; ++i) {
int tx_index = p_tti->dl_tti_pdu_list[i].pdsch_pdu.pdsch_pdu_rel15.pduIndex - 1;
if (tx_index >= txd->Number_of_PDUs) {
NFAPI_TRACE(NFAPI_TRACE_ERROR,
"%4d.%2d no corresponding tx_data.request for dl_tti.request index %d, dropping\n",
sfn,
slot,
tx_index);
continue;
}
ret_dl_tti->dl_tti_request_body.dl_tti_pdu_list[ret_idx] = p_tti->dl_tti_pdu_list[i];
// TODO avoid huge copy
ret_tx_data->pdu_list[ret_idx] = txd->pdu_list[i];
ret_idx++;
}
ret_dl_tti->dl_tti_request_body.nPDUs = ret_idx;
ret_tx_data->Number_of_PDUs = ret_idx;
tx_slot_buffer->dl_tti_req.SFN = -1;
tx_slot_buffer->dl_tti_req.Slot = -1;
tx_slot_buffer->tx_data_req.SFN = -1;
tx_slot_buffer->tx_data_req.Slot = -1;
}
if (tx_data_req->Number_of_PDUs > 0 && tx_data_req->SFN == sfn && tx_data_req->Slot == slot) {
// there is a tx_data.request in this slot, but no corresponding
// dl_tti.request (when they need to come pairwise)
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%4d.%2d no corresponding dl_tti.request for tx_data.request, dropping\n", sfn, slot);
tx_slot_buffer->tx_data_req.SFN = -1;
tx_slot_buffer->tx_data_req.Slot = -1;
}
if(tx_slot_buffer->ul_tti_req.n_pdus > 0 && tx_slot_buffer->ul_tti_req.SFN == sfn && tx_slot_buffer->ul_tti_req.Slot == slot)
{
DevAssert(pnf_p7->_public.ul_tti_req_fn != NULL);
(pnf_p7->_public.ul_tti_req_fn)(NULL, &(pnf_p7->_public), &tx_slot_buffer->ul_tti_req);
ret_ul_tti->SFN = sfn;
ret_ul_tti->Slot = slot;
ret_ul_tti->n_pdus = 0;
if (tx_slot_buffer->ul_tti_req.SFN == sfn && tx_slot_buffer->ul_tti_req.Slot == slot) {
nfapi_nr_ul_tti_request_t* p = &tx_slot_buffer->ul_tti_req;
ret_ul_tti->n_pdus = p->n_pdus;
for (int i = 0; i < p->n_pdus; ++i)
ret_ul_tti->pdus_list[i] = p->pdus_list[i];
tx_slot_buffer->ul_tti_req.SFN = -1;
tx_slot_buffer->ul_tti_req.Slot = -1;
}
}
if(tx_slot_buffer->ul_dci_req.numPdus > 0 && tx_slot_buffer->ul_dci_req.SFN == sfn && tx_slot_buffer->ul_dci_req.Slot == slot)
{
DevAssert(pnf_p7->_public.ul_dci_req_fn != NULL);
(pnf_p7->_public.ul_dci_req_fn)(NULL, &(pnf_p7->_public), &tx_slot_buffer->ul_dci_req);
ret_ul_dci->SFN = sfn;
ret_ul_dci->Slot = slot;
ret_ul_dci->numPdus = 0;
if (tx_slot_buffer->ul_dci_req.SFN == sfn && tx_slot_buffer->ul_dci_req.Slot == slot) {
nfapi_nr_ul_dci_request_t* p = &tx_slot_buffer->ul_dci_req;
ret_ul_dci->numPdus = p->numPdus;
for (int i = 0; i < p->numPdus; ++i)
ret_ul_dci->ul_dci_pdu_list[i] = p->ul_dci_pdu_list[i];
tx_slot_buffer->ul_dci_req.SFN = -1;
tx_slot_buffer->ul_dci_req.Slot = -1;
}
}
//send the periodic timing info if configured
if(pnf_p7->_public.timing_info_mode_periodic && (pnf_p7->timing_info_period_counter++) == pnf_p7->_public.timing_info_period)
{
pnf_nr_pack_and_send_timing_info(pnf_p7);
// send the periodic timing info if configured
if (pnf_p7->_public.timing_info_mode_periodic && (pnf_p7->timing_info_period_counter++) == pnf_p7->_public.timing_info_period) {
pnf_nr_pack_and_send_timing_info(pnf_p7);
pnf_p7->timing_info_period_counter = 0;
}
else if(pnf_p7->_public.timing_info_mode_aperiodic && pnf_p7->timing_info_aperiodic_send)
{
pnf_nr_pack_and_send_timing_info(pnf_p7);
pnf_p7->timing_info_period_counter = 0;
} else if (pnf_p7->_public.timing_info_mode_aperiodic && pnf_p7->timing_info_aperiodic_send) {
pnf_nr_pack_and_send_timing_info(pnf_p7);
pnf_p7->timing_info_aperiodic_send = 0;
}
else
{
pnf_p7->timing_info_ms_counter++;
}
}
pnf_p7->timing_info_aperiodic_send = 0;
} else {
pnf_p7->timing_info_ms_counter++;
}
}
if (sfn % 128 == 0 && slot == 0) {
pnf_p7_nr_stats_t* s = &pnf_p7->nr_stats;
int ontime = s->dl_tti.ontime + s->ul_tti.ontime + s->ul_dci.ontime + s->tx_data.ontime;
int late = s->dl_tti.late + s->ul_tti.late + s->ul_dci.late + s->tx_data.late;
float dl_thr = (float) s->dl.bytes * 8 / 1000 / 1000 / 1.28f; // every 128 frames = 1.28 s
float ul_thr = (float) s->ul.bytes * 8 / 1000 / 1000 / 1.28f;
NFAPI_TRACE(NFAPI_TRACE_INFO, "[P7:%d] msgs ontime %d thr DL %.2f UL %.2f msg late %d (vtime)\n", pnf_p7->_public.phy_id, ontime, dl_thr, ul_thr, late);
float dl_thr = (float)s->dl.bytes * 8 / 1000 / 1000 / 1.28f; // every 128 frames = 1.28 s
float ul_thr = (float)s->ul.bytes * 8 / 1000 / 1000 / 1.28f;
NFAPI_TRACE(NFAPI_TRACE_INFO,
"[P7:%d] msgs ontime %d thr DL %.2f UL %.2f msg late %d (vtime)\n",
pnf_p7->_public.phy_id,
ontime,
dl_thr,
ul_thr,
late);
memset(s, 0, sizeof(*s));
}
if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n");
return -1;
}
if (pthread_mutex_unlock(&(pnf_p7->mutex)) != 0) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n");
return -1;
}
return 0;
return 0;
}
int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf)
{
// We could either send an event to the p7 thread have have it run the
+14 -7
View File
@@ -89,15 +89,22 @@ int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config)
return 0;
}
int nfapi_pnf_p7_slot_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot)
int nfapi_pnf_p7_get_msgs(nfapi_pnf_p7_config_t* config,
uint16_t phy_id,
uint16_t sfn,
uint16_t slot,
nfapi_nr_dl_tti_request_t* ret_dl_tti,
nfapi_nr_ul_tti_request_t* ret_ul_tti,
nfapi_nr_ul_dci_request_t* ret_ul_dci,
nfapi_nr_tx_data_request_t* ret_tx_data)
{
// Verify that config is not null
if(config == 0)
return -1;
pnf_p7_t* _this = (pnf_p7_t*)(config);
// Verify that config is not null
if (config == 0)
return -1;
return pnf_p7_slot_ind(_this, phy_id, sfn, slot);
pnf_p7_t* _this = (pnf_p7_t*)(config);
return nr_pnf_p7_get_msgs(_this, phy_id, sfn, slot, ret_dl_tti, ret_ul_tti, ret_ul_dci, ret_tx_data);
}
int nfapi_pnf_p7_subframe_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn_sf)
@@ -1210,12 +1210,6 @@ void send_dl_subframe_msgs_interleaved(int p7Sock, int phy_id, struct sockaddr_i
//free(req.tx_request_body.tx_pdu_list);
}
void send_slot_indication(phy_info_t* phy_info)
{
// DONE: add sfn and slot as members in the phy_info
nfapi_pnf_p7_slot_ind(phy_info->config, phy_info->phy_id, phy_info->sfn, phy_info->slot);
}
void send_subframe_indication(phy_info_t* phy_info)
{
nfapi_pnf_p7_subframe_ind(phy_info->config, phy_info->phy_id, phy_info->sfn_sf);
@@ -36,7 +36,6 @@
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "SCHED_NR/sched_nr.h"
#include "SCHED_NR/fapi_nr_l1.h"
#include "defs.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "common/utils/LOG/log.h"
@@ -38,7 +38,6 @@
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
#include "PHY/defs_gNB.h"
#include "SCHED_NR/fapi_nr_l1.h"
#include "SCHED_NR/sched_nr.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
+14 -26
View File
@@ -39,11 +39,13 @@
#include <complex.h>
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
#include "PHY/NR_REFSIG/nr_refsig.h"
#include "SCHED_NR/fapi_nr_l1.h"
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
#include <string.h>
#include "nfapi/open-nFAPI/fapi/inc/nr_fapi_p5_utils.h"
static void init_DLSCH_struct(PHY_VARS_gNB *gNB);
static void destroy_DLSCH_struct(const PHY_VARS_gNB *gNB);
int l1_north_init_gNB()
{
AssertFatal(RC.nb_nr_L1_inst > 0, "Failed to init PHY callbacks: nb_nr_L1_inst = %d\n", RC.nb_nr_L1_inst);
@@ -58,7 +60,6 @@ int l1_north_init_gNB()
LOG_D(NR_PHY, "RC.gNB[%d]: installing callbacks\n", i);
RC.gNB[i]->if_inst->NR_PHY_config_req = nr_phy_config_request;
RC.gNB[i]->if_inst->NR_Schedule_response = nr_schedule_response;
}
return 0;
@@ -155,6 +156,8 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB)
/// Transport init necessary for NR synchro
init_nr_transport(gNB);
init_DLSCH_struct(gNB);
gNB->nr_srs_info = (nr_srs_info_t **)malloc16_clear(gNB->max_nb_srs * sizeof(nr_srs_info_t*));
for (int id = 0; id < gNB->max_nb_srs; id++) {
gNB->nr_srs_info[id] = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t));
@@ -241,6 +244,8 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
reset_nr_transport(gNB);
destroy_DLSCH_struct(gNB);
NR_gNB_COMMON * common_vars = &gNB->common_vars;
for (int j = 0; j < common_vars->num_beams_period; j++) {
if (common_vars->beam_id)
@@ -281,13 +286,6 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
}
//Adding nr_schedule_handler
void install_nr_schedule_handlers(NR_IF_Module_t *if_inst)
{
if_inst->NR_PHY_config_req = nr_phy_config_request;
if_inst->NR_Schedule_response = nr_schedule_response;
}
void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,
int N_RB_DL,
int N_RB_UL,
@@ -366,7 +364,7 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config)
fp->ul_CarrierFreq = ((ul_bw_khz>>1) + gNB_config->carrier_config.uplink_frequency.value)*1000 ;
int32_t dlul_offset = fp->ul_CarrierFreq - fp->dl_CarrierFreq;
fp->nr_band = get_band(fp->dl_CarrierFreq, dlul_offset);
fp->nr_band = get_band(fp->dl_CarrierFreq, dlul_offset, dl_bw_khz, ul_bw_khz);
LOG_I(PHY, "DL frequency %lu Hz, UL frequency %lu Hz: band %d, uldl offset %d Hz\n", fp->dl_CarrierFreq, fp->ul_CarrierFreq, fp->nr_band, dlul_offset);
@@ -401,37 +399,27 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config)
init_timeshift_rotation(fp);
}
void init_DLSCH_struct(PHY_VARS_gNB *gNB, processingData_L1tx_t *msg)
static void init_DLSCH_struct(PHY_VARS_gNB *gNB)
{
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
uint16_t grid_size = cfg->carrier_config.dl_grid_size[fp->numerology_index].value;
msg->num_pdsch_slot = 0;
msg->dlsch = malloc16(gNB->max_nb_pdsch * sizeof(NR_gNB_DLSCH_t *));
int num_cw = NR_MAX_NB_LAYERS > 4? 2:1;
gNB->dlsch = calloc(gNB->max_nb_pdsch, sizeof(*gNB->dlsch));
for (int i = 0; i < gNB->max_nb_pdsch; i++) {
LOG_D(PHY, "Allocating Transport Channel Buffers for DLSCH %d/%d\n", i, gNB->max_nb_pdsch);
msg->dlsch[i] = (NR_gNB_DLSCH_t *)malloc16(num_cw * sizeof(NR_gNB_DLSCH_t));
for (int j = 0; j < num_cw; j++) {
msg->dlsch[i][j] = new_gNB_dlsch(fp, grid_size);
}
gNB->dlsch[i] = new_gNB_dlsch(fp, grid_size);
}
}
void reset_DLSCH_struct(const PHY_VARS_gNB *gNB, processingData_L1tx_t *msg)
static void destroy_DLSCH_struct(const PHY_VARS_gNB *gNB)
{
const NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
const nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
const uint16_t grid_size = cfg->carrier_config.dl_grid_size[fp->numerology_index].value;
int num_cw = NR_MAX_NB_LAYERS > 4? 2:1;
for (int i = 0; i < gNB->max_nb_pdsch; i++) {
for (int j = 0; j < num_cw; j++) {
free_gNB_dlsch(&msg->dlsch[i][j], grid_size, fp);
}
free(msg->dlsch[i]);
free_gNB_dlsch(&gNB->dlsch[i], grid_size, fp);
}
free(msg->dlsch);
free(gNB->dlsch);
}
void init_nr_transport(PHY_VARS_gNB *gNB)
+5 -15
View File
@@ -379,15 +379,13 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
fp->N_RB_SL = config->carrier_config.sl_grid_size[fp->numerology_index];
fp->frame_type = get_frame_type(fp->nr_band, fp->numerology_index);
int32_t uplink_frequency_offset = get_delta_duplex(fp->nr_band, fp->numerology_index);
int64_t uplink_frequency_offset = fp->ul_CarrierFreq - fp->dl_CarrierFreq;
uplink_frequency_offset *= 1000;
LOG_I(PHY, "Initializing frame parms: DL frequency %lu Hz, UL frequency %lu Hz: band %d, uldl offset %d Hz\n", fp->dl_CarrierFreq, fp->ul_CarrierFreq, fp->nr_band, uplink_frequency_offset);
LOG_I(PHY, "Initializing frame parms: DL frequency %lu Hz, UL frequency %lu Hz: band %d, uldl offset %ld Hz\n", fp->dl_CarrierFreq, fp->ul_CarrierFreq, fp->nr_band, uplink_frequency_offset);
AssertFatal(fp->frame_type==config->cell_config.frame_duplex_type, "Invalid duplex type (frame_type %d,cell_config.frame_duplex_type %d) in config request file for band %d\n", fp->frame_type,config->cell_config.frame_duplex_type,fp->nr_band);
AssertFatal(fp->ul_CarrierFreq == (fp->dl_CarrierFreq + uplink_frequency_offset), "Disagreement in uplink frequency for band %d: ul_CarrierFreq = %lu Hz vs expected %lu Hz\n", fp->nr_band, fp->ul_CarrierFreq, fp->dl_CarrierFreq + uplink_frequency_offset);
LOG_I(PHY,"Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",fp->numerology_index, fp->N_RB_DL, Ncp);
@@ -508,7 +506,7 @@ int nr_init_frame_parms_ue_sl(NR_DL_FRAME_PARMS *fp,
fp->ofdm_offset_divisor = ofdm_offset_divisor;
fp->threequarter_fs = threequarter_fs;
fp->nr_band = get_band(config->sl_carrier_config.sl_frequency, 0);
fp->nr_band = get_band(config->sl_carrier_config.sl_frequency, 0, 0, 0);
fp->att_rx = 0;
fp->att_tx = 0;
@@ -522,8 +520,6 @@ int nr_init_frame_parms_ue_sl(NR_DL_FRAME_PARMS *fp,
fp->Ncp = config->sl_bwp_config.sl_cyclic_prefix;
fp->frame_type = get_frame_type(fp->nr_band, fp->numerology_index);
int32_t uplink_frequency_offset = get_delta_duplex(fp->nr_band, fp->numerology_index);
uplink_frequency_offset *= 1000;
uint64_t bw_khz = (12 * config->sl_carrier_config.sl_grid_size) * (15 << config->sl_bwp_config.sl_scs);
// REfer to section 3GPP spec 38.101 5.4E.2.1
@@ -539,20 +535,14 @@ int nr_init_frame_parms_ue_sl(NR_DL_FRAME_PARMS *fp,
LOG_D(PHY, "CarrierFreq %lu Hz\n", fp->sl_CarrierFreq);
LOG_I(PHY,
"Initializing frame parms: DL frequency %lu Hz, UL frequency %lu Hz SL frequency %lu Hz: band %d, uldl offset %d Hz\n",
"Initializing frame parms: DL frequency %lu Hz, UL frequency %lu Hz SL frequency %lu Hz: band %d\n",
fp->dl_CarrierFreq,
fp->ul_CarrierFreq,
fp->sl_CarrierFreq,
fp->nr_band,
uplink_frequency_offset);
fp->nr_band);
AssertFatal(fp->frame_type == TDD, "Sidelink bands only support TDD");
AssertFatal(fp->ul_CarrierFreq == (fp->dl_CarrierFreq + uplink_frequency_offset),
"Disagreement in uplink frequency for band %d: ul_CarrierFreq = %lu Hz vs expected %lu Hz\n",
fp->nr_band,
fp->ul_CarrierFreq,
fp->dl_CarrierFreq + uplink_frequency_offset);
LOG_I(PHY, "Initializing frame parms for mu %d, N_RB %d, Ncp %d\n", fp->numerology_index, fp->N_RB_DL, fp->Ncp);
-3
View File
@@ -46,9 +46,6 @@ int l1_north_init_gNB(void);
void init_nr_transport(PHY_VARS_gNB *gNB);
void reset_nr_transport(PHY_VARS_gNB *gNB);
void init_DLSCH_struct(PHY_VARS_gNB *gNB, processingData_L1tx_t *msg);
void reset_DLSCH_struct(const PHY_VARS_gNB *gNB, processingData_L1tx_t *msg);
void RCconfig_nrUE_prs(void *cfg);
void init_nr_prs_ue_vars(PHY_VARS_NR_UE *ue);
void nr_init_dl_harq_processes(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_DLSCH_HARQ_PROCESSES], int number_of_processes, int num_rb);
+5 -18
View File
@@ -51,11 +51,11 @@ static void nr_pdcch_scrambling(uint32_t *in, uint32_t size, uint32_t Nid, uint3
out[i] = in[i] ^ seq[i];
}
static void nr_generate_dci(PHY_VARS_gNB *gNB,
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
int txdataF_offset,
NR_DL_FRAME_PARMS *frame_parms,
int slot)
void nr_generate_dci(PHY_VARS_gNB *gNB,
const nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
int txdataF_offset,
NR_DL_FRAME_PARMS *frame_parms,
int slot)
{
// fill reg list per symbol
int reg_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL * NR_NB_REG_PER_CCE];
@@ -237,16 +237,3 @@ static void nr_generate_dci(PHY_VARS_gNB *gNB,
*(unsigned long long *)dci_pdu->Payload);
} // for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++)
}
void nr_generate_dci_top(processingData_L1tx_t *msgTx, int slot, int txdataF_offset)
{
PHY_VARS_gNB *gNB = msgTx->gNB;
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
start_meas(&gNB->dci_generation_stats);
for (int i = 0; i < msgTx->num_ul_pdcch; i++)
nr_generate_dci(msgTx->gNB, &msgTx->ul_pdcch_pdu[i].pdcch_pdu.pdcch_pdu_rel15, txdataF_offset, frame_parms, slot);
for (int i = 0; i < msgTx->num_dl_pdcch; i++)
nr_generate_dci(msgTx->gNB, &msgTx->pdcch_pdu[i].pdcch_pdu_rel15, txdataF_offset, frame_parms, slot);
stop_meas(&gNB->dci_generation_stats);
}
+6 -2
View File
@@ -26,7 +26,11 @@
#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, int txdataF_offset);
void nr_generate_dci(PHY_VARS_gNB *gNB,
const nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
int txdataF_offset,
NR_DL_FRAME_PARMS *frame_parms,
int slot);
int16_t find_nr_pdcch(int frame,int slot, PHY_VARS_gNB *gNB,find_type_t type);
@@ -42,6 +46,6 @@ void nr_fill_ul_dci(PHY_VARS_gNB *gNB,
int slot,
nfapi_nr_ul_dci_request_pdus_t *pdcch_pdu);
void nr_fill_reg_list(int cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL * NR_NB_REG_PER_CCE], nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15);
void nr_fill_reg_list(int cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL * NR_NB_REG_PER_CCE], const nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15);
#endif //__PHY_NR_TRANSPORT_DCI__H
+1 -1
View File
@@ -42,7 +42,7 @@ int compfunc(const void *a, const void *b)
return (*(int *)a - *(int *)b);
}
void nr_fill_reg_list(int reg_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL * NR_NB_REG_PER_CCE], nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15)
void nr_fill_reg_list(int reg_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL * NR_NB_REG_PER_CCE], const nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15)
{
int bsize = pdcch_pdu_rel15->RegBundleSize;
int R = pdcch_pdu_rel15->InterleaverSize;
+19 -24
View File
@@ -51,7 +51,7 @@ static void nr_pdsch_codeword_scrambling(uint8_t *in, uint32_t size, uint8_t q,
nr_codeword_scrambling(in, size, q, Nid, n_RNTI, out);
}
static int do_ptrs_symbol(nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15,
static int do_ptrs_symbol(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15,
int start_sc,
int symbol_sz,
c16_t *txF,
@@ -339,7 +339,7 @@ static inline void neg_dmrs(c16_t *in, c16_t *out, int sz)
static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms,
int slot,
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15,
const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15,
int layer,
c16_t *output,
c16_t *txl_start,
@@ -457,7 +457,7 @@ static inline void do_txdataF(c16_t **txdataF,
int symbol_sz,
c16_t txdataF_precoding[][symbol_sz],
PHY_VARS_gNB *gNB,
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15,
const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15,
int ant,
int start_sc,
int txdataF_offset_per_symbol)
@@ -465,7 +465,7 @@ static inline void do_txdataF(c16_t **txdataF,
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
int rb = 0;
uint16_t subCarrier = start_sc;
nfapi_nr_tx_precoding_and_beamforming_t *pb = &rel15->precodingAndBeamforming;
const nfapi_nr_tx_precoding_and_beamforming_t *pb = &rel15->precodingAndBeamforming;
while (rb < rel15->rbSize) {
// get pmi info
const int pmi = (pb->prg_size > 0) ? (pb->prgs_list[(int)rb / pb->prg_size].pm_idx) : 0;
@@ -555,8 +555,7 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
time_stats_t *dlsch_scrambling_stats = &gNB->dlsch_scrambling_stats;
time_stats_t *dlsch_modulation_stats = &gNB->dlsch_modulation_stats;
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15;
const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->pdsch_pdu->pdsch_pdu_rel15;
const int layerSz = frame_parms->N_RB_DL * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB;
const int symbol_sz=frame_parms->ofdm_symbol_size;
const int dmrs_Type = rel15->dmrsConfigType;
@@ -580,7 +579,6 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
/* PTRS */
uint16_t dlPtrsSymPos = 0;
int n_ptrs = 0;
uint32_t ptrsSymbPerSlot = 0;
if (rel15->pduBitmap & 0x1) {
set_ptrs_symb_idx(&dlPtrsSymPos,
rel15->NrOfSymbols,
@@ -588,15 +586,13 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
1 << rel15->PTRSTimeDensity,
rel15->dlDmrsSymbPos);
n_ptrs = (rel15->rbSize + rel15->PTRSFreqDensity - 1) / rel15->PTRSFreqDensity;
ptrsSymbPerSlot = get_ptrs_symbols_in_slot(dlPtrsSymPos, rel15->StartSymbolIndex, rel15->NrOfSymbols);
}
harq->unav_res = ptrsSymbPerSlot * n_ptrs;
#ifdef DEBUG_DLSCH
printf("PDSCH encoding:\nPayload:\n");
for (int i = 0; i < (harq->B >> 3); i += 16) {
for (int i = 0; i < (dlsch->B >> 3); i += 16) {
for (int j = 0; j < 16; j++)
printf("0x%02x\t", harq->pdu[i + j]);
printf("0x%02x\t", dlsch->pdu[i + j]);
printf("\n");
}
printf("\nEncoded payload:\n");
@@ -609,7 +605,7 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
#endif
if (IS_SOFTMODEM_DLSIM)
memcpy(harq->f, input_ptr, (encoded_length + 7) >> 3);
memcpy(dlsch->f, input_ptr, (encoded_length + 7) >> 3);
c16_t mod_symbs[rel15->NrOfCodewords][encoded_length] __attribute__((aligned(64)));
for (int codeWord = 0; codeWord < rel15->NrOfCodewords; codeWord++) {
@@ -680,7 +676,7 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
// pmi = prgs_list[rbidx/prg_size].pm_idx, rbidx =0,...,rbSize-1
// The Precoding matrix:
// The Codebook Type I
nfapi_nr_tx_precoding_and_beamforming_t *pb = &rel15->precodingAndBeamforming;
const nfapi_nr_tx_precoding_and_beamforming_t *pb = &rel15->precodingAndBeamforming;
// beam number in multi-beam scenario (concurrent beams)
int bitmap = SL_to_bitmap(rel15->StartSymbolIndex, rel15->NrOfSymbols);
int beam_nb = beam_index_allocation(gNB->enable_analog_das,
@@ -777,9 +773,8 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
return ((size_output_tb + 511) >> 9) << 6;
}
void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
void nr_generate_pdsch(PHY_VARS_gNB *gNB, int n_dlsch, NR_gNB_DLSCH_t *dlsch_array, int frame, int slot)
{
PHY_VARS_gNB *gNB = msgTx->gNB;
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
time_stats_t *dlsch_encoding_stats = &gNB->dlsch_encoding_stats;
time_stats_t *tinput = &gNB->tinput;
@@ -792,10 +787,9 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
size_t size_output = 0;
for (int dlsch_id = 0; dlsch_id < msgTx->num_pdsch_slot; dlsch_id++) {
NR_gNB_DLSCH_t *dlsch = msgTx->dlsch[dlsch_id];
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15;
for (int i = 0; i < n_dlsch; i++) {
NR_gNB_DLSCH_t *dlsch = &dlsch_array[i];
const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->pdsch_pdu->pdsch_pdu_rel15;
LOG_D(PHY,
"pdsch: BWPStart %d, BWPSize %d, rbStart %d, rbsize %d\n",
@@ -819,10 +813,10 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
n_ptrs = (rel15->rbSize + rel15->PTRSFreqDensity - 1) / rel15->PTRSFreqDensity;
ptrsSymbPerSlot = get_ptrs_symbols_in_slot(dlPtrsSymPos, rel15->StartSymbolIndex, rel15->NrOfSymbols);
}
harq->unav_res = ptrsSymbPerSlot * n_ptrs;
dlsch->unav_res = ptrsSymbPerSlot * n_ptrs;
/// CRC, coding, interleaving and rate matching
AssertFatal(harq->pdu != NULL, "%4d.%2d no HARQ PDU for PDSCH generation\n", msgTx->frame, msgTx->slot);
AssertFatal(dlsch->pdu != NULL, "%4d.%2d no PDU for PDSCH generation\n", frame, slot);
/* output and its parts for each dlsch should be aligned on 64 bytes (or 8 * 64 bits)
* => size_output is a sum of parts sizes rounded up to a multiple of 8 * 64
@@ -836,7 +830,8 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
start_meas(dlsch_encoding_stats);
if (nr_dlsch_encoding(gNB,
msgTx,
n_dlsch,
dlsch_array,
frame,
slot,
frame_parms,
@@ -854,8 +849,8 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
stop_meas(dlsch_encoding_stats);
unsigned char *output_ptr = output;
for (int dlsch_id = 0; dlsch_id < msgTx->num_pdsch_slot; dlsch_id++) {
output_ptr += do_one_dlsch(output_ptr, gNB, msgTx->dlsch[dlsch_id], slot);
for (int i = 0; i < n_dlsch; i++) {
output_ptr += do_one_dlsch(output_ptr, gNB, &dlsch_array[i], slot);
}
}
+3 -7
View File
@@ -35,15 +35,11 @@
#include "PHY/defs_gNB.h"
void nr_fill_dlsch_dl_tti_req(processingData_L1tx_t *msgTx, nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu);
void nr_fill_dlsch_tx_req(processingData_L1tx_t *msgTx, int idx, uint8_t *sdu);
void nr_generate_pdsch(processingData_L1tx_t *msgTx,
int frame,
int slot);
void nr_generate_pdsch(PHY_VARS_gNB *gNB, int n_dlsch, NR_gNB_DLSCH_t *dlsch_array, int frame, int slot);
int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
processingData_L1tx_t *msgTx,
int n_dlsch,
NR_gNB_DLSCH_t *dlsch_array,
int frame,
uint8_t slot,
NR_DL_FRAME_PARMS *frame_parms,
+54 -61
View File
@@ -52,20 +52,19 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch, uint16_t N_RB, const NR_DL_FRAME_PARM
a_segments = a_segments / 273 + 1;
}
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
if (harq->b) {
free16(harq->b, a_segments * 1056);
harq->b = NULL;
if (dlsch->b) {
free16(dlsch->b, a_segments * 1056);
dlsch->b = NULL;
}
if (harq->f) {
free16(harq->f, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
harq->f = NULL;
if (dlsch->f) {
free16(dlsch->f, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
dlsch->f = NULL;
}
for (int r = 0; r < a_segments; r++) {
free(harq->c[r]);
harq->c[r] = NULL;
free(dlsch->c[r]);
dlsch->c[r] = NULL;
}
free(harq->c);
free(dlsch->c);
}
NR_gNB_DLSCH_t new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t N_RB)
@@ -80,34 +79,33 @@ NR_gNB_DLSCH_t new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t N_RB)
LOG_D(PHY, "Allocating %d segments (MAX %d, N_PRB %d)\n", a_segments, MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER, N_RB);
uint32_t dlsch_bytes = a_segments * 1056; // allocated bytes per segment
NR_gNB_DLSCH_t dlsch;
NR_gNB_DLSCH_t dlsch = {0};
NR_DL_gNB_HARQ_t *harq = &dlsch.harq_process;
bzero(harq, sizeof(NR_DL_gNB_HARQ_t));
harq->b = malloc16(dlsch_bytes);
AssertFatal(harq->b, "cannot allocate memory for harq->b\n");
bzero(harq->b, dlsch_bytes);
dlsch.b = malloc16(dlsch_bytes);
AssertFatal(dlsch.b, "cannot allocate memory for dlsch.b\n");
bzero(dlsch.b, dlsch_bytes);
harq->c = (uint8_t **)malloc16(a_segments * sizeof(uint8_t *));
dlsch.c = (uint8_t **)malloc16(a_segments * sizeof(uint8_t *));
for (int r = 0; r < a_segments; r++) {
// account for filler in first segment and CRCs for multiple segment case
// [hna] 8448 is the maximum CB size in NR
// 68*348 = 68*(maximum size of Zc)
// In section 5.3.2 in 38.212, the for loop is up to N + 2*Zc (maximum size of N is 66*Zc, therefore 68*Zc)
harq->c[r] = malloc16(8448);
AssertFatal(harq->c[r], "cannot allocate harq->c[%d]\n", r);
bzero(harq->c[r], 8448);
dlsch.c[r] = malloc16(8448);
AssertFatal(dlsch.c[r], "cannot allocate dlsch.c[%d]\n", r);
bzero(dlsch.c[r], 8448);
}
harq->f = malloc16(N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
AssertFatal(harq->f, "cannot allocate harq->f\n");
bzero(harq->f, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
dlsch.f = malloc16(N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
AssertFatal(dlsch.f, "cannot allocate dlsch->f\n");
bzero(dlsch.f, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
return (dlsch);
}
int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
processingData_L1tx_t *msgTx,
int n_dlsch,
NR_gNB_DLSCH_t *dlsch_array,
int frame,
uint8_t slot,
NR_DL_FRAME_PARMS *frame_parms,
@@ -122,28 +120,18 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
{
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_IN);
nrLDPC_TB_encoding_parameters_t TBs[msgTx->num_pdsch_slot];
nrLDPC_TB_encoding_parameters_t TBs[n_dlsch];
memset(TBs, 0, sizeof(TBs));
nrLDPC_slot_encoding_parameters_t slot_parameters = {.frame = frame,
.slot = slot,
.nb_TBs = msgTx->num_pdsch_slot,
.threadPool = &gNB->threadPool,
.tinput = tinput,
.tprep = tprep,
.tparity = tparity,
.toutput = toutput,
.TBs = TBs};
int num_segments = 0;
for (int dlsch_id = 0; dlsch_id < msgTx->num_pdsch_slot; dlsch_id++) {
NR_gNB_DLSCH_t *dlsch = msgTx->dlsch[dlsch_id];
for (int i = 0; i < n_dlsch; i++) {
NR_gNB_DLSCH_t *dlsch = &dlsch_array[i];
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
unsigned int crc = 1;
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15;
const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->pdsch_pdu->pdsch_pdu_rel15;
uint32_t A = rel15->TBSize[0] << 3;
unsigned char *a = harq->pdu;
unsigned char *a = dlsch->pdu;
if (rel15->rnti != SI_RNTI) {
ws_trace_t tmp = {.nr = true,
.direction = DIRECTION_DOWNLINK,
@@ -182,9 +170,8 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
// printf("CRC %x (A %d)\n",crc,A);
// printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]);
B = A + 24;
// harq->b = a;
AssertFatal((A / 8) + 4 <= max_bytes, "A %d is too big (A/8+4 = %d > %d)\n", A, (A / 8) + 4, max_bytes);
memcpy(harq->b, a, (A / 8) + 4); // why is this +4 if the CRC is only 3 bytes?
memcpy(dlsch->b, a, (A / 8) + 4); // why is this +4 if the CRC is only 3 bytes?
} else {
// Add 16-bit crc (polynomial A) to payload
crc = crc16(a, A) >> 16;
@@ -193,21 +180,19 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
// printf("CRC %x (A %d)\n",crc,A);
// printf("a0 %d a1 %d \n", a[A>>3], a[1+(A>>3)]);
B = A + 16;
// harq->b = a;
AssertFatal((A / 8) + 3 <= max_bytes, "A %d is too big (A/8+3 = %d > %d)\n", A, (A / 8) + 3, max_bytes);
memcpy(harq->b, a, (A / 8) + 3); // using 3 bytes to mimic the case of 24 bit crc
memcpy(dlsch->b, a, (A / 8) + 3); // using 3 bytes to mimic the case of 24 bit crc
}
nrLDPC_TB_encoding_parameters_t *TB_parameters = &TBs[dlsch_id];
nrLDPC_TB_encoding_parameters_t *TB_parameters = &TBs[i];
// The harq_pid is not unique among the active HARQ processes in the instance so we use dlsch_id instead
TB_parameters->harq_unique_pid = dlsch_id;
// The harq_pid is not unique among the active HARQ processes in the instance so we use i instead
TB_parameters->harq_unique_pid = i;
TB_parameters->BG = rel15->maintenance_parms_v3.ldpcBaseGraph;
TB_parameters->Z = harq->Z;
TB_parameters->A = A;
start_meas(dlsch_segmentation_stats);
TB_parameters->Kb = nr_segmentation(harq->b,
harq->c,
TB_parameters->Kb = nr_segmentation(dlsch->b,
dlsch->c,
B,
&TB_parameters->C,
&TB_parameters->K,
@@ -228,20 +213,19 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
size_t segments_offset = 0;
size_t dlsch_offset = 0;
for (int dlsch_id = 0; dlsch_id < msgTx->num_pdsch_slot; dlsch_id++) {
NR_gNB_DLSCH_t *dlsch = msgTx->dlsch[dlsch_id];
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15;
for (int i = 0; i < n_dlsch; i++) {
NR_gNB_DLSCH_t *dlsch = &dlsch_array[i];
const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->pdsch_pdu->pdsch_pdu_rel15;
nrLDPC_TB_encoding_parameters_t *TB_parameters = &TBs[dlsch_id];
nrLDPC_TB_encoding_parameters_t *TB_parameters = &TBs[i];
#ifdef DEBUG_DLSCH_CODING
for (int r = 0; r < TB_parameters->C; r++) {
LOG_D(PHY, "Encoder: B %d F %d \n", harq->B, TB_parameters->F);
LOG_D(PHY, "Encoder: B %d F %d \n", dlsch->B, TB_parameters->F);
LOG_D(PHY, "start ldpc encoder segment %d/%d\n", r, TB_parameters->C);
LOG_D(PHY, "input %d %d %d %d %d \n", harq->c[r][0], harq->c[r][1], harq->c[r][2], harq->c[r][3], harq->c[r][4]);
LOG_D(PHY, "input %d %d %d %d %d \n", dlsch->c[r][0], dlsch->c[r][1], dlsch->c[r][2], dlsch->c[r][3], dlsch->c[r][4]);
for (int cnt = 0; cnt < 22 * (TB_parameters->Z) / 8; cnt++) {
LOG_D(PHY, "%d ", harq->c[r][cnt]);
LOG_D(PHY, "%d ", dlsch->c[r][cnt]);
}
LOG_D(PHY, "\n");
}
@@ -259,7 +243,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
rel15->NrOfSymbols,
nb_re_dmrs,
get_num_dmrs(rel15->dlDmrsSymbPos),
harq->unav_res,
dlsch->unav_res,
rel15->qamModOrder[0],
rel15->nrOfLayers);
@@ -270,7 +254,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
for (int r = 0; r < TB_parameters->C; r++) {
nrLDPC_segment_encoding_parameters_t *segment_parameters = &TB_parameters->segments[r];
segment_parameters->c = harq->c[r];
segment_parameters->c = dlsch->c[r];
segment_parameters->E = nr_get_E(TB_parameters->G, TB_parameters->C, TB_parameters->Qm, rel15->nrOfLayers, r);
reset_meas(&segment_parameters->ts_interleave);
@@ -287,10 +271,19 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
dlsch_offset += ceil_mod(dlsch_size, 8 * 64);
}
nrLDPC_slot_encoding_parameters_t slot_parameters = {.frame = frame,
.slot = slot,
.nb_TBs = n_dlsch,
.threadPool = &gNB->threadPool,
.tinput = tinput,
.tprep = tprep,
.tparity = tparity,
.toutput = toutput,
.TBs = TBs};
gNB->nrLDPC_coding_interface.nrLDPC_coding_encoder(&slot_parameters);
for (int dlsch_id = 0; dlsch_id < msgTx->num_pdsch_slot; dlsch_id++) {
nrLDPC_TB_encoding_parameters_t *TB_parameters = &TBs[dlsch_id];
for (int i = 0; i < n_dlsch; i++) {
nrLDPC_TB_encoding_parameters_t *TB_parameters = &TBs[i];
for (int r = 0; r < TB_parameters->C; r++) {
nrLDPC_segment_encoding_parameters_t *segment_parameters = &TB_parameters->segments[r];
merge_meas(dlsch_interleaving_stats, &segment_parameters->ts_interleave);
@@ -1,62 +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 PHY/NR_TRANSPORT/nr_dlsch_tools.c
* \brief Top-level routines for decoding DLSCH transport channel from 38-214, V15.2.0 2018-06
* \author Guy De Souza
* \date 2018
* \version 0.1
* \company Eurecom
* \email: desouza@eurecom.fr
* \note
* \warning
*/
#include "nr_dlsch.h"
#include "../../../nfapi/oai_integration/vendor_ext.h"
void nr_fill_dlsch_dl_tti_req(processingData_L1tx_t *msgTx, nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu)
{
NR_gNB_DLSCH_t *dlsch = &msgTx->dlsch[msgTx->num_pdsch_slot][0];
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
/// DLSCH struct
memcpy((void*)&harq->pdsch_pdu, (void*)pdsch_pdu, sizeof(nfapi_nr_dl_tti_pdsch_pdu));
AssertFatal(msgTx->num_pdsch_slot == pdsch_pdu->pdsch_pdu_rel15.pduIndex,
"PDSCH PDU index %d does not match msgTx index %d\n",
pdsch_pdu->pdsch_pdu_rel15.pduIndex,
msgTx->num_pdsch_slot);
msgTx->num_pdsch_slot++;
harq->pdu = NULL;
}
void nr_fill_dlsch_tx_req(processingData_L1tx_t *msgTx, int idx, uint8_t *sdu)
{
AssertFatal(sdu != NULL, "sdu is null\n");
/* not sure if FAPI could transmit DL_TTI_req and TX_req in different orders.
* for the moment, assume they are in the same order (and check!) */
NR_gNB_DLSCH_t *dlsch = &msgTx->dlsch[idx][0];
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
nfapi_nr_dl_tti_pdsch_pdu *pdsch = &harq->pdsch_pdu;
AssertFatal(pdsch->pdsch_pdu_rel15.pduIndex == idx, "PDSCH PDU index %d does not match %d\n", pdsch->pdsch_pdu_rel15.pduIndex, idx);
harq->pdu = sdu;
}
+1 -1
View File
@@ -13,7 +13,7 @@ int nr_generate_prs(int slot,
int16_t amp,
prs_config_t *prs_cfg,
nfapi_nr_config_request_scf_t *config,
NR_DL_FRAME_PARMS *frame_parms)
const NR_DL_FRAME_PARMS *frame_parms)
{
int k_prime = 0, k = 0, idx;
@@ -45,7 +45,7 @@ int nr_generate_prs(int slot,
int16_t amp,
prs_config_t *prs_cfg,
nfapi_nr_config_request_scf_t *config,
NR_DL_FRAME_PARMS *frame_parms);
const NR_DL_FRAME_PARMS *frame_parms);
/*!
\fn int nr_generate_pss
+80
View File
@@ -59,8 +59,88 @@ static NR_gNB_ULSCH_t *find_nr_ulsch(PHY_VARS_gNB *gNB, uint16_t rnti, int pid)
return ulsch;
}
static void dump_pusch_pdu(int instance, int frame, int slot, nfapi_nr_pusch_pdu_t *pusch_pdu)
{
LOG_D(PHY,
"[gNB %d] %d.%d ULSCH PDU pdu_bit_map %u "
"rnti %u "
"handle %u "
"bwp_size %u "
"bwp_start %u "
"subcarrier_spacing %u "
"cyclic_prefix %u "
"target_code_rate %u "
"qam_mod_order %u "
"mcs_index %u "
"mcs_table %u "
"transform_precoding %u "
"data_scrambling_id %u "
"nrOfLayers %u "
"ul_dmrs_symb_pos %u "
"dmrs_config_type %u "
"ul_dmrs_scrambling_id %u "
"scid %u "
"num_dmrs_cdm_grps_no_data %u "
"dmrs_ports %u "
"resource_alloc %u "
"rb_start %u "
"rb_size %u "
"vrb_to_prb_mapping %u "
"frequency_hopping %u "
"tx_direct_current_location %u "
"uplink_frequency_shift_7p5khz %u "
"start_symbol_index %u "
"nr_of_symbols %u "
"tbslbrm %u "
"ldpcBaseGraph %u "
"pusch_data->rv_index %u "
"pusch_data->harq_process_id %u "
"pusch_data->new_data_indicator %u "
"pusch_data->num_cb %u\n",
instance,
frame,
slot,
pusch_pdu->pdu_bit_map,
pusch_pdu->rnti,
pusch_pdu->handle,
pusch_pdu->bwp_size,
pusch_pdu->bwp_start,
pusch_pdu->subcarrier_spacing,
pusch_pdu->cyclic_prefix,
pusch_pdu->target_code_rate,
pusch_pdu->qam_mod_order,
pusch_pdu->mcs_index,
pusch_pdu->mcs_table,
pusch_pdu->transform_precoding,
pusch_pdu->data_scrambling_id,
pusch_pdu->nrOfLayers,
pusch_pdu->ul_dmrs_symb_pos,
pusch_pdu->dmrs_config_type,
pusch_pdu->ul_dmrs_scrambling_id,
pusch_pdu->scid,
pusch_pdu->num_dmrs_cdm_grps_no_data,
pusch_pdu->dmrs_ports,
pusch_pdu->resource_alloc,
pusch_pdu->rb_start,
pusch_pdu->rb_size,
pusch_pdu->vrb_to_prb_mapping,
pusch_pdu->frequency_hopping,
pusch_pdu->tx_direct_current_location,
pusch_pdu->uplink_frequency_shift_7p5khz,
pusch_pdu->start_symbol_index,
pusch_pdu->nr_of_symbols,
pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes,
pusch_pdu->maintenance_parms_v3.ldpcBaseGraph,
pusch_pdu->pusch_data.rv_index,
pusch_pdu->pusch_data.harq_process_id,
pusch_pdu->pusch_data.new_data_indicator,
pusch_pdu->pusch_data.num_cb);
}
void nr_fill_ulsch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pusch_pdu_t *ulsch_pdu)
{
dump_pusch_pdu(gNB->Mod_id, frame, slot, ulsch_pdu);
int harq_pid = ulsch_pdu->pusch_data.harq_process_id;
NR_gNB_ULSCH_t *ulsch = find_nr_ulsch(gNB, ulsch_pdu->rnti, harq_pid);
if (ulsch == NULL) {
@@ -35,7 +35,6 @@
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "SCHED_NR/sched_nr.h"
#include "SCHED_NR/fapi_nr_l1.h"
#include "defs.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "common/utils/LOG/log.h"
@@ -236,6 +236,7 @@ void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue,
.meas_type = NFAPI_NR_SS_MEAS,
.Nid_cell = ue->frame_parms.Nid_cell,
.rsrp_dBm = ue->measurements.ssb_rsrp_dBm[ssb_index],
.sinr_dB = ue->measurements.ssb_sinr_dB[ssb_index],
.ssb_index = ssb_index,
.is_neighboring_cell = false,
};
+232 -54
View File
@@ -1,13 +1,47 @@
[Window][WindowOverViewport_11111111]
Pos=0,19
Size=1920,927
Collapsed=0
[Window][Debug##Default]
Pos=60,60
Size=400,400
Collapsed=0
[Window][Status bar]
Pos=0,914
Size=1920,32
Collapsed=0
DockId=0x00000004,0
[Window][Global scope settings]
Pos=697,153
Size=545,478
Collapsed=0
[Window][PUSCH SLOT IQ]
Pos=0,257
Size=789,655
Collapsed=0
DockId=0x0000000B,0
[Window][PUSCH LLRs]
Pos=791,257
Size=1129,655
Collapsed=0
DockId=0x0000000C,0
[Window][Time domain samples]
Pos=997,201
Size=923,711
Collapsed=0
DockId=0x0000000E,0
[Window][NR KPI]
Pos=0,19
Size=1133,667
Collapsed=0
DockId=0x00000005,0
DockId=0x00000007,0
[Window][Dear ImGui Demo]
Pos=531,19
@@ -21,79 +55,223 @@ Size=529,667
Collapsed=0
DockId=0x00000002,0
[Window][WindowOverViewport_11111111]
Pos=0,19
Size=1280,701
Collapsed=0
[Window][Status bar]
Pos=0,688
Size=1280,32
Collapsed=0
DockId=0x00000004,0
[Window][Global scope settings]
Pos=1038,19
Size=242,667
Collapsed=0
DockId=0x00000006,0
[Window][UE KPI]
Pos=532,19
Size=528,667
Pos=0,19
Size=1920,180
Collapsed=0
DockId=0x00000008,0
DockId=0x00000007,0
[Window][UE PDSCH IQ]
Pos=0,19
Size=530,667
Pos=997,201
Size=923,711
Collapsed=0
DockId=0x00000005,1
[Window][Time domain samples]
Pos=0,19
Size=1036,667
Collapsed=0
DockId=0x00000005,0
DockId=0x0000000E,3
[Window][Time domain samples - before sync]
Pos=0,19
Size=530,667
Pos=0,201
Size=995,711
Collapsed=0
DockId=0x00000005,2
DockId=0x0000000D,0
[Window][Broadcast channel]
Pos=0,19
Size=530,667
Pos=997,201
Size=923,711
Collapsed=0
DockId=0x00000005,3
DockId=0x0000000E,1
[Window][RX IQ]
Pos=532,19
Size=528,667
Collapsed=0
DockId=0x00000008,0
DockId=0x00000001,0
[Window][PUSCH SLOT IQ]
Pos=0,19
Size=1036,667
[Window][UE PDSCH Chan est]
Pos=997,201
Size=923,711
Collapsed=0
DockId=0x00000005,1
DockId=0x0000000E,2
[Window][PUSCH LLRs]
Pos=0,19
Size=1036,667
[Window][UE PDSCH IQ before compensation]
Pos=0,201
Size=995,711
Collapsed=0
DockId=0x00000005,2
DockId=0x0000000D,1
[Window][gNB Scope]
Pos=-4,30
Size=1728,834
Collapsed=0
[Window][UE Scope]
Pos=-1,23
Size=1922,902
Collapsed=0
[Window][Dear ImGui Demo/##Basket_379447C1]
IsChild=1
Size=1202,260
[Window][Dear ImGui Demo/ResizableChild_D5443E47]
IsChild=1
Size=1153,32
[Window][Dear ImGui Demo/Red_1D4E05CE]
IsChild=1
Size=200,100
[Window][Delete?]
Pos=804,420
Size=311,105
Collapsed=0
[Window][Stacked 1]
Pos=755,387
Size=409,172
Collapsed=0
[Window][Example: Simple layout]
Pos=354,164
Size=981,698
Collapsed=0
[Window][Example: Simple layout/left pane_AED60EF8]
IsChild=1
Size=150,644
[Window][Example: Log]
Pos=60,60
Size=500,400
Collapsed=0
[Window][Example: Auto-resizing window]
Pos=179,108
Size=654,437
Collapsed=0
[Window][gNB Scope/##pusch_time_domain_5637DE0C]
IsChild=1
Size=1728,302
[Window][gNB Scope/##pusch_iq_903C5250]
IsChild=1
Size=408,500
[Window][gNB Scope/##pusch_llr_FE553CCC]
IsChild=1
Size=1443,502
[Window][Dear ImGui Demo/##Tree_C1CE970E]
IsChild=1
Size=1132,260
[Window][Dear ImGui Demo/##Basket_97A64F14]
IsChild=1
Size=1132,260
[Window][Dear ImGui Demo/##Basket_745C408A]
IsChild=1
Size=1132,260
[Window][UE Scope/##ue_kpi_A22981AC]
IsChild=1
Size=1839,183
[Window][UE Scope/##ue_iq_plots_F23AA7B4]
IsChild=1
Size=814,517
[Window][UE Scope/##ue_plots0_D75041C0]
IsChild=1
Size=1067,610
[Window][UE Scope/##ue_plots1_A0577156]
IsChild=1
Size=733,604
[Window][UE PDCCH IQ]
Pos=997,201
Size=923,711
Collapsed=0
DockId=0x0000000E,4
[Window][UE PDCCH LLR]
Pos=0,201
Size=995,711
Collapsed=0
DockId=0x0000000D,2
[Table][0xC9935533,3]
Column 0 Weight=1.0000
Column 1 Weight=1.0000
Column 2 Weight=1.0000
[Table][0xE0773582,3]
Column 0 Weight=1.0000
Column 1 Weight=1.0000
Column 2 Weight=1.0000
[Table][0x45A0E60D,7]
RefScale=13
Column 0 Width=49
Column 1 Width=112
Column 2 Width=112
Column 3 Width=112
Column 4 Width=112
Column 5 Width=112
Column 6 Width=112
[Table][0xDA36A7E0,6]
RefScale=13
Column 0 Width=28 Sort=0v
Column 1 Width=42
Column 2 Width=73
Column 3 Width=68
Column 4 Weight=1.0000
Column 5 Width=-1
[Table][0x0919F5A2,14]
RefScale=13
Column 0 Width=56
Column 1 Width=19
Column 2 Width=19
Column 3 Width=19
Column 4 Width=19
Column 5 Width=19
Column 6 Width=19
Column 7 Width=19
Column 8 Width=19
Column 9 Width=19
Column 10 Width=19
Column 11 Width=19
Column 12 Width=19
Column 13 Width=19
[Table][0x8DFA6E86,2]
Column 0 Weight=1.0000
Column 1 Weight=1.0000
[Table][0xFABAAEF7,2]
Column 0 Weight=1.0000
Column 1 Weight=1.0000
[Table][0xC179E37C,3]
RefScale=13
Column 0 Width=108 Sort=0v
Column 1 Width=63
Column 2 Width=-1
[Docking][Data]
DockSpace ID=0x7C6B3D9B Window=0xA87D555D Pos=0,19 Size=1280,701 Split=Y Selected=0x71C89FCB
DockNode ID=0x00000003 Parent=0x7C6B3D9B SizeRef=1280,667 Split=X
DockNode ID=0x00000001 Parent=0x00000003 SizeRef=1319,720 Split=X Selected=0x6627CA6C
DockNode ID=0x00000007 Parent=0x00000001 SizeRef=530,667 Split=X Selected=0x93FDECFF
DockNode ID=0x00000005 Parent=0x00000007 SizeRef=1036,334 CentralNode=1 Selected=0x93FDECFF
DockNode ID=0x00000006 Parent=0x00000007 SizeRef=242,334 Selected=0xFAA8D9D5
DockNode ID=0x00000008 Parent=0x00000001 SizeRef=528,667 Selected=0x6627CA6C
DockNode ID=0x00000002 Parent=0x00000003 SizeRef=529,720 Selected=0xB903C8C9
DockNode ID=0x00000004 Parent=0x7C6B3D9B SizeRef=1280,32 HiddenTabBar=1 Selected=0xD9B9B9C7
DockSpace ID=0x7C6B3D9B Window=0xA87D555D Pos=0,19 Size=1920,927 Split=Y Selected=0x71C89FCB
DockNode ID=0x00000003 Parent=0x7C6B3D9B SizeRef=1280,667 Split=X
DockNode ID=0x00000001 Parent=0x00000003 SizeRef=1319,720 Split=Y Selected=0x6627CA6C
DockNode ID=0x00000009 Parent=0x00000001 SizeRef=1920,236 Split=Y Selected=0x6627CA6C
DockNode ID=0x00000007 Parent=0x00000009 SizeRef=1920,180 CentralNode=1 Selected=0x6627CA6C
DockNode ID=0x00000008 Parent=0x00000009 SizeRef=1920,711 Split=X Selected=0x3A5D5B36
DockNode ID=0x0000000D Parent=0x00000008 SizeRef=995,711 Selected=0xF0B5A18D
DockNode ID=0x0000000E Parent=0x00000008 SizeRef=923,711 Selected=0x752F58D8
DockNode ID=0x0000000A Parent=0x00000001 SizeRef=1920,655 Split=X Selected=0x93FDECFF
DockNode ID=0x0000000B Parent=0x0000000A SizeRef=789,444 Selected=0x93FDECFF
DockNode ID=0x0000000C Parent=0x0000000A SizeRef=1129,444 Selected=0x43E927D5
DockNode ID=0x00000002 Parent=0x00000003 SizeRef=529,720 Selected=0xB903C8C9
DockNode ID=0x00000004 Parent=0x7C6B3D9B SizeRef=1280,32 HiddenTabBar=1 Selected=0xD9B9B9C7
+43 -11
View File
@@ -100,6 +100,7 @@ class LLRPlot {
ImScopeDataWrapper &scope_data = scope_array[type];
if (ImPlot::BeginPlot(label)) {
ImPlot::SetupAxes(nullptr, nullptr, ImPlotAxisFlags_AutoFit, ImPlotAxisFlags_AutoFit);
if (!frozen || next) {
if (scope_data.is_data_ready) {
iq_procedure_timer.Add(scope_data.data.time_taken_in_ns);
@@ -205,6 +206,7 @@ class IQHist {
if (plot_type == 0) {
float x = ImGui::CalcItemWidth();
if (ImPlot::BeginPlot(label.c_str(), {x, x})) {
ImPlot::SetupAxes(nullptr, nullptr, ImPlotAxisFlags_AutoFit, ImPlotAxisFlags_AutoFit);
ImPlot::PlotHistogram2D(label.c_str(),
iq_data->real.data(),
iq_data->imag.data(),
@@ -217,6 +219,7 @@ class IQHist {
} else if (plot_type == 2) {
float x = ImGui::CalcItemWidth();
if (ImPlot::BeginPlot(label.c_str(), {x, x})) {
ImPlot::SetupAxes(nullptr, nullptr, ImPlotAxisFlags_AutoFit, ImPlotAxisFlags_AutoFit);
int points_drawn = 0;
while (points_drawn < iq_data->len) {
// Limit the amount of data plotted with PlotScatter call (issue with vertices/draw call)
@@ -232,6 +235,7 @@ class IQHist {
}
} else if (plot_type == 1) {
if (ImPlot::BeginPlot(label.c_str())) {
ImPlot::SetupAxes(nullptr, nullptr, ImPlotAxisFlags_AutoFit, ImPlotAxisFlags_AutoFit);
ImPlot::PlotLine(label.c_str(), iq_data->power.data(), iq_data->len);
ImPlot::EndPlot();
}
@@ -364,6 +368,7 @@ class IQSlotHeatmap {
static std::vector<int> symbol_boundaries = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
if (ImPlot::BeginPlot(label.c_str(), {(float)ImGui::GetWindowWidth() * 0.9f, 0})) {
auto num_sc = num_rb * NR_NB_SC_PER_RB;
ImPlot::SetupAxes(nullptr, nullptr, ImPlotAxisFlags_AutoFit, ImPlotAxisFlags_AutoFit);
ImPlot::SetupAxes("symbols", "subcarriers");
ImPlot::SetupAxisLimits(ImAxis_X1, num_symbols, 0);
ImPlot::SetupAxisLimits(ImAxis_Y1, num_sc, 0);
@@ -429,6 +434,7 @@ void ShowUeScope(void *data_void_ptr, float t)
rbs_buffer.AddPoint(t, getKPIUE()->nofRBs);
bler.AddPoint(t, (float)getKPIUE()->nb_nack / (float)getKPIUE()->nb_total);
mcs.AddPoint(t, (float)getKPIUE()->dl_mcs);
ImPlot::SetupAxes(nullptr, nullptr, ImPlotAxisFlags_AutoFit, ImPlotAxisFlags_AutoFit);
ImPlot::SetupAxes("time", "noOfRbs");
ImPlot::SetupAxisLimits(ImAxis_X1, t - history, t, ImGuiCond_Always);
ImPlot::SetupAxisLimits(ImAxis_Y1, 0, NR_MAX_RB);
@@ -444,6 +450,23 @@ void ShowUeScope(void *data_void_ptr, float t)
}
ImGui::End();
if (ImGui::Begin("UE PDCCH IQ")) {
static auto iq_data = new IQData();
static auto pdcch_iq_hist = new IQHist("PDCCH IQ");
bool new_data = false;
if (pdcch_iq_hist->ShouldReadData()) {
new_data = iq_data->TryCollect(&scope_array[pdcchRxdataF_comp], t, pdcch_iq_hist->GetEpsilon(), iq_procedure_timer);
}
pdcch_iq_hist->Draw(iq_data, t, new_data);
}
ImGui::End();
if (ImGui::Begin("UE PDCCH LLR")) {
static auto llr_plot = new LLRPlot();
llr_plot->Draw(t, pdcchLlr, "PDCCH LLR");
}
ImGui::End();
if (ImGui::Begin("UE PDSCH IQ")) {
static auto iq_data = new IQData();
static auto pdsch_iq_hist = new IQHist("PDSCH IQ");
@@ -710,6 +733,7 @@ void *imscope_thread(void *data_void_ptr)
static float t = 0;
static bool show_imgui_demo_window = false;
static bool show_implot_demo_window = false;
static bool show_scope_settings_window = false;
ImGui::DockSpaceOverViewport();
if (ImGui::BeginMainMenuBar()) {
if (ImGui::BeginMenu("File")) {
@@ -729,6 +753,12 @@ void *imscope_thread(void *data_void_ptr)
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Settings")) {
if (ImGui::MenuItem("Global scope settings")) {
show_scope_settings_window = !show_scope_settings_window;
}
ImGui::EndMenu();
}
ImGui::EndMainMenuBar();
}
@@ -739,16 +769,6 @@ void *imscope_thread(void *data_void_ptr)
}
ImGui::End();
ImGui::Begin("Global scope settings");
ImGui::ShowStyleSelector("ImGui Style");
ImPlot::ShowStyleSelector("ImPlot Style");
ImPlot::ShowColormapSelector("ImPlot Colormap");
ImGui::SliderInt("FPS target", &target_fps, 12, 60);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Reduces scope flickering in unfrozen mode. Can reduce impact on perfromance of the modem");
}
ImGui::End();
t += ImGui::GetIO().DeltaTime;
iq_procedure_timer.UpdateAverage(t);
@@ -765,7 +785,19 @@ void *imscope_thread(void *data_void_ptr)
ImPlot::ShowDemoWindow();
if (show_imgui_demo_window)
ImGui::ShowDemoWindow();
// Settings
if (show_scope_settings_window) {
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_FirstUseEver, ImVec2(0.5f, 0.5f));
ImGui::Begin("Global scope settings", &show_scope_settings_window);
ImGui::ShowStyleSelector("ImGui Style");
ImPlot::ShowStyleSelector("ImPlot Style");
ImPlot::ShowColormapSelector("ImPlot Colormap");
ImGui::SliderInt("FPS target", &target_fps, 12, 60);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Reduces scope flickering in unfrozen mode. Can reduce impact on perfromance of the modem");
}
ImGui::End();
}
// Rendering
ImGui::Render();
glViewport(0, 0, display_w, display_h);
+14 -47
View File
@@ -53,30 +53,6 @@ typedef struct {
int lut[MAX_PUCCH0_NID][160][14];
} NR_gNB_PUCCH0_LUT_t;
typedef struct {
/// Nfapi DLSCH PDU
nfapi_nr_dl_tti_pdsch_pdu pdsch_pdu;
/// pointer to pdu from MAC interface (this is "a" in 36.212)
uint8_t *pdu;
/// Pointer to the payload
uint8_t *b;
/// Pointers to transport block segments
uint8_t **c;
/// Frame where current HARQ round was sent
uint32_t frame;
/// Interleaver outputs
uint8_t *f;
/// LDPC lifting size
uint32_t Z;
/// REs unavailable for DLSCH (overlapping with PTRS, CSIRS etc.)
uint32_t unav_res;
} NR_DL_gNB_HARQ_t;
typedef struct {
uint8_t active;
nfapi_nr_dl_tti_csi_rs_pdu csirs_pdu;
} NR_gNB_CSIRS_t;
typedef struct {
int dump_frame;
int round_trials[8];
@@ -121,19 +97,20 @@ typedef struct {
} NR_gNB_PHY_STATS_t;
typedef struct {
/// Pointers to variables related to DLSCH harq process
NR_DL_gNB_HARQ_t harq_process;
/// Active flag for baseband transmitter processing
uint8_t active;
/// Number of soft channel bits
uint32_t G;
/// Nfapi DLSCH PDU
const nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu;
/// pointer to pdu from MAC interface (this is "a" in 36.212)
uint8_t *pdu;
/// Pointer to the payload
uint8_t *b;
/// Pointers to transport block segments
uint8_t **c;
/// Interleaver outputs
uint8_t *f;
/// REs unavailable for DLSCH (overlapping with PTRS, CSIRS etc.)
uint32_t unav_res;
} NR_gNB_DLSCH_t;
typedef struct {
bool active;
nfapi_nr_dl_tti_ssb_pdu ssb_pdu;
} NR_gNB_SSB_t;
typedef struct {
uint8_t NumPRSResources;
prs_config_t prs_cfg[NR_MAX_PRS_RESOURCES_PER_SET];
@@ -409,6 +386,8 @@ typedef struct PHY_VARS_gNB_s {
NR_gNB_COMMON common_vars;
prach_list_t prach_list;
// TODO: can we remove c from NR_gNB_DLSCH_t and put it on the stack?
NR_gNB_DLSCH_t *dlsch;
NR_gNB_PRS prs_vars;
NR_gNB_PUSCH *pusch_vars;
NR_gNB_PUCCH_t *pucch;
@@ -494,7 +473,6 @@ typedef struct PHY_VARS_gNB_s {
time_stats_t rx_pusch_symbol_processing_stats;
time_stats_t ul_indication_stats;
time_stats_t slot_indication_stats;
time_stats_t schedule_response_stats;
time_stats_t ulsch_decoding_stats;
time_stats_t ts_deinterleave;
time_stats_t ts_rate_unmatch;
@@ -522,7 +500,6 @@ typedef struct PHY_VARS_gNB_s {
int L1_rx_thread_core;
pthread_t L1_tx_thread;
int L1_tx_thread_core;
struct processingData_L1tx *msgDataTx;
void *scopeData;
} PHY_VARS_gNB;
@@ -599,16 +576,6 @@ typedef struct processingData_L1tx {
int slot_rx;
openair0_timestamp timestamp_tx;
PHY_VARS_gNB *gNB;
nfapi_nr_dl_tti_pdcch_pdu pdcch_pdu[NFAPI_NR_MAX_NB_CORESETS];
nfapi_nr_ul_dci_request_pdus_t ul_pdcch_pdu[NFAPI_NR_MAX_NB_CORESETS];
NR_gNB_CSIRS_t csirs_pdu[NR_SYMBOLS_PER_SLOT];
NR_gNB_DLSCH_t **dlsch;
NR_gNB_SSB_t ssb[64];
uint16_t num_pdsch_slot;
int num_dl_pdcch;
int num_ul_pdcch;
/* a reference to the sched_response, to release it when not needed anymore */
int sched_response_id;
} processingData_L1tx_t;
typedef struct processingData_L1rx {
@@ -365,7 +365,7 @@ void nr_channel_level(const int symbol,
int32_t avg[nb_rx * Nl],
const uint32_t len);
void nr_scale_channel(int size, int ch_estimates_ext[][size], int symb, uint32_t len, int nrOfLayers, int nb_rx, int shift_ch_ext);
bool generate_srs_nr(NR_DL_FRAME_PARMS *frame_parms,
bool generate_srs_nr(const NR_DL_FRAME_PARMS *frame_parms,
c16_t **txdataF,
uint16_t symbol_offset,
int bwp_start,
@@ -139,7 +139,7 @@ static int compute_n_b(frame_t frame_number,
* See TS 38.211 - Section 6.4.1.4 Sounding reference signal
*
***************************************************************************/
bool generate_srs_nr(NR_DL_FRAME_PARMS *frame_parms,
bool generate_srs_nr(const NR_DL_FRAME_PARMS *frame_parms,
c16_t **txdataF,
uint16_t symbol_offset,
int bwp_start,
-20
View File
@@ -9,30 +9,12 @@ typedef struct pnf_p7_t pnf_p7_t;
typedef struct vnf_t vnf_t;
typedef struct vnf_p7_t vnf_p7_t;
void handle_nfapi_nr_pdcch_pdu(PHY_VARS_gNB *gNB,
int frame, int slot,
nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu){}
void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu){}
void handle_nr_nfapi_pdsch_pdu(processingData_L1tx_t *msgTx,
nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
uint8_t *sdu){
}
void handle_nfapi_nr_csirs_pdu(processingData_L1tx_t *msgTx,
int frame, int slot,
nfapi_nr_dl_tti_csi_rs_pdu *csirs_pdu){
}
int l1_north_init_gNB(void){return 0;}
int slot_ahead = 6;
//uint8_t nfapi_mode=0;
NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {return NULL;}
void handle_nfapi_nr_ul_dci_pdu(PHY_VARS_gNB *gNB,
int frame, int slot,
nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu){}
void nr_fill_ulsch(PHY_VARS_gNB *gNB,
int frame,
int slot,
@@ -47,8 +29,6 @@ void nr_schedule_rx_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_p
void nr_phy_config_request(NR_PHY_Config_t *gNB){}
void install_nr_schedule_handlers(NR_IF_Module_t *if_inst){}
void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp){}
bool vnf_nr_send_p5_msg(vnf_t *vnf, uint16_t p5_idx, nfapi_nr_p4_p5_message_header_t *msg, uint32_t msg_len)
-49
View File
@@ -1,49 +0,0 @@
//Dummy NR defs to avoid linking errors
#include "PHY/defs_gNB.h"
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h"
#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h"
#include "openair1/PHY/LTE_TRANSPORT/transport_common.h"
void handle_nfapi_nr_pdcch_pdu(PHY_VARS_gNB *gNB,
int frame, int slot,
nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu){}
void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu){}
void handle_nr_nfapi_pdsch_pdu(processingData_L1tx_t *msgTx,
nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
uint8_t *sdu){
}
void handle_nfapi_nr_csirs_pdu(processingData_L1tx_t *msgTx,
int frame, int slot,
nfapi_nr_dl_tti_csi_rs_pdu *csirs_pdu){
}
int l1_north_init_gNB(void){return 0;}
int slot_ahead = 6;
//uint8_t nfapi_mode=0;
NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {return NULL;}
void handle_nfapi_nr_ul_dci_pdu(PHY_VARS_gNB *gNB,
int frame, int slot,
nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu){}
void nr_fill_ulsch(PHY_VARS_gNB *gNB,
int frame,
int slot,
nfapi_nr_pusch_pdu_t *ulsch_pdu){}
void nr_fill_pucch(PHY_VARS_gNB *gNB,
int frame,
int slot,
nfapi_nr_pucch_pdu_t *pucch_pdu){}
void nr_schedule_rx_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu)
{
}
void nr_phy_config_request(NR_PHY_Config_t *gNB){}
void install_nr_schedule_handlers(NR_IF_Module_t *if_inst){}
//void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp){}
-232
View File
@@ -1,232 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file fapi_nr_l1.c
* \brief functions for FAPI L1 interface
* \author R. Knopp, WEI-TAI CHEN
* \date 2017, 2018
* \version 0.1
* \company Eurecom, NTUST
* \email: knopp@eurecom.fr, kroempa@gmail.com
* \note
* \warning
*/
#include "fapi_nr_l1.h"
#include "common/ran_context.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "PHY/NR_TRANSPORT/nr_dci.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include "openair2/NR_PHY_INTERFACE/nr_sched_response.h"
#include "nfapi/oai_integration/nfapi_vnf.h"
void handle_nr_nfapi_ssb_pdu(processingData_L1tx_t *msgTx,int frame,int slot,
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu)
{
AssertFatal(dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag== 1, "bchPayloadFlat %d != 1\n",
dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag);
uint8_t i_ssb = dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex;
LOG_D(NR_PHY,"%d.%d : ssb index %d pbch_pdu: %x\n",frame,slot,i_ssb,dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload);
if (msgTx->ssb[i_ssb].active)
AssertFatal(1==0,"SSB PDU with index %d already active\n",i_ssb);
else {
msgTx->ssb[i_ssb].active = true;
memcpy((void*)&msgTx->ssb[i_ssb].ssb_pdu,&dl_tti_pdu->ssb_pdu,sizeof(dl_tti_pdu->ssb_pdu));
}
}
void handle_nfapi_nr_csirs_pdu(processingData_L1tx_t *msgTx, int frame, int slot, nfapi_nr_dl_tti_csi_rs_pdu *csirs_pdu)
{
int found = 0;
for (int id = 0; id < NR_NUMBER_OF_SYMBOLS_PER_SLOT; id++) {
NR_gNB_CSIRS_t *csirs = &msgTx->csirs_pdu[id];
if (csirs->active == 0) {
LOG_D(NR_PHY,"Frame %d Slot %d CSI_RS with ID %d is now active\n",frame,slot,id);
csirs->active = 1;
memcpy((void*)&csirs->csirs_pdu, (void*)csirs_pdu, sizeof(nfapi_nr_dl_tti_csi_rs_pdu));
found = 1;
break;
}
}
if (found == 0)
LOG_E(MAC,"CSI-RS list is full\n");
}
void nr_schedule_dl_tti_req(PHY_VARS_gNB *gNB, nfapi_nr_dl_tti_request_t *DL_req)
{
DevAssert(gNB != NULL);
DevAssert(DL_req != NULL);
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
int frame = DL_req->SFN;
int slot = DL_req->Slot;
int slot_type = nr_slot_select(cfg, frame, slot);
DevAssert(slot_type == NR_DOWNLINK_SLOT || slot_type == NR_MIXED_SLOT);
processingData_L1tx_t *msgTx = gNB->msgDataTx;
msgTx->slot = slot;
msgTx->frame = frame;
uint8_t number_dl_pdu = DL_req->dl_tti_request_body.nPDUs;
for (int i = 0; i < number_dl_pdu; i++) {
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu = &DL_req->dl_tti_request_body.dl_tti_pdu_list[i];
LOG_D(NR_PHY, "NFAPI: dl_pdu %d : type %d\n", i, dl_tti_pdu->PDUType);
switch (dl_tti_pdu->PDUType) {
case NFAPI_NR_DL_TTI_SSB_PDU_TYPE:
handle_nr_nfapi_ssb_pdu(msgTx, frame, slot, dl_tti_pdu);
break;
case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE:
LOG_D(NR_PHY, "frame %d, slot %d, Got NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE for %d.%d\n", frame, slot, DL_req->SFN, DL_req->Slot);
msgTx->pdcch_pdu[msgTx->num_dl_pdcch] = dl_tti_pdu->pdcch_pdu;
msgTx->num_dl_pdcch++;
break;
case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE:
LOG_D(NR_PHY, "frame %d, slot %d, Got NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE for %d.%d\n", frame, slot, DL_req->SFN, DL_req->Slot);
handle_nfapi_nr_csirs_pdu(msgTx, frame, slot, &dl_tti_pdu->csi_rs_pdu);
break;
case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE:
LOG_D(NR_PHY, "frame %d, slot %d, Got NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE for %d.%d\n", frame, slot, DL_req->SFN, DL_req->Slot);
nr_fill_dlsch_dl_tti_req(msgTx, &dl_tti_pdu->pdsch_pdu);
}
}
}
void nr_schedule_ul_tti_req(PHY_VARS_gNB *gNB, nfapi_nr_ul_tti_request_t *UL_tti_req)
{
DevAssert(gNB != NULL);
DevAssert(UL_tti_req != NULL);
int frame = UL_tti_req->SFN;
int slot = UL_tti_req->Slot;
for (int i = 0; i < UL_tti_req->n_pdus; i++) {
int type = UL_tti_req->pdus_list[i].pdu_type;
LOG_D(NR_PHY,
"frame %d, slot %d got %s for %d.%d\n",
frame,
slot,
txt_nfapi_nr_ul_config_pdu_type[type],
UL_tti_req->SFN,
UL_tti_req->Slot);
switch (type) {
case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE:
nr_fill_ulsch(gNB, UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].pusch_pdu);
break;
case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE:
nr_fill_pucch(gNB, UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].pucch_pdu);
break;
case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE: {
nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu;
prach_item_t *prach = nr_schedule_rx_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu);
if (!prach)
LOG_W(NR_PHY_RACH, "Error in scheduling rach\n");
} break;
case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE:
nr_fill_srs(gNB, UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].srs_pdu);
break;
}
}
}
void nr_schedule_tx_req(PHY_VARS_gNB *gNB, nfapi_nr_tx_data_request_t *TX_req)
{
DevAssert(gNB != NULL);
DevAssert(TX_req != NULL);
processingData_L1tx_t *msgTx = gNB->msgDataTx;
for (int idx = 0; idx < TX_req->Number_of_PDUs; ++idx) {
uint8_t *sdu = (uint8_t *)TX_req->pdu_list[idx].TLVs[0].value.direct;
nr_fill_dlsch_tx_req(msgTx, idx, sdu);
}
}
void nr_schedule_ul_dci_req(PHY_VARS_gNB *gNB, nfapi_nr_ul_dci_request_t *UL_dci_req)
{
DevAssert(gNB != NULL);
DevAssert(UL_dci_req != NULL);
processingData_L1tx_t *msgTx = gNB->msgDataTx;
msgTx->num_ul_pdcch = UL_dci_req->numPdus;
for (int i = 0; i < UL_dci_req->numPdus; i++)
msgTx->ul_pdcch_pdu[i] = UL_dci_req->ul_dci_pdu_list[i];
}
void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO)
{
// copy data from L2 interface into L1 structures
module_id_t Mod_id = Sched_INFO->module_id;
frame_t frame = Sched_INFO->frame;
slot_t slot = Sched_INFO->slot;
AssertFatal(RC.gNB != NULL, "RC.gNB is null\n");
AssertFatal(RC.gNB[Mod_id] != NULL, "RC.gNB[%d] is null\n", Mod_id);
PHY_VARS_gNB *gNB = RC.gNB[Mod_id];
start_meas(&gNB->schedule_response_stats);
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
int slot_type = nr_slot_select(cfg, frame, slot);
clear_slot_beamid(gNB, slot); // reset beam_id information for the slot to be processed
DevAssert(NFAPI_MODE == NFAPI_MONOLITHIC);
bool is_dl = slot_type == NR_DOWNLINK_SLOT || slot_type == NR_MIXED_SLOT;
processingData_L1tx_t *msgTx = gNB->msgDataTx;
/* store the sched_response_id for the TX thread to release it when done */
msgTx->sched_response_id = Sched_INFO->sched_response_id;
DevAssert(Sched_INFO->DL_req.SFN == frame);
DevAssert(Sched_INFO->DL_req.Slot == slot);
if (is_dl) {
nr_schedule_dl_tti_req(gNB, &Sched_INFO->DL_req);
}
nr_schedule_ul_tti_req(gNB, &Sched_INFO->UL_tti_req);
if (is_dl) {
nr_schedule_tx_req(gNB, &Sched_INFO->TX_req);
nr_schedule_ul_dci_req(gNB, &Sched_INFO->UL_dci_req);
/* Both the current thread and the TX thread will access the sched_info
* at the same time, so increase its reference counter, so that it is
* released only when both threads are done with it.
*/
inc_ref_sched_response(Sched_INFO->sched_response_id);
}
/* this thread is done with the sched_info, decrease the reference counter */
if ((slot_type == NR_DOWNLINK_SLOT || slot_type == NR_MIXED_SLOT) && NFAPI_MODE == NFAPI_MONOLITHIC) {
LOG_D(NR_PHY, "Calling dref_sched_response for id %d in %d.%d (sched_response)\n", Sched_INFO->sched_response_id, frame, slot);
deref_sched_response(Sched_INFO->sched_response_id);
}
stop_meas(&gNB->schedule_response_stats);
}
-69
View File
@@ -1,69 +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 fapi_nr_l1.h
* \brief function prototypes for FAPI L1 interface
* \author R. Knopp, WEI-TAI CHEN
* \date 2017, 2018
* \version 0.1
* \company Eurecom, NTUST
* \email: knopp@eurecom.fr, kroempa@gmail.com
* \note
* \warning
*/
#include "PHY/defs_gNB.h"
#include "SCHED_NR/sched_nr.h"
#include "nfapi_nr_interface_scf.h"
// added
void handle_nr_nfapi_ssb_pdu(processingData_L1tx_t *msgTx,
int frame,int slot,
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu);
void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO);
void handle_nfapi_nr_csirs_pdu(processingData_L1tx_t *msgTx,
int frame, int slot,
nfapi_nr_dl_tti_csi_rs_pdu *csirs_pdu);
void handle_nfapi_nr_pdcch_pdu(PHY_VARS_gNB *gNB,
int frame, int subframe,
nfapi_nr_dl_tti_pdcch_pdu *dcl_dl_pdu);
void handle_nr_nfapi_pdsch_pdu(processingData_L1tx_t *msgTx,
nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
uint8_t *sdu);
void nr_fill_indication(PHY_VARS_gNB *gNB,
int frame,
int slot_rx,
int UE_id,
uint8_t harq_pid,
uint8_t crc_flag,
int dtx_flag,
nfapi_nr_crc_t *crc,
nfapi_nr_rx_data_pdu_t *pdu);
//added
void handle_nfapi_nr_ul_dci_pdu(PHY_VARS_gNB *gNB,
int frame, int slot,
nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu);
-1
View File
@@ -33,7 +33,6 @@
#include "PHY/defs_gNB.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "nfapi_nr_interface_scf.h"
#include "fapi_nr_l1.h"
#include "nfapi_pnf.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
+1 -1
View File
@@ -152,7 +152,7 @@ void set_tdd_config_nr(nfapi_nr_config_request_scf_t *cfg, frame_structure_t *fs
}
}
int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_slot)
int nr_slot_select(const nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_slot)
{
(void) nr_frame;
+1 -1
View File
@@ -53,7 +53,7 @@ void set_tdd_config_nr(nfapi_nr_config_request_scf_t *cfg, frame_structure_t *fs
* @param nr_slot : slot number
@returns int : downlink, uplink or mixed slot type*/
int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_slot);
int nr_slot_select(const nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_slot);
void do_tdd_config_sim(PHY_VARS_gNB *gNB, int mu);
File diff suppressed because it is too large Load Diff
+10 -3
View File
@@ -33,10 +33,17 @@
#include "phy_frame_config_nr.h"
void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME_PARMS *fp);
void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, int frame_tx, int slot_tx, int do_meas);
void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
const nfapi_nr_dl_tti_request_t *DL_req,
const nfapi_nr_tx_data_request_t *TX_req,
const nfapi_nr_ul_dci_request_t *UL_dci_req,
int frame,
int slot,
int do_meas);
void nr_save_ul_tti_req(PHY_VARS_gNB *gNB, nfapi_nr_ul_tti_request_t *UL_tti_req);
int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, NR_UL_IND_t *UL_INFO);
void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rach_indication_t *rach_ind);
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_dl_tti_ssb_pdu ssb_pdu);
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot, const nfapi_nr_dl_tti_ssb_pdu *ssb_pdu);
void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx);
void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa);
void nr_feptx_prec(RU_t *ru,int frame_tx,int tti_tx);
@@ -49,7 +56,7 @@ void nr_phy_free_RU(RU_t *ru);
void clear_slot_beamid(PHY_VARS_gNB *gNB, int slot);
int beam_index_allocation(bool das,
int fapi_beam_index,
nfapi_nr_analog_beamforming_ve_t *analog_bf,
const nfapi_nr_analog_beamforming_ve_t *analog_bf,
NR_gNB_COMMON *common_vars,
int slot,
int symbols_per_slot,
+83
View File
@@ -230,6 +230,88 @@ static void nr_ue_scheduled_response_dl(NR_UE_MAC_INST_t *mac,
dl_config->number_pdus = 0;
}
static void dump_pusch_pdu(int instance, int frame, int slot, nfapi_nr_ue_pusch_pdu_t *pusch_pdu)
{
LOG_D(PHY,
"[UE %d] %d.%d ULSCH PDU pdu_bit_map %u "
"rnti %u "
"handle %u "
"bwp_size %u "
"bwp_start %u "
"subcarrier_spacing %u "
"cyclic_prefix %u "
"target_code_rate %u "
"qam_mod_order %u "
"mcs_index %u "
"mcs_table %u "
"transform_precoding %u "
"data_scrambling_id %u "
"nrOfLayers %u "
"Tpmi %u "
"ul_dmrs_symb_pos %u "
"dmrs_config_type %u "
"ul_dmrs_scrambling_id %u "
"scid %u "
"num_dmrs_cdm_grps_no_data %u "
"dmrs_ports %u "
"resource_alloc %u "
"rb_start %u "
"rb_size %u "
"vrb_to_prb_mapping %u "
"frequency_hopping %u "
"tx_direct_current_location %u "
"uplink_frequency_shift_7p5khz %u "
"start_symbol_index %u "
"nr_of_symbols %u "
"tbslbrm %u "
"ldpcBaseGraph %u "
"ulsch_indicator %u "
"pusch_data->rv_index %u "
"pusch_data->harq_process_id %u "
"pusch_data->new_data_indicator %u "
"pusch_data->num_cb %u\n",
instance,
frame,
slot,
pusch_pdu->pdu_bit_map,
pusch_pdu->rnti,
pusch_pdu->handle,
pusch_pdu->bwp_size,
pusch_pdu->bwp_start,
pusch_pdu->subcarrier_spacing,
pusch_pdu->cyclic_prefix,
pusch_pdu->target_code_rate,
pusch_pdu->qam_mod_order,
pusch_pdu->mcs_index,
pusch_pdu->mcs_table,
pusch_pdu->transform_precoding,
pusch_pdu->data_scrambling_id,
pusch_pdu->nrOfLayers,
pusch_pdu->Tpmi,
pusch_pdu->ul_dmrs_symb_pos,
pusch_pdu->dmrs_config_type,
pusch_pdu->ul_dmrs_scrambling_id,
pusch_pdu->scid,
pusch_pdu->num_dmrs_cdm_grps_no_data,
pusch_pdu->dmrs_ports,
pusch_pdu->resource_alloc,
pusch_pdu->rb_start,
pusch_pdu->rb_size,
pusch_pdu->vrb_to_prb_mapping,
pusch_pdu->frequency_hopping,
pusch_pdu->tx_direct_current_location,
pusch_pdu->uplink_frequency_shift_7p5khz,
pusch_pdu->start_symbol_index,
pusch_pdu->nr_of_symbols,
pusch_pdu->tbslbrm,
pusch_pdu->ldpcBaseGraph,
pusch_pdu->ulsch_indicator,
pusch_pdu->pusch_data.rv_index,
pusch_pdu->pusch_data.harq_process_id,
pusch_pdu->pusch_data.new_data_indicator,
pusch_pdu->pusch_data.num_cb);
}
static void nr_ue_scheduled_response_ul(PHY_VARS_NR_UE *phy, fapi_nr_ul_config_request_t *ul_config, nr_phy_data_tx_t *phy_data)
{
fapi_nr_ul_config_request_pdu_t *pdu = fapiLockIterator(ul_config, ul_config->frame, ul_config->slot);
@@ -251,6 +333,7 @@ static void nr_ue_scheduled_response_ul(PHY_VARS_NR_UE *phy, fapi_nr_ul_config_r
pdu->pusch_config_pdu.num_dmrs_cdm_grps_no_data);
memcpy(pusch_pdu, &pdu->pusch_config_pdu, sizeof(*pusch_pdu));
dump_pusch_pdu(phy->Mod_id, ul_config->frame, ul_config->slot, pusch_pdu);
if (pdu->pusch_config_pdu.tx_request_body.fapiTxPdu) {
LOG_D(PHY,
"%d.%d Copying %d bytes to harq_process_ul_ue->a (harq_pid %d)\n",
+22 -23
View File
@@ -439,10 +439,7 @@ int main(int argc, char **argv)
nr_init_dl_harq_processes(UE->dl_harq_processes, 8, nb_rb);
unsigned char harq_pid = 0; //dlsch->harq_ids[subframe];
processingData_L1tx_t msgDataTx;
init_DLSCH_struct(gNB, &msgDataTx);
NR_gNB_DLSCH_t *dlsch = &msgDataTx.dlsch[0][0];
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->harq_process.pdsch_pdu.pdsch_pdu_rel15;
NR_gNB_DLSCH_t *dlsch = &gNB->dlsch[0];
//time_stats_t *rm_stats, *te_stats, *i_stats;
unsigned int TBS = 8424;
uint8_t nb_re_dmrs = 6; // No data in dmrs symbol
@@ -459,19 +456,24 @@ int main(int argc, char **argv)
TBS = nr_compute_tbs(mod_order,rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, 0, Nl);
printf("available bits %u TBS %u mod_order %d\n", available_bits, TBS, mod_order);
//dlsch->harq_ids[subframe]= 0;
rel15->rbSize = nb_rb;
rel15->NrOfSymbols = nb_symb_sch;
rel15->qamModOrder[0] = mod_order;
rel15->nrOfLayers = Nl;
rel15->TBSize[0] = TBS>>3;
rel15->targetCodeRate[0] = rate;
rel15->NrOfCodewords = 1;
rel15->dmrsConfigType = NFAPI_NR_DMRS_TYPE1;
rel15->dlDmrsSymbPos = 4;
rel15->mcsIndex[0] = Imcs;
rel15->numDmrsCdmGrpsNoData = 1;
rel15->maintenance_parms_v3.tbSizeLbrmBytes = Tbslbrm;
rel15->maintenance_parms_v3.ldpcBaseGraph = get_BG(TBS, rate);
nfapi_nr_dl_tti_pdsch_pdu pdsch_pdu = {
.pdsch_pdu_rel15 = {
.rbSize = nb_rb,
.NrOfSymbols = nb_symb_sch,
.qamModOrder[0] = mod_order,
.nrOfLayers = Nl,
.TBSize[0] = TBS >> 3,
.targetCodeRate[0] = rate,
.NrOfCodewords = 1,
.dmrsConfigType = NFAPI_NR_DMRS_TYPE1,
.dlDmrsSymbPos = 4,
.mcsIndex[0] = Imcs,
.numDmrsCdmGrpsNoData = 1,
.maintenance_parms_v3.tbSizeLbrmBytes = Tbslbrm,
.maintenance_parms_v3.ldpcBaseGraph = get_BG(TBS, rate),
},
};
dlsch->pdsch_pdu = &pdsch_pdu;
double modulated_input[16 * 68 * 384]; // [hna] 16 segments, 68*Zc
short channel_output_fixed[16 * 68 * 384];
//unsigned char *estimated_output;
@@ -498,7 +500,7 @@ int main(int argc, char **argv)
printf("harq process ue mcs = %d Qm = %d, symb %d\n", dlsch0_ue->dlsch_config.mcs, dlsch0_ue->dlsch_config.qamModOrder, nb_symb_sch);
uint8_t test_input[TBS / 8 + 4]; // + 3 for CRC + 1 additional byte, see nr_dlsch_encoding()
dlsch->harq_process.pdu = test_input;
dlsch->pdu = test_input;
//unsigned char test_input[TBS / 8] __attribute__ ((aligned(16)));
for (i = 0; i < TBS / 8; i++)
test_input[i] = (unsigned char) rand();
@@ -512,11 +514,10 @@ int main(int argc, char **argv)
//printf("crc32: [0]->0x%08x\n",crc24c(test_input, 32));
// generate signal
unsigned char output[rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * NR_MAX_NB_LAYERS] __attribute__((aligned(64)));
unsigned char output[nb_rb * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * NR_MAX_NB_LAYERS] __attribute__((aligned(64)));
bzero(output, sizeof(output));
if (input_fd == NULL) {
msgDataTx.num_pdsch_slot = 1;
nr_dlsch_encoding(gNB, &msgDataTx, frame, slot, frame_parms, output, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
nr_dlsch_encoding(gNB, 1, dlsch, frame, slot, frame_parms, output, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
}
for (SNR = snr0; SNR < snr1 && !stop; SNR += snr_step) {
@@ -622,8 +623,6 @@ int main(int argc, char **argv)
free_channel_desc_scm(gNB2UE);
reset_DLSCH_struct(gNB, &msgDataTx);
int nb_slots_to_set = (1 << mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
for (int i = 0; i < nb_slots_to_set; ++i)
free(gNB->gNB_config.tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list);
+30 -45
View File
@@ -62,7 +62,6 @@
#include "PHY/defs_nr_common.h"
#include "PHY/impl_defs_nr.h"
#include "PHY/phy_vars_nr_ue.h"
#include "SCHED_NR/fapi_nr_l1.h"
#include "SCHED_NR/sched_nr.h"
#include "SCHED_NR_UE/defs.h"
#include "SCHED_NR_UE/fapi_nr_ue_l1.h"
@@ -286,7 +285,6 @@ nrUE_params_t *get_nrUE_params(void) {
return &nrUE_params;
}
void validate_input_pmi(nfapi_nr_config_request_scf_t *gNB_config,
nr_pdsch_AntennaPorts_t pdsch_AntennaPorts,
int nrOfLayers,
@@ -974,13 +972,6 @@ int main(int argc, char **argv)
int ret = 1;
initNamedTpool(gNBthreads, &gNB->threadPool, true, "gNB-tpool");
initNotifiedFIFO(&gNB->L1_tx_out);
// we create 2 threads for L1 tx processing
processingData_L1tx_t *msgDataTx = malloc(sizeof(processingData_L1tx_t));
init_DLSCH_struct(gNB, msgDataTx);
msgDataTx->slot = slot;
msgDataTx->frame = frame;
memset(msgDataTx->ssb, 0, 64*sizeof(NR_gNB_SSB_t));
gNB->msgDataTx = msgDataTx;
// Buffers to store internal memory of slot process
int rx_size = (((14 * UE->frame_parms.N_RB_DL * 12 * sizeof(int32_t)) + 15) >> 4) << 4;
@@ -1059,8 +1050,13 @@ int main(int argc, char **argv)
n_false_positive = 0;
if (n_trials== 1) num_rounds = 1;
NR_gNB_DLSCH_t *gNB_dlsch = &msgDataTx->dlsch[0][0];
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &gNB_dlsch->harq_process.pdsch_pdu.pdsch_pdu_rel15;
NR_gNB_DLSCH_t *gNB_dlsch = &gNB->dlsch[0];
memset(Sched_INFO, 0, sizeof(*Sched_INFO));
Sched_INFO->sched_response_id = -1;
nfapi_nr_dl_tti_request_body_t *dl_req = &Sched_INFO->DL_req.dl_tti_request_body;
// scheduler will place PDSCH second (after PDCCH), verification below
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[1];
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
for (trial = 0; trial < n_trials && !stop; trial++) {
@@ -1082,11 +1078,9 @@ int main(int argc, char **argv)
UE_harq_process->DLround = round;
UE_harq_process->first_rx = 1;
memset(Sched_INFO, 0, sizeof(*Sched_INFO));
Sched_INFO->sched_response_id = -1;
while (round < num_rounds && !UE_harq_process->decodeResult && !stop) {
clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot, &Sched_INFO->DL_req, &Sched_INFO->TX_req, &Sched_INFO->UL_dci_req);
reset_sched_response(Sched_INFO, frame, slot, 0, 0);
clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot);
UE_info->UE_sched_ctrl.harq_processes[harq_pid].ndi = !(trial&1);
UE_info->UE_sched_ctrl.harq_processes[harq_pid].round = round;
@@ -1094,18 +1088,13 @@ int main(int argc, char **argv)
NR_SCHED_LOCK(&gNB_mac->sched_lock);
nr_schedule_ue_spec(0, frame, slot, &Sched_INFO->DL_req, &Sched_INFO->TX_req);
NR_SCHED_UNLOCK(&gNB_mac->sched_lock);
Sched_INFO->module_id = 0;
Sched_INFO->CC_id = 0;
Sched_INFO->frame = frame;
Sched_INFO->slot = slot;
Sched_INFO->UL_dci_req.numPdus = 0;
nr_schedule_response(Sched_INFO);
/* check that second message is indeed PDSCH */
DevAssert(dl_tti_pdsch_pdu->PDUType == NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE);
/* PTRS values for DLSIM calculations */
nfapi_nr_dl_tti_request_body_t *dl_req = &Sched_INFO->DL_req.dl_tti_request_body;
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[1];
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
pdu_bit_map = pdsch_pdu_rel15->pduBitmap;
// This is already in DL procedures??
if(pdu_bit_map & 0x1) {
set_ptrs_symb_idx(&dlPtrsSymPos,
pdsch_pdu_rel15->NrOfSymbols,
@@ -1113,16 +1102,12 @@ int main(int argc, char **argv)
1<<pdsch_pdu_rel15->PTRSTimeDensity,
pdsch_pdu_rel15->dlDmrsSymbPos);
ptrsSymbPerSlot = get_ptrs_symbols_in_slot(dlPtrsSymPos, pdsch_pdu_rel15->StartSymbolIndex, pdsch_pdu_rel15->NrOfSymbols);
ptrsRePerSymb = ((rel15->rbSize + rel15->PTRSFreqDensity - 1) / rel15->PTRSFreqDensity);
ptrsRePerSymb = ((pdsch_pdu_rel15->rbSize + pdsch_pdu_rel15->PTRSFreqDensity - 1) / pdsch_pdu_rel15->PTRSFreqDensity);
LOG_D(PHY,"[DLSIM] PTRS Symbols in a slot: %2u, RE per Symbol: %3u, RE in a slot %4d\n", ptrsSymbPerSlot, ptrsRePerSymb, ptrsSymbPerSlot * ptrsRePerSymb);
}
msgDataTx->ssb[0].ssb_pdu.ssb_pdu_rel15.bchPayload=0x001234;
msgDataTx->ssb[0].ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = 0;
msgDataTx->gNB = gNB;
start_meas(&gNB->phy_proc_tx);
phy_procedures_gNB_TX(msgDataTx,frame,slot,1);
phy_procedures_gNB_TX(gNB, &Sched_INFO->DL_req, &Sched_INFO->TX_req, &Sched_INFO->UL_dci_req, frame, slot, 1);
stop_meas(&gNB->phy_proc_tx);
int txdataF_offset = slot * frame_parms->samples_per_slot_wCP;
@@ -1197,9 +1182,9 @@ int main(int argc, char **argv)
double ts = 1.0/(frame_parms->subcarrier_spacing * frame_parms->ofdm_symbol_size);
//Compute AWGN variance
sigma2_dB = 10 * log10((double)txlev_sum * ((double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize))) - SNR;
sigma2_dB = 10 * log10((double)txlev_sum * ((double)UE->frame_parms.ofdm_symbol_size/(12*pdsch_pdu_rel15->rbSize))) - SNR;
sigma2 = pow(10, sigma2_dB/10);
if (n_trials==1) printf("sigma2 %f (%f dB), txlev_sum %f (factor %f)\n",sigma2,sigma2_dB,10*log10((double)txlev_sum),(double)(double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize));
if (n_trials==1) printf("sigma2 %f (%f dB), txlev_sum %f (factor %f)\n",sigma2,sigma2_dB,10*log10((double)txlev_sum),(double)(double)UE->frame_parms.ofdm_symbol_size/(12*pdsch_pdu_rel15->rbSize));
for (aa = 0; aa < n_rx; aa++) {
bzero(r_re[aa], slot_length * sizeof(double));
@@ -1241,22 +1226,22 @@ int main(int argc, char **argv)
int16_t *UE_llr = (int16_t*)UE->phy_sim_pdsch_llr;
TBS = dlsch0->dlsch_config.TBS;//rel15->TBSize[0];
TBS = dlsch0->dlsch_config.TBS;
uint16_t length_dmrs = get_num_dmrs(dlsch0->dlsch_config.dlDmrsSymbPos);
uint16_t nb_rb = dlsch0->dlsch_config.number_rbs;
uint8_t nb_re_dmrs = dlsch0->dlsch_config.dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6*dlsch0->dlsch_config.n_dmrs_cdm_groups : 4*dlsch0->dlsch_config.n_dmrs_cdm_groups;
uint8_t mod_order = dlsch0->dlsch_config.qamModOrder;
uint8_t nb_symb_sch = dlsch0->dlsch_config.number_symbols;
uint32_t unav_res = ptrsSymbPerSlot * ptrsRePerSymb;
available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, unav_res, mod_order, rel15->nrOfLayers);
available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, unav_res, mod_order, pdsch_pdu_rel15->nrOfLayers);
if (pdu_bit_map & 0x1) {
if (trial == 0 && round == 0) {
printf("[DLSIM][PTRS] Available bits are: %5u, removed PTRS bits are: %5u \n", available_bits, (ptrsSymbPerSlot * ptrsRePerSymb * rel15->nrOfLayers * mod_order));
printf("[DLSIM][PTRS] Available bits are: %5u, removed PTRS bits are: %5u \n", available_bits, (ptrsSymbPerSlot * ptrsRePerSymb * pdsch_pdu_rel15->nrOfLayers * mod_order));
}
}
for (i = 0; i < available_bits; i++) {
const uint8_t current_bit = (gNB_dlsch->harq_process.f[i / 8] & (1 << (i & 7))) >> (i & 7);
const uint8_t current_bit = (gNB_dlsch->f[i / 8] & (1 << (i & 7))) >> (i & 7);
if (((current_bit == 0) && (UE_llr[i] <= 0)) || ((current_bit == 1) && (UE_llr[i] >= 0))) {
if (errors_scrambling[round] == 0) {
LOG_D(PHY,"First bit in error in unscrambling = %d\n",i);
@@ -1270,13 +1255,13 @@ int main(int argc, char **argv)
} // round
if (test_input_bit == NULL) {
test_input_bit = (unsigned char *)malloc16(8 * rel15->TBSize[0]);
estimated_output_bit = (unsigned char *)malloc16(8 * rel15->TBSize[0]);
test_input_bit = (unsigned char *)malloc16(8 * pdsch_pdu_rel15->TBSize[0]);
estimated_output_bit = (unsigned char *)malloc16(8 * pdsch_pdu_rel15->TBSize[0]);
}
for (i = 0; i < TBS; i++) {
estimated_output_bit[i] = (UE->phy_sim_dlsch_b[i/8] & (1 << (i & 7))) >> (i & 7);
test_input_bit[i] = (gNB_dlsch->harq_process.b[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments
test_input_bit[i] = (gNB_dlsch->b[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments
if (estimated_output_bit[i] != test_input_bit[i]) {
if(errors_bit == 0)
@@ -1320,7 +1305,7 @@ int main(int argc, char **argv)
printf("), Channel BER (%e", berStats[0]);
for (int r = 1; r < num_rounds; r++)
printf(",%e", berStats[r]);
printf(") Avg round %.2f, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %u bits/slot\n", roundStats, effRate, effRate / (8 * rel15->TBSize[0]) * 100, 8 * rel15->TBSize[0]);
printf(") Avg round %.2f, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %u bits/slot\n", roundStats, effRate, effRate / (8 * pdsch_pdu_rel15->TBSize[0]) * 100, 8 * pdsch_pdu_rel15->TBSize[0]);
printf("*****************************************\n");
printf("\n");
// writing to csv file
@@ -1328,7 +1313,7 @@ int main(int argc, char **argv)
fprintf(csv_file,"%f,%d/%d,",SNR,n_false_positive,n_trials);
for (int r = 0; r < num_rounds; r++)
fprintf(csv_file,"%d/%d,%u/%u,%f,%e,",n_errors[r], round_trials[r], errors_scrambling[r], available_bits * round_trials[r],blerStats[r],berStats[r]);
fprintf(csv_file,"%.2f,%.4f,%.2f,%u\n", roundStats, effRate, effRate / (8 * rel15->TBSize[0]) * 100, 8 * rel15->TBSize[0]);
fprintf(csv_file,"%.2f,%.4f,%.2f,%u\n", roundStats, effRate, effRate / (8 * pdsch_pdu_rel15->TBSize[0]) * 100, 8 * pdsch_pdu_rel15->TBSize[0]);
}
if (print_perf==1) {
printf("\ngNB TX function statistics (per %d us slot, NPRB %d, mcs %d, C %d, block %d)\n",
@@ -1336,7 +1321,7 @@ int main(int argc, char **argv)
g_rbSize,
g_mcsIndex,
UE->dl_harq_processes[0][slot].C,
8 * rel15->TBSize[0]);
8 * pdsch_pdu_rel15->TBSize[0]);
printDistribution(&gNB->phy_proc_tx,table_tx,"PHY proc tx");
printStatIndent2(&gNB->dci_generation_stats, "DCI encoding time");
printStatIndent2(&gNB->dlsch_encoding_stats,"DLSCH encoding time");
@@ -1378,8 +1363,8 @@ int main(int argc, char **argv)
const uint32_t numReSym = (g_rbSize * 12 + 15) & (~15);
for (int l = 0; l < g_nrOfLayers; l++) {
for (int r = 0; r < n_rx; r++) {
const int s = rel15->StartSymbolIndex;
const int n = rel15->NrOfSymbols;
const int s = pdsch_pdu_rel15->StartSymbolIndex;
const int n = pdsch_pdu_rel15->NrOfSymbols;
for (int i = s; i < s + n; i++) {
const uint32_t dmrsBitMap = phy_data.dlsch[0].dlsch_config.dlDmrsSymbPos;
const uint32_t dmrsCfg = phy_data.dlsch[0].dlsch_config.dmrsConfigType;
@@ -1415,7 +1400,7 @@ int main(int argc, char **argv)
break;
}
if (effRate >= (eff_tp_check * 8 * rel15->TBSize[0])) {
if (effRate >= (eff_tp_check * 8 * pdsch_pdu_rel15->TBSize[0])) {
printf("PDSCH test OK\n");
ret = 0;
break;
+7 -7
View File
@@ -519,10 +519,10 @@ int main(int argc, char **argv)
exit(-1);
}
processingData_L1tx_t msgDataTx;
// generate signal
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];
nfapi_nr_dl_tti_ssb_pdu ssb_pdu[64] = {0};
if (input_fd==NULL) {
for (i=0; i<frame_parms->Lmax; i++) {
@@ -530,10 +530,10 @@ int main(int argc, char **argv)
const int sc_offset = frame_parms->freq_range == FR1 ? ssb_subcarrier_offset<<mu : ssb_subcarrier_offset;
const int prb_offset = frame_parms->freq_range == FR1 ? gNB->gNB_config.ssb_table.ssb_offset_point_a.value<<mu : gNB->gNB_config.ssb_table.ssb_offset_point_a.value << (mu - 2);
msgDataTx.ssb[i].ssb_pdu.ssb_pdu_rel15.bchPayload = 0x55dd33;
msgDataTx.ssb[i].ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = i;
msgDataTx.ssb[i].ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = sc_offset;
msgDataTx.ssb[i].ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = prb_offset;
ssb_pdu[i].ssb_pdu_rel15.bchPayload = 0x55dd33;
ssb_pdu[i].ssb_pdu_rel15.SsbBlockIndex = i;
ssb_pdu[i].ssb_pdu_rel15.SsbSubcarrierOffset = sc_offset;
ssb_pdu[i].ssb_pdu_rel15.ssbOffsetPointA = prb_offset;
start_symbol = nr_get_ssb_start_symbol(frame_parms,i);
int slot = start_symbol/14;
@@ -541,7 +541,7 @@ int main(int argc, char **argv)
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++)
memset(gNB->common_vars.txdataF[0][aa], 0, frame_parms->samples_per_slot_wCP * sizeof(int32_t));
nr_common_signal_procedures (gNB,frame,slot,msgDataTx.ssb[i].ssb_pdu);
nr_common_signal_procedures (gNB,frame,slot, &ssb_pdu[i]);
int samp = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0);
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
@@ -744,7 +744,7 @@ int main(int argc, char **argv)
gNB->gNB_config.ssb_table.ssb_subcarrier_offset.value,
frame_parms->Lmax);
int payload_ret = (result.xtra_byte == xtra_byte);
nfapi_nr_dl_tti_ssb_pdu_rel15_t *pdu = &msgDataTx.ssb[ssb_index].ssb_pdu.ssb_pdu_rel15;
nfapi_nr_dl_tti_ssb_pdu_rel15_t *pdu = &ssb_pdu[ssb_index].ssb_pdu_rel15;
for (int i = 0; i < 3; i++)
payload_ret += (result.decoded_output[i] == ((pdu->bchPayload >> (8 * i)) & 0xff));
// printf("ret %d\n", payload_ret);
+3 -9
View File
@@ -60,7 +60,6 @@
#include "PHY/defs_nr_common.h"
#include "PHY/impl_defs_nr.h"
#include "PHY/phy_vars_nr_ue.h"
#include "SCHED_NR/fapi_nr_l1.h"
#include "SCHED_NR/sched_nr.h"
#include "SCHED_NR_UE/defs.h"
#include "SCHED_NR_UE/fapi_nr_ue_l1.h"
@@ -727,11 +726,6 @@ int main(int argc, char *argv[])
else
initNamedTpool(gNBthreads, &gNB->threadPool, true, "gNB-tpool");
processingData_L1tx_t *msgDataTx = malloc(sizeof(processingData_L1tx_t));
msgDataTx->slot = -1;
gNB->msgDataTx = msgDataTx;
//gNB_config = &gNB->gNB_config;
NR_UL_IND_t UL_INFO = {0};
UL_INFO.crc_ind.crc_list = UL_INFO.crc_pdu_list;
UL_INFO.rx_ind.pdu_list = UL_INFO.rx_pdu_list;
@@ -1284,6 +1278,9 @@ int main(int argc, char *argv[])
srs_pdu->beamforming.prg_size = 1;
}
/* load FAPI into RX of L1 */
nr_save_ul_tti_req(gNB, &Sched_INFO->UL_tti_req);
/// UE UL PDUs
UE->ul_harq_processes[harq_pid].round = round;
@@ -1291,9 +1288,6 @@ int main(int argc, char *argv[])
UE_proc.frame_tx = frame;
UE_proc.gNB_id = 0;
// prepare ULSCH/PUSCH reception
nr_schedule_response(Sched_INFO);
// --------- setting parameters for UE --------
nr_scheduled_response_t scheduled_response = {.ul_config = &ul_config, .phy_data = (void *)&phy_data};
+11
View File
@@ -475,6 +475,14 @@ typedef struct pdu_session_to_mod_s {
DRB_nGRAN_to_mod_t DRBnGRanModList[E1AP_MAX_NUM_DRBS];
} pdu_session_to_mod_t;
/** PDU Session Resource To Remove List (3GPP TS 38.463 clause 9.3.3.12) */
typedef struct {
// PDU Session ID (M)
long sessionId;
// Cause (O)
e1ap_cause_t cause;
} pdu_session_to_remove_t;
/**
* Bearer Context Setup Request message, clause 9.2.2.1 of 3GPP TS 38.463
*/
@@ -534,6 +542,9 @@ typedef struct e1ap_bearer_mod_req_s {
// NG-RAN PDU Session Resource To Modify List (O)
int numPDUSessionsMod;
pdu_session_to_mod_t pduSessionMod[E1AP_MAX_NUM_PDU_SESSIONS];
// NG-RAN PDU Session Resource To Remove List (O)
int numPDUSessionsRem;
pdu_session_to_remove_t pduSessionRem[E1AP_MAX_NUM_PDU_SESSIONS];
} e1ap_bearer_mod_req_t;
typedef struct e1ap_bearer_release_cmd_s {
+158 -119
View File
@@ -1631,6 +1631,20 @@ E1AP_E1AP_PDU_t *encode_E1_bearer_context_mod_request(const e1ap_bearer_mod_req_
*ieC3_1 = e1_encode_pdu_session_to_mod_item(i);
}
}
// NG-RAN PDU Session Resource To Remove List (O)
if (in->numPDUSessionsRem) {
asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationRequestIEs_t, remList);
E1AP_NG_RAN_BearerContextModificationRequest_t *msgNGRAN = encode_ng_ran_to_mod(remList);
msgNGRAN->id = E1AP_ProtocolIE_ID_id_PDU_Session_Resource_To_Remove_List;
msgNGRAN->criticality = E1AP_Criticality_reject;
msgNGRAN->value.present = E1AP_NG_RAN_BearerContextModificationRequest__value_PR_PDU_Session_Resource_To_Remove_List;
E1AP_PDU_Session_Resource_To_Remove_List_t *pdu2Remove = &msgNGRAN->value.choice.PDU_Session_Resource_To_Remove_List;
for (const pdu_session_to_remove_t *i = in->pduSessionRem; i < in->pduSessionRem + in->numPDUSessionsRem; i++) {
asn1cSequenceAdd(pdu2Remove->list, E1AP_PDU_Session_Resource_To_Remove_Item_t, ieC4_1);
ieC4_1->pDU_Session_ID = i->sessionId;
}
}
return pdu;
}
@@ -1854,6 +1868,19 @@ bool decode_E1_bearer_context_mod_request(const E1AP_E1AP_PDU_t *pdu, e1ap_beare
CHECK_E1AP_DEC(e1_decode_pdu_session_to_mod_item(out->pduSessionMod + i, modList->list.array[i]));
}
break;
case E1AP_ProtocolIE_ID_id_PDU_Session_Resource_To_Remove_List:
/* PDU Session Resource To Remove List (see 9.3.3.12 of TS 38.463) */
_E1_EQ_CHECK_INT(msgNGRAN->value.present,
E1AP_NG_RAN_BearerContextModificationRequest__value_PR_PDU_Session_Resource_To_Remove_List);
E1AP_PDU_Session_Resource_To_Remove_List_t *remList = &msgNGRAN->value.choice.PDU_Session_Resource_To_Remove_List;
out->numPDUSessionsRem = remList->list.count;
// Loop through all PDU sessions to remove
for (int i = 0; i < remList->list.count; i++) {
E1AP_PDU_Session_Resource_To_Remove_Item_t *remItem = remList->list.array[i];
pdu_session_to_remove_t *pduRem = &out->pduSessionRem[i];
pduRem->sessionId = remItem->pDU_Session_ID;
}
break;
default:
PRINT_ERROR("Unknown msgNGRAN->id in E1 Setup Modification Request\n");
return false;
@@ -1924,6 +1951,9 @@ e1ap_bearer_mod_req_t cp_bearer_context_mod_request(const e1ap_bearer_mod_req_t
cp.pduSession[i] = cp_pdu_session_item(&msg->pduSession[i]);
for (int i = 0; i < msg->numPDUSessionsMod; i++)
cp.pduSessionMod[i] = cp_pdu_session_to_mod_item(&msg->pduSessionMod[i]);
// Copy PDU sessions to remove (simple struct copy, no deep copy needed)
for (int i = 0; i < msg->numPDUSessionsRem; i++)
cp.pduSessionRem[i] = msg->pduSessionRem[i];
return cp;
}
@@ -2037,6 +2067,15 @@ bool eq_bearer_context_mod_request(const e1ap_bearer_mod_req_t *a, const e1ap_be
if (!eq_pdu_session_to_mod_item(&a->pduSessionMod[i], &b->pduSessionMod[i]))
return false;
}
// PDU Sessions to Remove
_E1_EQ_CHECK_INT(a->numPDUSessionsRem, b->numPDUSessionsRem);
for (int i = 0; i < a->numPDUSessionsRem; i++) {
const pdu_session_to_remove_t *pduRemA = &a->pduSessionRem[i];
const pdu_session_to_remove_t *pduRemB = &b->pduSessionRem[i];
_E1_EQ_CHECK_LONG(pduRemA->sessionId, pduRemB->sessionId);
_E1_EQ_CHECK_INT(pduRemA->cause.type, pduRemB->cause.type);
_E1_EQ_CHECK_INT(pduRemA->cause.value, pduRemB->cause.value);
}
return true;
}
@@ -2114,129 +2153,129 @@ struct E1AP_E1AP_PDU *encode_E1_bearer_context_mod_response(const e1ap_bearer_mo
ie2->criticality = E1AP_Criticality_reject;
ie2->value.present = E1AP_BearerContextModificationResponseIEs__value_PR_GNB_CU_UP_UE_E1AP_ID;
ie2->value.choice.GNB_CU_UP_UE_E1AP_ID = msg->gNB_cu_up_ue_id;
// NG-RAN PDU Session Resource Modified List (O)
asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationResponseIEs_t, ie3);
ie3->id = E1AP_ProtocolIE_ID_id_System_BearerContextModificationResponse;
ie3->criticality = E1AP_Criticality_ignore;
// CHOICE System (O)
ie3->value.present = E1AP_BearerContextModificationResponseIEs__value_PR_System_BearerContextModificationResponse;
E1AP_System_BearerContextModificationResponse_t *sys = &ie3->value.choice.System_BearerContextModificationResponse;
// NG-RAN
E1AP_ProtocolIE_Container_4932P29_t *ngran = calloc_or_fail(1, sizeof(*ngran));
sys->present = E1AP_System_BearerContextModificationResponse_PR_nG_RAN_BearerContextModificationResponse;
sys->choice.nG_RAN_BearerContextModificationResponse = (struct E1AP_ProtocolIE_Container *)ngran;
asn1cSequenceAdd(ngran->list, E1AP_NG_RAN_BearerContextModificationResponse_t, list);
// PDU Session Resource Modified List (O)
list->id = E1AP_ProtocolIE_ID_id_PDU_Session_Resource_Modified_List;
list->criticality = E1AP_Criticality_reject;
list->value.present = E1AP_NG_RAN_BearerContextModificationResponse__value_PR_PDU_Session_Resource_Modified_List;
E1AP_PDU_Session_Resource_Modified_List_t *pdu_mod_l = &list->value.choice.PDU_Session_Resource_Modified_List;
for (int i = 0; i < msg->numPDUSessionsMod; ++i) {
// PDU Session Resource Modified Item (1..maxnoofPDUSessionResource)
const pdu_session_modif_t *pdu = &msg->pduSessionMod[i];
asn1cSequenceAdd(pdu_mod_l->list, E1AP_PDU_Session_Resource_Modified_Item_t, iePdu);
// PDU Session ID (M)
iePdu->pDU_Session_ID = pdu->id;
// Security Result (O)
if (pdu->confidentialityProtectionIndication || pdu->integrityProtectionIndication) {
iePdu->securityResult = calloc_or_fail(1, sizeof(*iePdu->securityResult));
if (pdu->confidentialityProtectionIndication)
iePdu->securityResult->confidentialityProtectionResult = *pdu->confidentialityProtectionIndication;
if (pdu->integrityProtectionIndication)
iePdu->securityResult->integrityProtectionResult = *pdu->integrityProtectionIndication;
}
// NG DL UP Transport Layer Information (O)
if (pdu->ng_DL_UP_TL_info) {
iePdu->nG_DL_UP_TNL_Information = calloc_or_fail(1, sizeof(*iePdu->nG_DL_UP_TNL_Information));
*iePdu->nG_DL_UP_TNL_Information = e1_encode_up_tnl_info(pdu->ng_DL_UP_TL_info);
}
// DRB Modified List (O)
if (pdu->numDRBModified > 0) {
iePdu->dRB_Modified_List_NG_RAN = calloc_or_fail(1, sizeof(*iePdu->dRB_Modified_List_NG_RAN));
E1AP_DRB_Modified_List_NG_RAN_t *drb_mod_l = iePdu->dRB_Modified_List_NG_RAN;
for (int j = 0; j < pdu->numDRBModified; ++j) {
const DRB_nGRAN_modified_t *drb = &pdu->DRBnGRanModList[j];
asn1cSequenceAdd(drb_mod_l->list, E1AP_DRB_Modified_Item_NG_RAN_t, drb_mod);
// DRB ID (M)
drb_mod->dRB_ID = drb->id;
// Flow Setup List (O)
if (drb->numQosFlowSetup)
drb_mod->flow_Setup_List = calloc_or_fail(1, sizeof(*drb_mod->flow_Setup_List));
for (int q = 0; q < drb->numQosFlowSetup; ++q) {
asn1cSequenceAdd(drb_mod->flow_Setup_List->list, E1AP_QoS_Flow_Item_t, qos_mod);
qos_mod->qoS_Flow_Identifier = drb->qosFlows[q].qfi;
}
// Flow Failed List (O)
if (drb->numQosFlowFailed)
drb_mod->flow_Failed_List = calloc_or_fail(1, sizeof(*drb_mod->flow_Failed_List));
for (int q = 0; q < drb->numQosFlowFailed; ++q) {
asn1cSequenceAdd(drb_mod->flow_Failed_List->list, E1AP_QoS_Flow_Failed_Item_t, fail);
encode_qos_flow_failed_item(fail, &drb->qosFlowsFailed[q]);
}
// PDCP Status Information (O)
if (drb->pdcp_status) {
asn1cCalloc(drb_mod->pDCP_SN_Status_Information, pdcp);
*pdcp = encode_pdcp_status_info(drb->pdcp_status);
}
// UL UP Parameters (O)
if (drb->numUpParam)
drb_mod->uL_UP_Transport_Parameters = calloc_or_fail(1, sizeof(*drb_mod->uL_UP_Transport_Parameters));
for (const up_params_t *k = drb->ul_UP_Params; k < drb->ul_UP_Params + drb->numUpParam; k++) {
asn1cSequenceAdd(drb_mod->uL_UP_Transport_Parameters->list, E1AP_UP_Parameters_Item_t, up);
up->uP_TNL_Information = e1_encode_up_tnl_info(&k->tl_info);
up->cell_Group_ID = k->cell_group_id;
if (msg->numPDUSessionsMod > 0) {
// NG-RAN PDU Session Resource Modified List (O)
asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationResponseIEs_t, ie3);
ie3->id = E1AP_ProtocolIE_ID_id_System_BearerContextModificationResponse;
ie3->criticality = E1AP_Criticality_ignore;
// CHOICE System (O)
ie3->value.present = E1AP_BearerContextModificationResponseIEs__value_PR_System_BearerContextModificationResponse;
E1AP_System_BearerContextModificationResponse_t *sys = &ie3->value.choice.System_BearerContextModificationResponse;
// NG-RAN
E1AP_ProtocolIE_Container_4932P29_t *ngran = calloc_or_fail(1, sizeof(*ngran));
sys->present = E1AP_System_BearerContextModificationResponse_PR_nG_RAN_BearerContextModificationResponse;
sys->choice.nG_RAN_BearerContextModificationResponse = (struct E1AP_ProtocolIE_Container *)ngran;
asn1cSequenceAdd(ngran->list, E1AP_NG_RAN_BearerContextModificationResponse_t, list);
// PDU Session Resource Modified List (O)
list->id = E1AP_ProtocolIE_ID_id_PDU_Session_Resource_Modified_List;
list->criticality = E1AP_Criticality_reject;
list->value.present = E1AP_NG_RAN_BearerContextModificationResponse__value_PR_PDU_Session_Resource_Modified_List;
E1AP_PDU_Session_Resource_Modified_List_t *pdu_mod_l = &list->value.choice.PDU_Session_Resource_Modified_List;
for (int i = 0; i < msg->numPDUSessionsMod; ++i) {
// PDU Session Resource Modified Item (1..maxnoofPDUSessionResource)
const pdu_session_modif_t *pdu = &msg->pduSessionMod[i];
asn1cSequenceAdd(pdu_mod_l->list, E1AP_PDU_Session_Resource_Modified_Item_t, iePdu);
// PDU Session ID (M)
iePdu->pDU_Session_ID = pdu->id;
// Security Result (O)
if (pdu->confidentialityProtectionIndication || pdu->integrityProtectionIndication) {
iePdu->securityResult = calloc_or_fail(1, sizeof(*iePdu->securityResult));
if (pdu->confidentialityProtectionIndication)
iePdu->securityResult->confidentialityProtectionResult = *pdu->confidentialityProtectionIndication;
if (pdu->integrityProtectionIndication)
iePdu->securityResult->integrityProtectionResult = *pdu->integrityProtectionIndication;
}
// NG DL UP Transport Layer Information (O)
if (pdu->ng_DL_UP_TL_info) {
iePdu->nG_DL_UP_TNL_Information = calloc_or_fail(1, sizeof(*iePdu->nG_DL_UP_TNL_Information));
*iePdu->nG_DL_UP_TNL_Information = e1_encode_up_tnl_info(pdu->ng_DL_UP_TL_info);
}
// DRB Modified List (O)
if (pdu->numDRBModified > 0) {
iePdu->dRB_Modified_List_NG_RAN = calloc_or_fail(1, sizeof(*iePdu->dRB_Modified_List_NG_RAN));
E1AP_DRB_Modified_List_NG_RAN_t *drb_mod_l = iePdu->dRB_Modified_List_NG_RAN;
for (int j = 0; j < pdu->numDRBModified; ++j) {
const DRB_nGRAN_modified_t *drb = &pdu->DRBnGRanModList[j];
asn1cSequenceAdd(drb_mod_l->list, E1AP_DRB_Modified_Item_NG_RAN_t, drb_mod);
// DRB ID (M)
drb_mod->dRB_ID = drb->id;
// Flow Setup List (O)
if (drb->numQosFlowSetup)
drb_mod->flow_Setup_List = calloc_or_fail(1, sizeof(*drb_mod->flow_Setup_List));
for (int q = 0; q < drb->numQosFlowSetup; ++q) {
asn1cSequenceAdd(drb_mod->flow_Setup_List->list, E1AP_QoS_Flow_Item_t, qos_mod);
qos_mod->qoS_Flow_Identifier = drb->qosFlows[q].qfi;
}
// Flow Failed List (O)
if (drb->numQosFlowFailed)
drb_mod->flow_Failed_List = calloc_or_fail(1, sizeof(*drb_mod->flow_Failed_List));
for (int q = 0; q < drb->numQosFlowFailed; ++q) {
asn1cSequenceAdd(drb_mod->flow_Failed_List->list, E1AP_QoS_Flow_Failed_Item_t, fail);
encode_qos_flow_failed_item(fail, &drb->qosFlowsFailed[q]);
}
// PDCP Status Information (O)
if (drb->pdcp_status) {
asn1cCalloc(drb_mod->pDCP_SN_Status_Information, pdcp);
*pdcp = encode_pdcp_status_info(drb->pdcp_status);
}
// UL UP Parameters (O)
if (drb->numUpParam)
drb_mod->uL_UP_Transport_Parameters = calloc_or_fail(1, sizeof(*drb_mod->uL_UP_Transport_Parameters));
for (const up_params_t *k = drb->ul_UP_Params; k < drb->ul_UP_Params + drb->numUpParam; k++) {
asn1cSequenceAdd(drb_mod->uL_UP_Transport_Parameters->list, E1AP_UP_Parameters_Item_t, up);
up->uP_TNL_Information = e1_encode_up_tnl_info(&k->tl_info);
up->cell_Group_ID = k->cell_group_id;
}
}
}
}
// DRB Failed To Modify List (O)
if (pdu->numDRBFailedToMod > 0) {
iePdu->dRB_Failed_To_Modify_List_NG_RAN = calloc_or_fail(1, sizeof(*iePdu->dRB_Failed_To_Modify_List_NG_RAN));
E1AP_DRB_Failed_To_Modify_List_NG_RAN_t *ngran = iePdu->dRB_Failed_To_Modify_List_NG_RAN;
for (int j = 0; j < pdu->numDRBFailedToMod; ++j) {
const DRB_nGRAN_failed_t *drb = &pdu->DRBnGRanFailedModList[j];
asn1cSequenceAdd(ngran->list, E1AP_DRB_Failed_To_Modify_Item_NG_RAN_t, fail_to_mod);
encode_drb_failed_item((E1AP_DRB_Failed_Item_NG_RAN_t *)fail_to_mod, drb);
}
}
// DRB Setup List (O)
if (pdu->numDRBSetup > 0) {
iePdu->dRB_Setup_List_NG_RAN = calloc_or_fail(1, sizeof(*iePdu->dRB_Setup_List_NG_RAN));
E1AP_DRB_Setup_List_NG_RAN_t *drb_setup = iePdu->dRB_Setup_List_NG_RAN;
for (int j = 0; j < pdu->numDRBModified; ++j) {
const DRB_nGRAN_setup_t *drb = &pdu->DRBnGRanSetupList[j];
asn1cSequenceAdd(drb_setup->list, E1AP_DRB_Setup_Item_NG_RAN_t, item);
// DRB ID (M)
item->dRB_ID = drb->id;
// UL UP Parameters (M)
for (const up_params_t *k = drb->UpParamList; k < drb->UpParamList + drb->numUpParam; k++) {
asn1cSequenceAdd(item->uL_UP_Transport_Parameters.list, E1AP_UP_Parameters_Item_t, up);
up->uP_TNL_Information = e1_encode_up_tnl_info(&k->tl_info);
up->cell_Group_ID = drb->UpParamList->cell_group_id;
}
// Flow Setup List (M)
for (int q = 0; q < drb->numQosFlowSetup; ++q) {
asn1cSequenceAdd(item->flow_Setup_List.list, E1AP_QoS_Flow_Item_t, qos);
qos->qoS_Flow_Identifier = drb->qosFlows[q].qfi;
}
// Flow Failed List (O)
if (drb->numQosFlowFailed)
item->flow_Failed_List = calloc_or_fail(1, sizeof(*item->flow_Failed_List));
for (int q = 0; q < drb->numQosFlowFailed; ++q) {
asn1cSequenceAdd(item->flow_Failed_List->list, E1AP_QoS_Flow_Failed_Item_t, fail);
encode_qos_flow_failed_item(fail, &drb->qosFlowsFailed[q]);
// DRB Failed To Modify List (O)
if (pdu->numDRBFailedToMod > 0) {
iePdu->dRB_Failed_To_Modify_List_NG_RAN = calloc_or_fail(1, sizeof(*iePdu->dRB_Failed_To_Modify_List_NG_RAN));
E1AP_DRB_Failed_To_Modify_List_NG_RAN_t *ngran = iePdu->dRB_Failed_To_Modify_List_NG_RAN;
for (int j = 0; j < pdu->numDRBFailedToMod; ++j) {
const DRB_nGRAN_failed_t *drb = &pdu->DRBnGRanFailedModList[j];
asn1cSequenceAdd(ngran->list, E1AP_DRB_Failed_To_Modify_Item_NG_RAN_t, fail_to_mod);
encode_drb_failed_item((E1AP_DRB_Failed_Item_NG_RAN_t *)fail_to_mod, drb);
}
}
}
// DRB Failed List (O)
if (pdu->numDRBFailed) {
iePdu->dRB_Failed_List_NG_RAN = calloc_or_fail(1, sizeof(*iePdu->dRB_Failed_List_NG_RAN));
E1AP_DRB_Failed_List_NG_RAN_t *ngran = iePdu->dRB_Failed_List_NG_RAN;
for (int j = 0; j < pdu->numDRBFailed; ++j) {
const DRB_nGRAN_failed_t *drb = &pdu->DRBnGRanFailedList[j];
asn1cSequenceAdd(ngran->list, E1AP_DRB_Failed_Item_NG_RAN_t, fail);
encode_drb_failed_item(fail, drb);
// DRB Setup List (O)
if (pdu->numDRBSetup > 0) {
iePdu->dRB_Setup_List_NG_RAN = calloc_or_fail(1, sizeof(*iePdu->dRB_Setup_List_NG_RAN));
E1AP_DRB_Setup_List_NG_RAN_t *drb_setup = iePdu->dRB_Setup_List_NG_RAN;
for (int j = 0; j < pdu->numDRBModified; ++j) {
const DRB_nGRAN_setup_t *drb = &pdu->DRBnGRanSetupList[j];
asn1cSequenceAdd(drb_setup->list, E1AP_DRB_Setup_Item_NG_RAN_t, item);
// DRB ID (M)
item->dRB_ID = drb->id;
// UL UP Parameters (M)
for (const up_params_t *k = drb->UpParamList; k < drb->UpParamList + drb->numUpParam; k++) {
asn1cSequenceAdd(item->uL_UP_Transport_Parameters.list, E1AP_UP_Parameters_Item_t, up);
up->uP_TNL_Information = e1_encode_up_tnl_info(&k->tl_info);
up->cell_Group_ID = drb->UpParamList->cell_group_id;
}
// Flow Setup List (M)
for (int q = 0; q < drb->numQosFlowSetup; ++q) {
asn1cSequenceAdd(item->flow_Setup_List.list, E1AP_QoS_Flow_Item_t, qos);
qos->qoS_Flow_Identifier = drb->qosFlows[q].qfi;
}
// Flow Failed List (O)
if (drb->numQosFlowFailed)
item->flow_Failed_List = calloc_or_fail(1, sizeof(*item->flow_Failed_List));
for (int q = 0; q < drb->numQosFlowFailed; ++q) {
asn1cSequenceAdd(item->flow_Failed_List->list, E1AP_QoS_Flow_Failed_Item_t, fail);
encode_qos_flow_failed_item(fail, &drb->qosFlowsFailed[q]);
}
}
}
// DRB Failed List (O)
if (pdu->numDRBFailed) {
iePdu->dRB_Failed_List_NG_RAN = calloc_or_fail(1, sizeof(*iePdu->dRB_Failed_List_NG_RAN));
E1AP_DRB_Failed_List_NG_RAN_t *ngran = iePdu->dRB_Failed_List_NG_RAN;
for (int j = 0; j < pdu->numDRBFailed; ++j) {
const DRB_nGRAN_failed_t *drb = &pdu->DRBnGRanFailedList[j];
asn1cSequenceAdd(ngran->list, E1AP_DRB_Failed_Item_NG_RAN_t, fail);
encode_drb_failed_item(fail, drb);
}
}
}
}
+1
View File
@@ -78,6 +78,7 @@
#include "E1AP_DRB-To-Modify-Item-NG-RAN.h"
#include "E1AP_PDU-Session-Resource-To-Setup-Mod-Item.h"
#include "E1AP_DRB-To-Setup-Mod-Item-NG-RAN.h"
#include "E1AP_PDU-Session-Resource-To-Remove-Item.h"
// E1 Bearer Context Modification Response
#include "E1AP_PDU-Session-Resource-Modified-Item.h"
#include "E1AP_DRB-Modified-List-NG-RAN.h"
+10
View File
@@ -538,6 +538,14 @@ static void test_bearer_context_modification_request(void)
.DRBnGRanList[0] = drb_to_setup,
};
// PDU Session to Remove
pdu_session_to_remove_t pdu_session_to_remove = {
.sessionId = 2,
// Note: cause is optional extension IE, currently encoding/decoding only handles sessionId
.cause.type = 0,
.cause.value = 0,
};
// Initialize the Bearer Context Modification Request
e1ap_bearer_mod_req_t orig = {
.gNB_cu_cp_ue_id = 0x1234,
@@ -548,6 +556,8 @@ static void test_bearer_context_modification_request(void)
.pduSession[0] = pdusession_setup_item,
.numPDUSessionsMod = 1,
.pduSessionMod[0] = pdusession_mod_item,
.numPDUSessionsRem = 1,
.pduSessionRem[0] = pdu_session_to_remove,
};
*orig.bearerContextStatus = BEARER_SUSPEND;
*orig.inactivityTimer = 1000;
@@ -54,10 +54,12 @@ typedef struct {
ue_id_e2sm_t* ue_id;
// Optional
// only used to retreive MAC/RLC stats
// only used to retrieve MAC/RLC stats
NR_UE_info_t** ue_info_list;
}arr_ue_id_t;
static e2_node_level_stats_t node_stats[2] = {0}; // [0] node stats collected in previous reporting period; [1] current node stats
static meas_data_lst_t fill_kpm_meas_data_item(const meas_info_format_1_lst_t* meas_info_lst, const size_t len, const uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx)
{
meas_data_lst_t data_item = {0};
@@ -74,7 +76,7 @@ static meas_data_lst_t fill_kpm_meas_data_item(const meas_info_format_1_lst_t* m
char* meas_info_name_str = cp_ba_to_str(meas_info_lst[i].meas_type.name);
data_item.meas_record_lst[i] = get_kpm_meas_value(meas_info_name_str, gran_period_ms, ue_info, ue_idx);
data_item.meas_record_lst[i] = get_kpm_meas_value(meas_info_name_str, gran_period_ms, ue_info, ue_idx, node_stats);
free(meas_info_name_str);
}
@@ -153,6 +155,8 @@ static kpm_ind_msg_format_3_t fill_kpm_ind_msg_frm_3(arr_ue_id_t* arr_ue_id, con
msg_frm_3.meas_report_per_ue[i].ind_msg_format_1 = fill_kpm_ind_msg_frm_1(ue_info, i, act_def_fr_1);
}
node_stats[0] = cp_node_level_stats(&node_stats[1]);
return msg_frm_3;
}
@@ -288,8 +292,10 @@ static arr_ue_id_t filter_ues_by_s_nssai_in_du_or_monolithic(const test_info_lst
const ngran_node_t node_type = get_e2_node_type();
gNB_MAC_INST *mac = RC.nrmac[0];
NR_SCHED_LOCK(&mac->sched_lock);
// Take MAC info
UE_iterator(RC.nrmac[0]->UE_info.connected_ue_list, ue) {
UE_iterator(mac->UE_info.connected_ue_list, ue) {
NR_UE_sched_ctrl_t *sched_ctrl = &ue->UE_sched_ctrl;
// UE matches if any of its DRBs matches
for (size_t l = 0; l < seq_arr_size(&sched_ctrl->lc_config); ++l) {
@@ -316,6 +322,10 @@ static arr_ue_id_t filter_ues_by_s_nssai_in_du_or_monolithic(const test_info_lst
AssertFatal(arr_ue_id.sz < MAX_MOBILES_PER_GNB, "cannot have more UEs than global UE number maximum\n");
}
node_stats[1].mac_stats.dl.total_prb_aggregate = mac->mac_stats.dl.total_prb_aggregate;
node_stats[1].mac_stats.ul.total_prb_aggregate = mac->mac_stats.ul.total_prb_aggregate;
NR_SCHED_UNLOCK(&mac->sched_lock);
free(sd); // if NULL, nothing happens
return arr_ue_id;
@@ -23,6 +23,18 @@
#include <search.h>
e2_node_level_stats_t cp_node_level_stats(const e2_node_level_stats_t *src)
{
e2_node_level_stats_t dst = {
.mac_stats.dl.total_prb_aggregate = src->mac_stats.dl.total_prb_aggregate,
.mac_stats.dl.used_prb_aggregate = src->mac_stats.dl.used_prb_aggregate,
.mac_stats.ul.total_prb_aggregate = src->mac_stats.ul.total_prb_aggregate,
.mac_stats.ul.used_prb_aggregate = src->mac_stats.ul.used_prb_aggregate,
};
return dst;
}
/* measurements that need to store values from previous reporting period have a limitation
when it comes to multiple subscriptions to the same UEs; ric_req_id is unique per subscription */
typedef struct uldlcounter {
@@ -46,7 +58,7 @@ static nr_pdcp_statistics_t get_pdcp_stats_per_drb(const uint32_t rrc_ue_id, con
/* 3GPP TS 28.522 - section 5.1.2.1.1.1
note: this measurement is calculated as per spec */
static meas_record_lst_t fill_DRB_PdcpSduVolumeDL(__attribute__((unused))uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx)
static meas_record_lst_t fill_DRB_PdcpSduVolumeDL(__attribute__((unused))uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx, __attribute__((unused))e2_node_level_stats_t* node_stats)
{
meas_record_lst_t meas_record = {0};
@@ -57,7 +69,7 @@ static meas_record_lst_t fill_DRB_PdcpSduVolumeDL(__attribute__((unused))uint32_
meas_record.value = INTEGER_MEAS_VALUE;
// Get DL data volume delivered to PDCP layer
meas_record.int_val = (pdcp.rxsdu_bytes - last_pdcp_sdu_total_bytes[ue_idx].dl)*8/1000; // [kb]
meas_record.int_val = (pdcp.rxsdu_bytes - last_pdcp_sdu_total_bytes[ue_idx].dl)*8/1000000; // [Mb]
last_pdcp_sdu_total_bytes[ue_idx].dl = pdcp.rxsdu_bytes;
return meas_record;
@@ -65,7 +77,7 @@ static meas_record_lst_t fill_DRB_PdcpSduVolumeDL(__attribute__((unused))uint32_
/* 3GPP TS 28.522 - section 5.1.2.1.2.1
note: this measurement is calculated as per spec */
static meas_record_lst_t fill_DRB_PdcpSduVolumeUL(__attribute__((unused))uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx)
static meas_record_lst_t fill_DRB_PdcpSduVolumeUL(__attribute__((unused))uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx, __attribute__((unused))e2_node_level_stats_t* node_stats)
{
meas_record_lst_t meas_record = {0};
@@ -76,7 +88,7 @@ static meas_record_lst_t fill_DRB_PdcpSduVolumeUL(__attribute__((unused))uint32_
meas_record.value = INTEGER_MEAS_VALUE;
// Get UL data volume delivered from PDCP layer
meas_record.int_val = (pdcp.txsdu_bytes - last_pdcp_sdu_total_bytes[ue_idx].ul)*8/1000; // [kb]
meas_record.int_val = (pdcp.txsdu_bytes - last_pdcp_sdu_total_bytes[ue_idx].ul)*8/1000000; // [Mb]
last_pdcp_sdu_total_bytes[ue_idx].ul = pdcp.txsdu_bytes;
return meas_record;
@@ -103,7 +115,7 @@ static nr_rlc_statistics_t get_rlc_stats_per_drb(const rnti_t rnti, const int rb
/* 3GPP TS 28.522 - section 5.1.3.3.3
note: by default this measurement is calculated for previous 100ms (openair2/LAYER2/nr_rlc/nr_rlc_entity.c:118, 173, 213); please, update according to your needs */
static meas_record_lst_t fill_DRB_RlcSduDelayDl(__attribute__((unused))uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, __attribute__((unused))const size_t ue_idx)
static meas_record_lst_t fill_DRB_RlcSduDelayDl(__attribute__((unused))uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, __attribute__((unused))const size_t ue_idx, __attribute__((unused))e2_node_level_stats_t* node_stats)
{
meas_record_lst_t meas_record = {0};
@@ -122,7 +134,7 @@ static meas_record_lst_t fill_DRB_RlcSduDelayDl(__attribute__((unused))uint32_t
/* 3GPP TS 28.522 - section 5.1.1.3.1
note: per spec, average UE throughput in DL (taken into consideration values from all UEs, and averaged)
here calculated as: UE specific throughput in DL */
static meas_record_lst_t fill_DRB_UEThpDl(uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx)
static meas_record_lst_t fill_DRB_UEThpDl(uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx, __attribute__((unused))e2_node_level_stats_t* node_stats)
{
meas_record_lst_t meas_record = {0};
@@ -141,7 +153,7 @@ static meas_record_lst_t fill_DRB_UEThpDl(uint32_t gran_period_ms, cudu_ue_info_
/* 3GPP TS 28.522 - section 5.1.1.3.3
note: per spec, average UE throughput in UL (taken into consideration values from all UEs, and averaged)
here calculated as: UE specific throughput in UL */
static meas_record_lst_t fill_DRB_UEThpUl(uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx)
static meas_record_lst_t fill_DRB_UEThpUl(uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx, __attribute__((unused))e2_node_level_stats_t* node_stats)
{
meas_record_lst_t meas_record = {0};
@@ -159,32 +171,30 @@ static meas_record_lst_t fill_DRB_UEThpUl(uint32_t gran_period_ms, cudu_ue_info_
}
/* 3GPP TS 28.522 - section 5.1.1.2.1
note: per spec, DL PRB usage [%] = (total used PRBs for DL traffic / total available PRBs for DL traffic) * 100
here calculated as: aggregated DL PRBs (t) - aggregated DL PRBs (t-gran_period) */
static meas_record_lst_t fill_RRU_PrbTotDl(__attribute__((unused))uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx)
note: this measurement is calculated as per spec */
static meas_record_lst_t fill_RRU_PrbTotDl(__attribute__((unused))uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx, e2_node_level_stats_t* node_stats)
{
meas_record_lst_t meas_record = {0};
meas_record.value = INTEGER_MEAS_VALUE;
// Get the number of DL PRBs
meas_record.int_val = ue_info.ue->mac_stats.dl.total_rbs - last_total_prbs[ue_idx].dl; // [PRBs]
meas_record.int_val = (ue_info.ue->mac_stats.dl.total_rbs - last_total_prbs[ue_idx].dl) * 100 / (node_stats[1].mac_stats.dl.total_prb_aggregate - node_stats[0].mac_stats.dl.total_prb_aggregate); // [%]
last_total_prbs[ue_idx].dl = ue_info.ue->mac_stats.dl.total_rbs;
return meas_record;
}
/* 3GPP TS 28.522 - section 5.1.1.2.2
note: per spec, UL PRB usage [%] = (total used PRBs for UL traffic / total available PRBs for UL traffic) * 100
here calculated as: aggregated UL PRBs (t) - aggregated UL PRBs (t-gran_period) */
static meas_record_lst_t fill_RRU_PrbTotUl(__attribute__((unused))uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx)
note: this measurement is calculated as per spec */
static meas_record_lst_t fill_RRU_PrbTotUl(__attribute__((unused))uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx, e2_node_level_stats_t* node_stats)
{
meas_record_lst_t meas_record = {0};
meas_record.value = INTEGER_MEAS_VALUE;
// Get the number of UL PRBs
meas_record.int_val = ue_info.ue->mac_stats.ul.total_rbs - last_total_prbs[ue_idx].ul; // [PRBs]
meas_record.int_val = (ue_info.ue->mac_stats.ul.total_rbs - last_total_prbs[ue_idx].ul) * 100 / (node_stats[1].mac_stats.ul.total_prb_aggregate - node_stats[0].mac_stats.ul.total_prb_aggregate); // [%]
last_total_prbs[ue_idx].ul = ue_info.ue->mac_stats.ul.total_rbs;
return meas_record;
@@ -217,7 +227,7 @@ void init_kpm_subs_data(void)
}
}
meas_record_lst_t get_kpm_meas_value(char* kpm_meas_name, uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx)
meas_record_lst_t get_kpm_meas_value(char* kpm_meas_name, uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx, e2_node_level_stats_t* node_stats)
{
assert(kpm_meas_name != NULL);
@@ -226,7 +236,7 @@ meas_record_lst_t get_kpm_meas_value(char* kpm_meas_name, uint32_t gran_period_m
assert(found_entry != NULL && "Unsupported KPM measurement name");
kv_measure_t *kv_found = (kv_measure_t *)found_entry->data;
meas_record_lst_t meas_record = kv_found->value(gran_period_ms, ue_info, ue_idx);
meas_record_lst_t meas_record = kv_found->value(gran_period_ms, ue_info, ue_idx, node_stats);
return meas_record;
}
@@ -34,7 +34,13 @@ typedef struct {
} cudu_ue_info_pair_t;
typedef meas_record_lst_t (*kpm_meas_fp)(uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx);
typedef struct {
dlul_mac_stats_t mac_stats;
} e2_node_level_stats_t;
e2_node_level_stats_t cp_node_level_stats(const e2_node_level_stats_t *src);
typedef meas_record_lst_t (*kpm_meas_fp)(uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx, e2_node_level_stats_t* node_stats);
typedef struct{
char* key;
@@ -44,6 +50,6 @@ typedef struct{
void init_kpm_subs_data(void);
meas_record_lst_t get_kpm_meas_value(char* kpm_meas_name, uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx);
meas_record_lst_t get_kpm_meas_value(char* kpm_meas_name, uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx, e2_node_level_stats_t* node_stats);
#endif
@@ -2819,11 +2819,13 @@ uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP,
dci_pdu->harq_pid.nbits = 4;
dci_pdu->frequency_domain_assignment.nbits = (uint8_t)ceil(log2((N_RB * (N_RB + 1)) >>1)); // Freq domain assignment -- hopping scenario to be updated
size += dci_pdu->frequency_domain_assignment.nbits;
if(alt_size >= size)
size += alt_size - size; // Padding to match 1_0 size
else if (ss_type == NR_SearchSpace__searchSpaceType_PR_common) {
dci_pdu->frequency_domain_assignment.nbits -= (size - alt_size);
size = alt_size;
if (alt_size) {
if(alt_size >= size)
size += alt_size - size; // Padding to match 1_0 size
else if (ss_type == NR_SearchSpace__searchSpaceType_PR_common) {
dci_pdu->frequency_domain_assignment.nbits -= (size - alt_size);
size = alt_size;
}
}
// UL/SUL indicator assumed to be 0
break;
@@ -3133,7 +3135,7 @@ uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP,
default:
AssertFatal(1==0, "Invalid NR DCI format %d\n", format);
}
LOG_D(NR_MAC, "DCI size: %d\n", size);
LOG_D(NR_MAC, "DCI format %d size: %d alt_size %d\n", format, size, alt_size);
return size;
}
@@ -555,6 +555,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
pusch_config_pdu->tbslbrm = 0;
} else if (dci) {
pusch_config_pdu->subcarrier_spacing = scs;
pusch_config_pdu->ulsch_indicator = dci->ulsch_indicator;
if (dci->csi_request.nbits > 0 && dci->csi_request.val > 0) {
AssertFatal(csi_report, "CSI report needs to be present in case of CSI request\n");
+2 -18
View File
@@ -59,13 +59,7 @@ uint8_t nr_get_rv(int rel_round)
return nr_rv_round_map[rel_round];
}
void clear_nr_nfapi_information(gNB_MAC_INST *gNB,
int CC_idP,
frame_t frameP,
slot_t slotP,
nfapi_nr_dl_tti_request_t *DL_req,
nfapi_nr_tx_data_request_t *TX_req,
nfapi_nr_ul_dci_request_t *UL_dci_req)
void clear_nr_nfapi_information(gNB_MAC_INST *gNB, int CC_idP, frame_t frameP, slot_t slotP)
{
/* called below and in simulators, so we assume a lock but don't require it */
const int num_slots = gNB->frame_structure.numb_slots_frame;
@@ -75,16 +69,8 @@ void clear_nr_nfapi_information(gNB_MAC_INST *gNB,
gNB->pdu_index[CC_idP] = 0;
DL_req[CC_idP].SFN = frameP;
DL_req[CC_idP].Slot = slotP;
DL_req[CC_idP].dl_tti_request_body.nPDUs = 0;
DL_req[CC_idP].dl_tti_request_body.nGroup = 0;
memset(pdcch, 0, sizeof(*pdcch) * MAX_NUM_CORESET);
UL_dci_req[CC_idP].SFN = frameP;
UL_dci_req[CC_idP].Slot = slotP;
UL_dci_req[CC_idP].numPdus = 0;
/* advance last round's future UL_tti_req to be ahead of current frame/slot */
const int size = gNB->UL_tti_req_ahead_size;
const int prev_slot = frameP * num_slots + slotP + size - 1;
@@ -100,8 +86,6 @@ void clear_nr_nfapi_information(gNB_MAC_INST *gNB,
future_ul_tti_req->n_ulsch = 0;
future_ul_tti_req->n_ulcch = 0;
future_ul_tti_req->n_group = 0;
TX_req[CC_idP].Number_of_PDUs = 0;
}
static void clear_beam_information(NR_beam_info_t *beam_info, int frame, int slot, int slots_per_frame)
@@ -191,7 +175,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, slot_t slo
uint16_t *vrb_map_UL = cc[CC_id].vrb_map_UL[i];
memcpy(&vrb_map_UL[prev_slot % size * MAX_BWP_SIZE], &gNB->ulprbbl, sizeof(uint16_t) * MAX_BWP_SIZE);
}
clear_nr_nfapi_information(gNB, CC_id, frame, slot, &sched_info->DL_req, &sched_info->TX_req, &sched_info->UL_dci_req);
clear_nr_nfapi_information(gNB, CC_id, frame, slot);
}
bool wait_prach_completed = gNB->num_scheduled_prach_rx >= NUM_PRACH_RX_FOR_NOISE_ESTIMATE;
@@ -649,9 +649,8 @@ static void pf_dl(gNB_MAC_INST *mac,
stats->current_bytes = 0;
stats->current_rbs = 0;
/* Check if this UE should get TA (every 100 frames). If we add the CE,
* ta_apply will be reset */
if (frame == ((sched_ctrl->ta_frame + 100) % 1024))
/* Check if this UE should get TA. If we add the CE, ta_apply will be reset */
if (frame == sched_ctrl->ta_frame)
sched_ctrl->ta_apply = true;
int total_rem_ues = 0;
@@ -690,7 +689,7 @@ static void pf_dl(gNB_MAC_INST *mac,
update_dlsch_buffer(pp_pdsch->frame, pp_pdsch->slot, UE);
/* Check DL buffer and skip this UE if no bytes and no TA necessary */
if (sched_ctrl->num_total_bytes == 0 && frame != (sched_ctrl->ta_frame + 100) % 1024)
if (sched_ctrl->num_total_bytes == 0 && sched_ctrl->ta_apply == false)
continue;
/* Calculate coeff */
@@ -871,8 +870,8 @@ static void pf_dl(gNB_MAC_INST *mac,
// awaiting. Therefore, for the time being, we put a fixed overhead of 12
// (for 4 PDUs) and optionally + 2 for TA. Once RLC gives the number of
// PDUs, we replace with 3 * numPDUs
const int oh = 3 * 4 + 2 * (frame == (sched_ctrl->ta_frame + 100) % 1024);
//const int oh = 3 * sched_ctrl->dl_pdus_total + 2 * (frame == (sched_ctrl->ta_frame + 100) % 1024);
const int oh = 3 * 4 + (sched_ctrl->ta_apply ? 2 : 0);
//const int oh = 3 * sched_ctrl->dl_pdus_total + (sched_ctrl->ta_apply ? 2 : 0);
nr_find_nb_rb(sched_pdsch.Qm,
sched_pdsch.R,
1, // no transform precoding for DL
@@ -1224,7 +1223,7 @@ void post_process_dlsch(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pdsch, NR_UE
T(T_GNB_MAC_RETRANSMISSION_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti),
T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_INT(harq->round), T_BUFFER(harq->transportBlock.buf, TBS));
UE->mac_stats.dl.total_rbs_retx += sched_pdsch->rbSize;
nr_mac->mac_stats.used_prb_aggregate += sched_pdsch->rbSize;
nr_mac->mac_stats.dl.used_prb_aggregate += sched_pdsch->rbSize;
} else { /* initial transmission */
LOG_D(NR_MAC, "Initial HARQ transmission in %d.%d\n", frame, slot);
uint8_t *buf = allocate_transportBlock_buffer(&harq->transportBlock, TBS);
@@ -1338,7 +1337,7 @@ void post_process_dlsch(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pdsch, NR_UE
UE->mac_stats.dl.num_mac_sdu += sdus;
UE->mac_stats.dl.current_rbs = sched_pdsch->rbSize;
UE->mac_stats.dl.total_sdu_bytes += dlsch_total_bytes;
nr_mac->mac_stats.used_prb_aggregate += sched_pdsch->rbSize;
nr_mac->mac_stats.dl.used_prb_aggregate += sched_pdsch->rbSize;
/* save retransmission information */
harq->sched_pdsch = *sched_pdsch;
@@ -1349,8 +1348,9 @@ void post_process_dlsch(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pdsch, NR_UE
// ta command is sent, values are reset
if (sched_ctrl->ta_apply) {
sched_ctrl->ta_apply = false;
sched_ctrl->ta_frame = frame;
LOG_D(NR_MAC, "%d.%2d UE %04x TA scheduled, resetting TA frame\n", frame, slot, UE->rnti);
sched_ctrl->ta_update = 31;
sched_ctrl->ta_frame = (frame + 100) % MAX_FRAME_NUMBER;
LOG_D(NR_MAC, "%d.%2d UE %04x TA scheduled, setting next TA frame to %d\n", frame, slot, UE->rnti, sched_ctrl->ta_frame);
}
T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti),
@@ -1387,8 +1387,8 @@ void nr_schedule_ue_spec(module_id_t module_id,
return;
NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_id].ServingCellConfigCommon;
const NR_BWP_t *initialDL = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
gNB_mac->mac_stats.total_prb_aggregate += NRRIV2BW(initialDL->locationAndBandwidth, MAX_BWP_SIZE);
int bw = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
gNB_mac->mac_stats.dl.total_prb_aggregate += bw;
nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
post_process_pdsch_t pdsch = { frame, slot, dl_req, TX_req };
@@ -125,6 +125,8 @@ static const uint16_t cqi_table3[16][2] = {{0, 0},
static void determine_aggregation_level_search_order(int agg_level_search_order[NUM_PDCCH_AGG_LEVELS],
float pdcch_cl_adjust);
static int nr_mac_interrupt_ue_transmission(gNB_MAC_INST *mac, NR_UE_info_t *UE, int slots, int slots_per_frame);
uint8_t get_dl_nrOfLayers(const NR_UE_sched_ctrl_t *sched_ctrl, const nr_dci_format_t dci_format)
{
// TODO check this but it should be enough for now
@@ -3435,7 +3437,7 @@ void nr_measgap_scheduling(gNB_MAC_INST *nr_mac, frame_t frame, sub_frame_t slot
continue;
const int slots_frame = nr_mac->frame_structure.numb_slots_frame;
const frame_t f = (frame + (slot + mgc->n_slots_advance) / slots_frame) % 1024;
const frame_t f = (frame + (slot + mgc->n_slots_advance) / slots_frame) % MAX_FRAME_NUMBER;
const slot_t s = (slot + mgc->n_slots_advance) % slots_frame;
// TS 38 331 - Section 5.5.2.9 Measurement gap configuration
@@ -3446,7 +3448,7 @@ void nr_measgap_scheduling(gNB_MAC_INST *nr_mac, frame_t frame, sub_frame_t slot
// start a timer to stop scheduling UE during MeasGap, or extend timer for
// duration of measGap with existing follow-up action
if (!nr_timer_is_active(t) || nr_timer_remaining_time(t) < mgc->mgl_slots) {
nr_mac_interrupt_ue_transmission(nr_mac, UE, mgc->mgl_slots);
nr_mac_interrupt_ue_transmission(nr_mac, UE, mgc->mgl_slots, slots_frame);
}
}
}
@@ -3530,7 +3532,7 @@ int nr_mac_get_reconfig_delay_slots(NR_SubcarrierSpacing_t scs)
return (delay_ms << scs) + sl_ahead;
}
int nr_mac_interrupt_ue_transmission(gNB_MAC_INST *mac, NR_UE_info_t *UE, int slots)
static int nr_mac_interrupt_ue_transmission(gNB_MAC_INST *mac, NR_UE_info_t *UE, int slots, int slots_per_frame)
{
DevAssert(mac != NULL);
DevAssert(UE != NULL);
@@ -3539,11 +3541,11 @@ int nr_mac_interrupt_ue_transmission(gNB_MAC_INST *mac, NR_UE_info_t *UE, int sl
nr_timer_setup(&UE->UE_sched_ctrl.transm_interrupt, slots, 1);
nr_timer_start(&UE->UE_sched_ctrl.transm_interrupt);
// it might happen that timing advance command should be sent during the UE
// inactivity time. To prevent this, set a variable as if we would have just
// sent it. This way, another TA command will for sure be sent in some
// frames, after the inactivity of the UE.
UE->UE_sched_ctrl.ta_frame = (mac->frame - 1 + 1024) % 1024;
// it might happen that timing advance command should be sent during the UE inactivity time.
// To prevent this, delay next TA command just after the UE inactivity time.
const int inactive_frames = slots / slots_per_frame + 1;
if ((UE->UE_sched_ctrl.ta_frame - mac->frame + MAX_FRAME_NUMBER) % MAX_FRAME_NUMBER < inactive_frames)
UE->UE_sched_ctrl.ta_frame = (mac->frame + inactive_frames) % MAX_FRAME_NUMBER;
LOG_D(NR_MAC, "UE %04x: Interrupt UE transmission (%d slots)\n", UE->rnti, slots);
return 0;
@@ -811,7 +811,7 @@ static void nr_rx_ra_sdu(const module_id_t mod_id,
}
// re-initialize ta update variables after RA procedure completion
UE->UE_sched_ctrl.ta_frame = frame;
UE->UE_sched_ctrl.ta_frame = (frame + 100) % MAX_FRAME_NUMBER;
LOG_A(NR_MAC, "%4d.%2d PUSCH with TC_RNTI 0x%04x received correctly\n", frame, slot, rnti);
@@ -2455,6 +2455,7 @@ void post_process_ulsch(gNB_MAC_INST *nr_mac, post_process_pusch_t *pusch, NR_UE
}
UE->mac_stats.ul.current_bytes = sched_pusch->tb_size;
UE->mac_stats.ul.current_rbs = sched_pusch->rbSize;
nr_mac->mac_stats.ul.used_prb_aggregate += sched_pusch->rbSize;
sched_ctrl->last_ul_frame = sched_pusch->frame;
sched_ctrl->last_ul_slot = sched_pusch->slot;
@@ -2697,6 +2698,7 @@ static void nr_ulsch_preprocessor(gNB_MAC_INST *nr_mac, post_process_pusch_t *pp
int tda = seq_arr_dist(&nr_mac->ul_tda, seq_arr_front(&nr_mac->ul_tda), tda_info);
AssertFatal(tda >= 0 && tda < 16, "illegal TDA index %d\n", tda);
nr_mac->mac_stats.ul.total_prb_aggregate += bw;
int len[num_beams];
for (int i = 0; i < num_beams; i++)
len[i] = rb_len;

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