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:
@@ -62,6 +62,7 @@ ForEachMacros:
|
||||
- BOOST_FOREACH
|
||||
- RB_FOREACH
|
||||
- UE_iterator
|
||||
- FOR_EACH_SEQ_ARR
|
||||
IncludeBlocks: Preserve
|
||||
IncludeCategories:
|
||||
- Regex: '^<ext/.*\.h>'
|
||||
|
||||
+1
-10
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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':
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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},
|
||||
};
|
||||
|
||||
|
||||
@@ -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},
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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)
|
||||
```
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
@@ -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() {};
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
-1
@@ -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
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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){}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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};
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
+1
-1
Submodule openair2/E2AP/flexric updated: df754a8553...6a595d8b24
@@ -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");
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user