Merge remote-tracking branch 'origin/develop' into scs_60_iisc
This commit is contained in:
@@ -6,7 +6,7 @@ eNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
eNB_ID = 0xe05;
|
||||
eNB_ID = 0xe04;
|
||||
|
||||
cell_type = "CELL_MACRO_ENB";
|
||||
|
||||
|
||||
@@ -254,7 +254,6 @@ MACRLCs = (
|
||||
tr_n_preference = "local_RRC";
|
||||
pusch_TargetSNRx10 = 200;
|
||||
pucch_TargetSNRx10 = 150;
|
||||
ulsch_max_slots_inactivity=20;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -251,7 +251,6 @@ MACRLCs = (
|
||||
tr_n_preference = "local_RRC";
|
||||
pusch_TargetSNRx10 = 200;
|
||||
pucch_TargetSNRx10 = 150;
|
||||
ulsch_max_slots_inactivity=20;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -228,9 +228,8 @@ MACRLCs = (
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
ulsch_max_slots_inactivity = 1;
|
||||
pusch_TargetSNRx10 = 200;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -232,7 +232,6 @@ MACRLCs = (
|
||||
tr_n_preference = "local_RRC";
|
||||
pusch_TargetSNRx10 = 200;
|
||||
pucch_TargetSNRx10 = 150;
|
||||
ulsch_max_slots_inactivity = 10;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -211,7 +211,6 @@ MACRLCs = (
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
ulsch_max_slots_inactivity = 1;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
+67
-11
@@ -66,6 +66,7 @@ class EPCManagement():
|
||||
self.containerPrefix = 'prod'
|
||||
self.mmeConfFile = 'mme.conf'
|
||||
self.yamlPath = ''
|
||||
self.isMagmaUsed = False
|
||||
|
||||
|
||||
#-----------------------------------------------------------
|
||||
@@ -164,7 +165,15 @@ class EPCManagement():
|
||||
if re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE):
|
||||
mySSH = SSH.SSHConnection()
|
||||
mySSH.open(self.IPAddress, self.UserName, self.Password)
|
||||
mySSH.command('docker inspect --format="MME_IP_ADDR = {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" ' + self.containerPrefix + '-oai-mme', '\$', 5)
|
||||
self.isMagmaUsed = False
|
||||
mySSH.command('docker ps -a', '\$', 5)
|
||||
result = re.search('magma', mySSH.getBefore())
|
||||
if result is not None:
|
||||
self.isMagmaUsed = True
|
||||
if self.isMagmaUsed:
|
||||
mySSH.command('docker inspect --format="MME_IP_ADDR = {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" ' + self.containerPrefix + '-magma-mme', '\$', 5)
|
||||
else:
|
||||
mySSH.command('docker inspect --format="MME_IP_ADDR = {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" ' + self.containerPrefix + '-oai-mme', '\$', 5)
|
||||
result = re.search('MME_IP_ADDR = (?P<mme_ip_addr>[0-9\.]+)', mySSH.getBefore())
|
||||
if result is not None:
|
||||
self.MmeIPAddress = result.group('mme_ip_addr')
|
||||
@@ -289,7 +298,15 @@ class EPCManagement():
|
||||
mySSH = SSH.SSHConnection()
|
||||
mySSH.open(self.IPAddress, self.UserName, self.Password)
|
||||
if re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE):
|
||||
mySSH.command('docker top ' + self.containerPrefix + '-oai-mme', '\$', 5)
|
||||
self.isMagmaUsed = False
|
||||
mySSH.command('docker ps -a', '\$', 5)
|
||||
result = re.search('magma', mySSH.getBefore())
|
||||
if result is not None:
|
||||
self.isMagmaUsed = True
|
||||
if self.isMagmaUsed:
|
||||
mySSH.command('docker top ' + self.containerPrefix + '-magma-mme', '\$', 5)
|
||||
else:
|
||||
mySSH.command('docker top ' + self.containerPrefix + '-oai-mme', '\$', 5)
|
||||
else:
|
||||
mySSH.command('stdbuf -o0 ps -aux | grep --color=never mme | grep -v grep', '\$', 5)
|
||||
if re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE):
|
||||
@@ -489,6 +506,12 @@ class EPCManagement():
|
||||
HTML.CreateHtmlTabFooter(False)
|
||||
sys.exit('docker-compose not installed on ' + self.IPAddress)
|
||||
|
||||
# Checking if it is a MAGMA deployment
|
||||
self.isMagmaUsed = False
|
||||
if os.path.isfile('./' + self.yamlPath + '/redis_extern.conf'):
|
||||
self.isMagmaUsed = True
|
||||
logging.debug('MAGMA MME is used!')
|
||||
|
||||
mySSH.command('if [ -d ' + self.SourceCodePath + '/scripts ]; then echo ' + self.Password + ' | sudo -S rm -Rf ' + self.SourceCodePath + '/scripts ; fi', '\$', 5)
|
||||
mySSH.command('if [ -d ' + self.SourceCodePath + '/logs ]; then echo ' + self.Password + ' | sudo -S rm -Rf ' + self.SourceCodePath + '/logs ; fi', '\$', 5)
|
||||
mySSH.command('mkdir -p ' + self.SourceCodePath + '/scripts ' + self.SourceCodePath + '/logs', '\$', 5)
|
||||
@@ -500,10 +523,15 @@ class EPCManagement():
|
||||
# - docker-compose config | grep container_name
|
||||
mySSH.command('cd ' + self.SourceCodePath + '/scripts', '\$', 5)
|
||||
mySSH.copyout(self.IPAddress, self.UserName, self.Password, './' + self.yamlPath + '/docker-compose.yml', self.SourceCodePath + '/scripts')
|
||||
if self.isMagmaUsed:
|
||||
mySSH.copyout(self.IPAddress, self.UserName, self.Password, './' + self.yamlPath + '/entrypoint.sh', self.SourceCodePath + '/scripts')
|
||||
mySSH.copyout(self.IPAddress, self.UserName, self.Password, './' + self.yamlPath + '/mme.conf', self.SourceCodePath + '/scripts')
|
||||
mySSH.copyout(self.IPAddress, self.UserName, self.Password, './' + self.yamlPath + '/mme_fd.sprint.conf', self.SourceCodePath + '/scripts')
|
||||
mySSH.copyout(self.IPAddress, self.UserName, self.Password, './' + self.yamlPath + '/redis_extern.conf', self.SourceCodePath + '/scripts')
|
||||
mySSH.command('chmod a+x ' + self.SourceCodePath + '/scripts/entrypoint.sh', '\$', 5)
|
||||
mySSH.command('wget --quiet --tries=3 --retry-connrefused https://raw.githubusercontent.com/OPENAIRINTERFACE/openair-hss/develop/src/hss_rel14/db/oai_db.cql', '\$', 30)
|
||||
mySSH.command('docker-compose down', '\$', 60)
|
||||
mySSH.command('docker-compose up -d db_init', '\$', 60)
|
||||
|
||||
# databases take time...
|
||||
time.sleep(10)
|
||||
cnt = 0
|
||||
@@ -525,8 +553,12 @@ class EPCManagement():
|
||||
|
||||
# deploying EPC cNFs
|
||||
mySSH.command('docker-compose up -d oai_spgwu', '\$', 60)
|
||||
listOfContainers = 'prod-cassandra prod-oai-hss prod-oai-mme prod-oai-spgwc prod-oai-spgwu-tiny'
|
||||
expectedHealthyContainers = 5
|
||||
if self.isMagmaUsed:
|
||||
listOfContainers = 'prod-cassandra prod-oai-hss prod-magma-mme prod-oai-spgwc prod-oai-spgwu-tiny prod-redis'
|
||||
expectedHealthyContainers = 6
|
||||
else:
|
||||
listOfContainers = 'prod-cassandra prod-oai-hss prod-oai-mme prod-oai-spgwc prod-oai-spgwu-tiny'
|
||||
expectedHealthyContainers = 5
|
||||
|
||||
# Checking for additional services
|
||||
mySSH.command('docker-compose config', '\$', 5)
|
||||
@@ -557,7 +589,10 @@ class EPCManagement():
|
||||
logging.debug(' -- ' + str(startingNb) + ' still starting container(s)')
|
||||
if healthyNb == expectedHealthyContainers:
|
||||
mySSH.command('docker exec -d prod-oai-hss /bin/bash -c "nohup tshark -i any -f \'port 9042 or port 3868\' -w /tmp/hss_check_run.pcap 2>&1 > /dev/null"', '\$', 5)
|
||||
mySSH.command('docker exec -d prod-oai-mme /bin/bash -c "nohup tshark -i any -f \'port 3868 or port 2123 or port 36412\' -w /tmp/mme_check_run.pcap 2>&1 > /dev/null"', '\$', 10)
|
||||
if self.isMagmaUsed:
|
||||
mySSH.command('docker exec -d prod-magma-mme /bin/bash -c "nohup tshark -i any -f \'port 3868 or port 2123 or port 36412\' -w /tmp/mme_check_run.pcap 2>&1 > /dev/null"', '\$', 10)
|
||||
else:
|
||||
mySSH.command('docker exec -d prod-oai-mme /bin/bash -c "nohup tshark -i any -f \'port 3868 or port 2123 or port 36412\' -w /tmp/mme_check_run.pcap 2>&1 > /dev/null"', '\$', 10)
|
||||
mySSH.command('docker exec -d prod-oai-spgwc /bin/bash -c "nohup tshark -i any -f \'port 2123 or port 8805\' -w /tmp/spgwc_check_run.pcap 2>&1 > /dev/null"', '\$', 10)
|
||||
# on SPGW-U, not capturing on SGI to avoid huge file
|
||||
mySSH.command('docker exec -d prod-oai-spgwu-tiny /bin/bash -c "nohup tshark -i any -f \'port 8805\' -w /tmp/spgwu_check_run.pcap 2>&1 > /dev/null"', '\$', 10)
|
||||
@@ -575,24 +610,45 @@ class EPCManagement():
|
||||
|
||||
mySSH = SSH.SSHConnection()
|
||||
mySSH.open(self.IPAddress, self.UserName, self.Password)
|
||||
# Checking if it is a MAGMA deployment.
|
||||
mySSH.command('cd ' + self.SourceCodePath + '/scripts', '\$', 5)
|
||||
mySSH.command('docker-compose ps -a', '\$', 5)
|
||||
self.isMagmaUsed = False
|
||||
result = re.search('magma', mySSH.getBefore())
|
||||
if result is not None:
|
||||
self.isMagmaUsed = True
|
||||
logging.debug('MAGMA MME is used!')
|
||||
# Recovering logs and pcap files
|
||||
mySSH.command('cd ' + self.SourceCodePath + '/logs', '\$', 5)
|
||||
mySSH.command('docker exec -it prod-oai-hss /bin/bash -c "killall --signal SIGINT oai_hss tshark"', '\$', 5)
|
||||
mySSH.command('docker exec -it prod-oai-mme /bin/bash -c "killall --signal SIGINT tshark"', '\$', 5)
|
||||
if self.isMagmaUsed:
|
||||
mySSH.command('docker exec -it prod-magma-mme /bin/bash -c "killall --signal SIGINT tshark"', '\$', 5)
|
||||
else:
|
||||
mySSH.command('docker exec -it prod-oai-mme /bin/bash -c "killall --signal SIGINT tshark"', '\$', 5)
|
||||
mySSH.command('docker exec -it prod-oai-spgwc /bin/bash -c "killall --signal SIGINT oai_spgwc tshark"', '\$', 5)
|
||||
mySSH.command('docker exec -it prod-oai-spgwu-tiny /bin/bash -c "killall --signal SIGINT tshark"', '\$', 5)
|
||||
mySSH.command('docker logs prod-oai-hss > hss_' + self.testCase_id + '.log', '\$', 5)
|
||||
mySSH.command('docker logs prod-oai-mme > mme_' + self.testCase_id + '.log', '\$', 5)
|
||||
if self.isMagmaUsed:
|
||||
mySSH.command('docker cp --follow-link prod-magma-mme:/var/log/mme.log mme_' + self.testCase_id + '.log', '\$', 15)
|
||||
else:
|
||||
mySSH.command('docker logs prod-oai-mme > mme_' + self.testCase_id + '.log', '\$', 5)
|
||||
mySSH.command('docker logs prod-oai-spgwc > spgwc_' + self.testCase_id + '.log', '\$', 5)
|
||||
mySSH.command('docker logs prod-oai-spgwu-tiny > spgwu_' + self.testCase_id + '.log', '\$', 5)
|
||||
mySSH.command('docker cp prod-oai-hss:/tmp/hss_check_run.pcap hss_' + self.testCase_id + '.pcap', '\$', 60)
|
||||
mySSH.command('docker cp prod-oai-mme:/tmp/mme_check_run.pcap mme_' + self.testCase_id + '.pcap', '\$', 60)
|
||||
if self.isMagmaUsed:
|
||||
mySSH.command('docker cp prod-magma-mme:/tmp/mme_check_run.pcap mme_' + self.testCase_id + '.pcap', '\$', 60)
|
||||
else:
|
||||
mySSH.command('docker cp prod-oai-mme:/tmp/mme_check_run.pcap mme_' + self.testCase_id + '.pcap', '\$', 60)
|
||||
mySSH.command('docker cp prod-oai-spgwc:/tmp/spgwc_check_run.pcap spgwc_' + self.testCase_id + '.pcap', '\$', 60)
|
||||
mySSH.command('docker cp prod-oai-spgwu-tiny:/tmp/spgwu_check_run.pcap spgwu_' + self.testCase_id + '.pcap', '\$', 60)
|
||||
# Remove all
|
||||
mySSH.command('cd ' + self.SourceCodePath + '/scripts', '\$', 5)
|
||||
listOfContainers = 'prod-cassandra prod-oai-hss prod-oai-mme prod-oai-spgwc prod-oai-spgwu-tiny'
|
||||
nbContainers = 5
|
||||
if self.isMagmaUsed:
|
||||
listOfContainers = 'prod-cassandra prod-oai-hss prod-magma-mme prod-oai-spgwc prod-oai-spgwu-tiny prod-redis'
|
||||
nbContainers = 6
|
||||
else:
|
||||
listOfContainers = 'prod-cassandra prod-oai-hss prod-oai-mme prod-oai-spgwc prod-oai-spgwu-tiny'
|
||||
nbContainers = 5
|
||||
# Checking for additional services
|
||||
mySSH.command('docker-compose config', '\$', 5)
|
||||
configResponse = mySSH.getBefore()
|
||||
|
||||
@@ -21,10 +21,10 @@
|
||||
|
||||
-->
|
||||
<testCaseList>
|
||||
<htmlTabRef>TEST-NSA-FR1-TM2</htmlTabRef>
|
||||
<htmlTabRef>TEST-NSA-FR1-TM2-Tab1</htmlTabRef>
|
||||
<htmlTabName>NSA 2x2 Ping DL UL with QUECTEL</htmlTabName>
|
||||
<htmlTabIcon>tasks</htmlTabIcon>
|
||||
<repeatCount>1</repeatCount>
|
||||
<repeatCount>5</repeatCount>
|
||||
<TestCaseRequestedList>
|
||||
030000
|
||||
040000
|
||||
@@ -85,7 +85,7 @@
|
||||
<testCase id="000001">
|
||||
<class>IdleSleep</class>
|
||||
<desc>Sleep</desc>
|
||||
<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
|
||||
<idle_sleep_time_in_sec>60</idle_sleep_time_in_sec>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000002">
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
<!--
|
||||
|
||||
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The OpenAirInterface Software Alliance licenses this file to You under
|
||||
the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.openairinterface.org/?page_id=698
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
contact@openairinterface.org
|
||||
|
||||
-->
|
||||
<testCaseList>
|
||||
<htmlTabRef>TEST-NSA-FR1-TM2-Tab2</htmlTabRef>
|
||||
<htmlTabName>NSA 2x2 Attach-Detach with QUECTEL</htmlTabName>
|
||||
<htmlTabIcon>tasks</htmlTabIcon>
|
||||
<repeatCount>5</repeatCount>
|
||||
<TestCaseRequestedList>
|
||||
031000
|
||||
041000
|
||||
000002
|
||||
010000
|
||||
000001
|
||||
050000
|
||||
000002
|
||||
010004
|
||||
000002
|
||||
010003
|
||||
000001
|
||||
050000
|
||||
000002
|
||||
010004
|
||||
000002
|
||||
010003
|
||||
000001
|
||||
050000
|
||||
000002
|
||||
010002
|
||||
080001
|
||||
080000
|
||||
</TestCaseRequestedList>
|
||||
<TestCaseExclusionList></TestCaseExclusionList>
|
||||
|
||||
<testCase id="010000">
|
||||
<class>Initialize_UE</class>
|
||||
<desc>Initialize Quectel</desc>
|
||||
<id>nrmodule2_quectel</id>
|
||||
<UE_Trace>yes</UE_Trace>
|
||||
</testCase>
|
||||
|
||||
|
||||
<testCase id="010002">
|
||||
<class>Terminate_UE</class>
|
||||
<desc>Terminate Quectel</desc>
|
||||
<id>nrmodule2_quectel</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="010003">
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach Quectel</desc>
|
||||
<id>nrmodule2_quectel</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="010004">
|
||||
<class>Detach_UE</class>
|
||||
<desc>Detach Quectel</desc>
|
||||
<id>nrmodule2_quectel</id>
|
||||
</testCase>
|
||||
|
||||
|
||||
<testCase id="031000">
|
||||
<class>Initialize_eNB</class>
|
||||
<desc>Initialize eNB</desc>
|
||||
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band38.nsa_2x2.100PRB.usrpn310.conf --usrp-tx-thread-config 1 --thread-pool 0,2,4,6</Initialize_eNB_args>
|
||||
<eNB_instance>0</eNB_instance>
|
||||
<eNB_serverId>0</eNB_serverId>
|
||||
<air_interface>lte</air_interface>
|
||||
<eNB_Trace>yes</eNB_Trace>
|
||||
<eNB_Stats>yes</eNB_Stats>
|
||||
<USRP_IPAddress>192.168.18.241</USRP_IPAddress>
|
||||
</testCase>
|
||||
|
||||
|
||||
<testCase id="041000">
|
||||
<class>Initialize_eNB</class>
|
||||
<desc>Initialize gNB</desc>
|
||||
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf -q --usrp-tx-thread-config 1 --thread-pool 0,2,4,6</Initialize_eNB_args>
|
||||
<eNB_instance>1</eNB_instance>
|
||||
<eNB_serverId>1</eNB_serverId>
|
||||
<air_interface>nr</air_interface>
|
||||
<eNB_Stats>yes</eNB_Stats>
|
||||
<USRP_IPAddress>192.168.18.240</USRP_IPAddress>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000001">
|
||||
<class>IdleSleep</class>
|
||||
<desc>Sleep</desc>
|
||||
<idle_sleep_time_in_sec>60</idle_sleep_time_in_sec>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000002">
|
||||
<class>IdleSleep</class>
|
||||
<desc>Sleep</desc>
|
||||
<idle_sleep_time_in_sec>20</idle_sleep_time_in_sec>
|
||||
</testCase>
|
||||
|
||||
|
||||
<testCase id="050000">
|
||||
<class>Ping</class>
|
||||
<desc>Ping: 20pings in 20sec</desc>
|
||||
<id>nrmodule2_quectel</id>
|
||||
<ping_args>-c 20</ping_args>
|
||||
<ping_packetloss_threshold>5</ping_packetloss_threshold>
|
||||
</testCase>
|
||||
|
||||
|
||||
|
||||
<testCase id="080000">
|
||||
<class>Terminate_eNB</class>
|
||||
<desc>Terminate eNB</desc>
|
||||
<eNB_instance>0</eNB_instance>
|
||||
<eNB_serverId>0</eNB_serverId>
|
||||
<air_interface>lte</air_interface>
|
||||
</testCase>
|
||||
|
||||
<testCase id="080001">
|
||||
<class>Terminate_eNB</class>
|
||||
<desc>Terminate gNB</desc>
|
||||
<eNB_instance>1</eNB_instance>
|
||||
<eNB_serverId>1</eNB_serverId>
|
||||
<air_interface>nr</air_interface>
|
||||
</testCase>
|
||||
|
||||
</testCaseList>
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
<testCase id="000100">
|
||||
<class>Deploy_EPC</class>
|
||||
<desc>Deploy all EPC containers</desc>
|
||||
<parameters>yaml_files/fr1_epc_20897</parameters>
|
||||
<parameters>yaml_files/magma_nsa_20897</parameters>
|
||||
</testCase>
|
||||
|
||||
</testCaseList>
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
cassandra:
|
||||
image: cassandra:2.1
|
||||
container_name: prod-cassandra
|
||||
networks:
|
||||
private_net:
|
||||
ipv4_address: 192.168.68.2
|
||||
environment:
|
||||
CASSANDRA_CLUSTER_NAME: "OAI HSS Cluster"
|
||||
CASSANDRA_ENDPOINT_SNITCH: GossipingPropertyFileSnitch
|
||||
healthcheck:
|
||||
test: /bin/bash -c "nodetool status"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
db_init:
|
||||
image: cassandra:2.1
|
||||
container_name: prod-db-init
|
||||
depends_on: [cassandra]
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
max_attempts: 10
|
||||
networks:
|
||||
private_net:
|
||||
ipv4_address: 192.168.68.4
|
||||
volumes:
|
||||
- ./oai_db.cql:/home/oai_db.cql
|
||||
entrypoint: /bin/bash -c "cqlsh --file /home/oai_db.cql 192.168.68.2 && echo 'OK'"
|
||||
|
||||
oai_hss:
|
||||
image: oai-hss:production
|
||||
container_name: prod-oai-hss
|
||||
privileged: true
|
||||
depends_on: [cassandra]
|
||||
networks:
|
||||
private_net:
|
||||
ipv4_address: 192.168.68.3
|
||||
public_net:
|
||||
ipv4_address: 192.168.61.194
|
||||
environment:
|
||||
TZ: Europe/Paris
|
||||
REALM: openairinterface.org
|
||||
HSS_FQDN: hss.openairinterface.org
|
||||
PREFIX: /openair-hss/etc
|
||||
cassandra_Server_IP: 192.168.68.2
|
||||
OP_KEY: 1006020f0a478bf6b699f15c062e42b3
|
||||
LTE_K: FEC86BA6EB707ED08905757B1BB44B8F
|
||||
APN1: oai.ipv4
|
||||
APN2: oai2.ipv4
|
||||
FIRST_IMSI: 208970100001127
|
||||
NB_USERS: 10
|
||||
healthcheck:
|
||||
test: /bin/bash -c "pgrep oai_hss"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
redis:
|
||||
image: redis:6.0.5
|
||||
container_name: prod-redis
|
||||
privileged: true
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.61.198
|
||||
volumes:
|
||||
- ./redis_extern.conf:/usr/local/etc/redis/redis.conf
|
||||
entrypoint: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf"
|
||||
healthcheck:
|
||||
test: /bin/bash -c "redis-cli -h 192.168.61.198 -p 6380 ping"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
magma_mme:
|
||||
image: magma-mme:production
|
||||
container_name: prod-magma-mme
|
||||
hostname: mme
|
||||
privileged: true
|
||||
depends_on: [oai_hss, redis]
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.61.195
|
||||
environment:
|
||||
TZ: Europe/Paris
|
||||
REALM: openairinterface.org
|
||||
PREFIX: /openair-mme/etc
|
||||
HSS_HOSTNAME: hss
|
||||
HSS_FQDN: hss.openairinterface.org
|
||||
HSS_REALM: openairinterface.org
|
||||
MME_FQDN: mme.openairinterface.org
|
||||
FEATURES: mme_oai
|
||||
volumes:
|
||||
- ./mme_fd.sprint.conf:/magma-mme/etc/mme_fd.conf.tmplt
|
||||
- ./mme.conf:/magma-mme/etc/mme.conf
|
||||
- ./entrypoint.sh:/magma-mme/bin/entrypoint.sh
|
||||
entrypoint: /bin/bash -c "/magma-mme/bin/entrypoint.sh"
|
||||
healthcheck:
|
||||
test: /bin/bash -c "pgrep oai_mme"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
oai_spgwc:
|
||||
image: oai-spgwc:production
|
||||
privileged: true
|
||||
depends_on: [magma_mme]
|
||||
container_name: prod-oai-spgwc
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.61.196
|
||||
environment:
|
||||
TZ: Europe/Paris
|
||||
SGW_INTERFACE_NAME_FOR_S11: eth0
|
||||
PGW_INTERFACE_NAME_FOR_SX: eth0
|
||||
DEFAULT_DNS_IPV4_ADDRESS: 192.168.18.129
|
||||
DEFAULT_DNS_SEC_IPV4_ADDRESS: 8.8.4.4
|
||||
PUSH_PROTOCOL_OPTION: 'true'
|
||||
APN_NI_1: oai.ipv4
|
||||
APN_NI_2: oai2.ipv4
|
||||
DEFAULT_APN_NI_1: oai.ipv4
|
||||
UE_IP_ADDRESS_POOL_1: '12.1.1.2 - 12.1.1.254'
|
||||
UE_IP_ADDRESS_POOL_2: '12.0.0.2 - 12.0.0.254'
|
||||
MCC: '208'
|
||||
MNC: '97'
|
||||
MNC03: '097'
|
||||
TAC: 1
|
||||
GW_ID: 1
|
||||
REALM: openairinterface.org
|
||||
UE_MTU_IPV4: 1500
|
||||
healthcheck:
|
||||
test: /bin/bash -c "pgrep oai_spgwc"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
oai_spgwu:
|
||||
image: oai-spgwu-tiny:production
|
||||
privileged: true
|
||||
container_name: prod-oai-spgwu-tiny
|
||||
depends_on: [oai_spgwc]
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.61.197
|
||||
environment:
|
||||
TZ: Europe/Paris
|
||||
PID_DIRECTORY: /var/run
|
||||
INSTANCE: 1
|
||||
SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP: eth0
|
||||
PGW_INTERFACE_NAME_FOR_SGI: eth0
|
||||
SGW_INTERFACE_NAME_FOR_SX: eth0
|
||||
SPGWC0_IP_ADDRESS: 192.168.61.196
|
||||
NETWORK_UE_IP: '12.1.1.0/24'
|
||||
NETWORK_UE_NAT_OPTION: 'yes'
|
||||
MCC: '208'
|
||||
MNC: '97'
|
||||
MNC03: '097'
|
||||
TAC: 1
|
||||
GW_ID: 1
|
||||
REALM: openairinterface.org
|
||||
healthcheck:
|
||||
test: /bin/bash -c "pgrep oai_spgwu"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
trf_gen:
|
||||
image: trf-gen:production
|
||||
privileged: true
|
||||
container_name: prod-trf-gen
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.61.200
|
||||
entrypoint: /bin/bash -c "ip route add 12.1.1.0/24 via 192.168.61.197 dev eth0; sleep infinity"
|
||||
healthcheck:
|
||||
test: /bin/bash -c "ip route | grep '12.1.1.0'"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
networks:
|
||||
private_net:
|
||||
name: prod-oai-private-net
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 192.168.68.0/26
|
||||
driver_opts:
|
||||
com.docker.network.bridge.name: "oai-priv-net"
|
||||
public_net:
|
||||
name: prod-oai-public-net
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 192.168.61.192/26
|
||||
driver_opts:
|
||||
com.docker.network.bridge.name: "oai-pub-net"
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
|
||||
INSTANCE=1
|
||||
PREFIX='/magma-mme/etc'
|
||||
MY_REALM='openairinterface.org'
|
||||
|
||||
declare -A MME_CONF
|
||||
|
||||
pushd $PREFIX
|
||||
MME_CONF[@MME_S6A_IP_ADDR@]="192.168.61.195"
|
||||
MME_CONF[@INSTANCE@]=$INSTANCE
|
||||
MME_CONF[@PREFIX@]=$PREFIX
|
||||
MME_CONF[@REALM@]=$MY_REALM
|
||||
MME_CONF[@MME_FQDN@]="mme.${MME_CONF[@REALM@]}"
|
||||
MME_CONF[@HSS_HOSTNAME@]='hss'
|
||||
MME_CONF[@HSS_FQDN@]="${MME_CONF[@HSS_HOSTNAME@]}.${MME_CONF[@REALM@]}"
|
||||
MME_CONF[@HSS_IP_ADDR@]="192.168.61.194"
|
||||
|
||||
cp mme_fd.conf.tmplt $PREFIX/mme_fd.conf
|
||||
|
||||
for K in "${!MME_CONF[@]}"; do
|
||||
egrep -lRZ "$K" $PREFIX/mme_fd.conf | xargs -0 -l sed -i -e "s|$K|${MME_CONF[$K]}|g"
|
||||
ret=$?;[[ ret -ne 0 ]] && echo "Tried to replace $K with ${MME_CONF[$K]}"
|
||||
done
|
||||
|
||||
sed -i -e "s@etc/freeDiameter@etc@" /magma-mme/etc/mme_fd.conf
|
||||
sed -i -e "s@bind: 127.0.0.1@bind: 192.168.61.198@" /etc/magma/redis.yml
|
||||
# Generate freeDiameter certificate
|
||||
popd
|
||||
cd /magma-mme/scripts
|
||||
./check_mme_s6a_certificate $PREFIX mme.${MME_CONF[@REALM@]}
|
||||
|
||||
cd /magma-mme
|
||||
nohup /magma-mme/bin/sctpd > /var/log/sctpd.log 2>&1 &
|
||||
sleep 5
|
||||
/magma-mme/bin/oai_mme -c /magma-mme/etc/mme.conf
|
||||
@@ -0,0 +1,136 @@
|
||||
# generated by generate_mme_config_script.py
|
||||
MME :
|
||||
{
|
||||
REALM = "openairinterface.org"
|
||||
PID_DIRECTORY = "/var/run";
|
||||
MAXENB = 8; # power of 2
|
||||
MAXUE = 16; # power of 2
|
||||
RELATIVE_CAPACITY = 10;
|
||||
|
||||
EMERGENCY_ATTACH_SUPPORTED = "no";
|
||||
UNAUTHENTICATED_IMSI_SUPPORTED = "no";
|
||||
|
||||
# EPS network feature support
|
||||
EPS_NETWORK_FEATURE_SUPPORT_IMS_VOICE_OVER_PS_SESSION_IN_S1 = "no"; # DO NOT CHANGE
|
||||
EPS_NETWORK_FEATURE_SUPPORT_EMERGENCY_BEARER_SERVICES_IN_S1_MODE = "no"; # DO NOT CHANGE
|
||||
EPS_NETWORK_FEATURE_SUPPORT_LOCATION_SERVICES_VIA_EPC = "no"; # DO NOT CHANGE
|
||||
EPS_NETWORK_FEATURE_SUPPORT_EXTENDED_SERVICE_REQUEST = "no"; # DO NOT CHANGE
|
||||
|
||||
# Display statistics about whole system (expressed in seconds)
|
||||
MME_STATISTIC_TIMER = 10;
|
||||
IP_CAPABILITY = "IPV4"; # UE PDN_TYPE
|
||||
USE_STATELESS = "";
|
||||
|
||||
INTERTASK_INTERFACE :
|
||||
{
|
||||
# max queue size per task
|
||||
ITTI_QUEUE_SIZE = 2000000;
|
||||
};
|
||||
|
||||
S6A :
|
||||
{
|
||||
S6A_CONF = "/magma-mme/etc/mme_fd.conf"; # YOUR MME freeDiameter config file path
|
||||
HSS_HOSTNAME = "hss.openairinterface.org";
|
||||
HSS_REALM = "openairinterface.org";
|
||||
};
|
||||
|
||||
# ------- SCTP definitions
|
||||
SCTP :
|
||||
{
|
||||
# Number of streams to use in input/output
|
||||
SCTP_INSTREAMS = 8;
|
||||
SCTP_OUTSTREAMS = 8;
|
||||
};
|
||||
|
||||
# ------- S1AP definitions
|
||||
S1AP :
|
||||
{
|
||||
# outcome drop timer value (seconds)
|
||||
S1AP_OUTCOME_TIMER = 10;
|
||||
};
|
||||
|
||||
# ------- MME served GUMMEIs
|
||||
GUMMEI_LIST = (
|
||||
{ MCC="208" ; MNC="97"; MME_GID="32768" ; MME_CODE="3"; }
|
||||
);
|
||||
|
||||
# ------- MME served TAIs
|
||||
TAI_LIST = (
|
||||
{MCC="208" ; MNC="97"; TAC = "1"; },
|
||||
{MCC="208" ; MNC="97"; TAC = "2"; },
|
||||
{MCC="208" ; MNC="97"; TAC = "3"; }
|
||||
);
|
||||
|
||||
TAC_LIST = (
|
||||
{MCC="208" ; MNC="97"; TAC = "1"; }
|
||||
);
|
||||
|
||||
CSFB :
|
||||
{
|
||||
NON_EPS_SERVICE_CONTROL = "OFF";
|
||||
CSFB_MCC = "208";
|
||||
CSFB_MNC = "97";
|
||||
LAC = "1";
|
||||
};
|
||||
NAS :
|
||||
{
|
||||
ORDERED_SUPPORTED_INTEGRITY_ALGORITHM_LIST = [ "EIA2" , "EIA1" , "EIA0" ];
|
||||
ORDERED_SUPPORTED_CIPHERING_ALGORITHM_LIST = [ "EEA0" , "EEA1" , "EEA2" ];
|
||||
T3402 = 1 # in minutes (default is 12 minutes)
|
||||
T3412 = 54 # in minutes (default is 54 minutes, network dependent)
|
||||
T3422 = 6 # in seconds (default is 6s)
|
||||
T3450 = 6 # in seconds (default is 6s)
|
||||
T3460 = 6 # in seconds (default is 6s)
|
||||
T3470 = 6 # in seconds (default is 6s)
|
||||
T3485 = 8 # UNUSED in seconds (default is 8s)
|
||||
T3486 = 8 # UNUSED in seconds (default is 8s)
|
||||
T3489 = 4 # UNUSED in seconds (default is 4s)
|
||||
T3495 = 8 # UNUSED in seconds (default is 8s)
|
||||
};
|
||||
|
||||
SGS :
|
||||
{
|
||||
TS6_1 = 10 # in seconds (default is 10s)
|
||||
TS8 = 4 # in seconds (default is 4s)
|
||||
TS9 = 2 # in seconds (default is 4s)
|
||||
TS10 = 4 # in seconds (default is 4s)
|
||||
TS13 = 4 # in seconds (default is 4s)
|
||||
};
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
MME_INTERFACE_NAME_FOR_S1_MME = "eth0";
|
||||
MME_IPV4_ADDRESS_FOR_S1_MME = "192.168.61.195/24";
|
||||
MME_INTERFACE_NAME_FOR_S11_MME = "eth0";
|
||||
MME_IPV4_ADDRESS_FOR_S11_MME = "192.168.61.195/24";
|
||||
MME_PORT_FOR_S11_MME = 2123;
|
||||
};
|
||||
|
||||
LOGGING :
|
||||
{
|
||||
OUTPUT = "CONSOLE";
|
||||
THREAD_SAFE = "no";
|
||||
COLOR = "no";
|
||||
|
||||
SCTP_LOG_LEVEL = "ERROR";
|
||||
GTPV1U_LOG_LEVEL = "INFO";
|
||||
SPGW_APP_LOG_LEVEL = "INFO";
|
||||
UDP_LOG_LEVEL = "INFO";
|
||||
S1AP_LOG_LEVEL = "DEBUG";
|
||||
NAS_LOG_LEVEL = "INFO";
|
||||
MME_APP_LOG_LEVEL = "DEBUG";
|
||||
GTPV2C_LOG_LEVEL = "INFO";
|
||||
S11_LOG_LEVEL = "DEBUG";
|
||||
S6A_LOG_LEVEL = "DEBUG";
|
||||
UTIL_LOG_LEVEL = "INFO";
|
||||
MSC_LOG_LEVEL = "ERROR";
|
||||
ITTI_LOG_LEVEL = "ERROR";
|
||||
MME_SCENARIO_PLAYER_LOG_LEVEL = "ERROR";
|
||||
ASN1_VERBOSITY = "INFO";
|
||||
};
|
||||
|
||||
S-GW :
|
||||
{
|
||||
SGW_IPV4_ADDRESS_FOR_S11 = "192.168.61.196";
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,169 @@
|
||||
# -------- Local ---------
|
||||
|
||||
# Uncomment if the framework cannot resolv it.
|
||||
Identity = "@MME_FQDN@";
|
||||
Realm = "@REALM@";
|
||||
|
||||
# TLS configuration (see previous section)
|
||||
TLS_Cred = "@PREFIX@/freeDiameter/mme.cert.pem",
|
||||
"@PREFIX@/freeDiameter/mme.key.pem";
|
||||
TLS_CA = "@PREFIX@/freeDiameter/mme.cacert.pem";
|
||||
|
||||
# Disable use of TCP protocol (only listen and connect in SCTP)
|
||||
# Default : TCP enabled
|
||||
No_SCTP;
|
||||
|
||||
# This option is ignored if freeDiameter is compiled with DISABLE_SCTP option.
|
||||
# Prefer TCP instead of SCTP for establishing new connections.
|
||||
# This setting may be overwritten per peer in peer configuration blocs.
|
||||
# Default : SCTP is attempted first.
|
||||
Prefer_TCP;
|
||||
|
||||
|
||||
No_IPv6;
|
||||
|
||||
# Overwrite the number of SCTP streams. This value should be kept low,
|
||||
# especially if you are using TLS over SCTP, because it consumes a lot of
|
||||
# resources in that case. See tickets 19 and 27 for some additional details on
|
||||
# this.
|
||||
# Limit the number of SCTP streams
|
||||
SCTP_streams = 3;
|
||||
|
||||
|
||||
# By default, freeDiameter acts as a Diameter Relay Agent by forwarding all
|
||||
# messages it cannot handle locally. This parameter disables this behavior.
|
||||
NoRelay;
|
||||
|
||||
# Use RFC3588 method for TLS protection, where TLS is negociated after CER/CEA exchange is completed
|
||||
# on the unsecure connection. The alternative is RFC6733 mechanism, where TLS protects also the
|
||||
# CER/CEA exchange on a dedicated secure port.
|
||||
# This parameter only affects outgoing connections.
|
||||
# The setting can be also defined per-peer (see Peers configuration section).
|
||||
# Default: use RFC6733 method with separate port for TLS.
|
||||
|
||||
#TLS_old_method;
|
||||
|
||||
AppServThreads = 4;
|
||||
|
||||
# Specify the addresses on which to bind the listening server. This must be
|
||||
# specified if the framework is unable to auto-detect these addresses, or if the
|
||||
# auto-detected values are incorrect. Note that the list of addresses is sent
|
||||
# in CER or CEA message, so one should pay attention to this parameter if some
|
||||
# adresses should be kept hidden.
|
||||
ListenOn = "@MME_S6A_IP_ADDR@";
|
||||
|
||||
Port = 3870;
|
||||
SecPort = 5870;
|
||||
|
||||
# -------- Extensions ---------
|
||||
|
||||
# Uncomment (and create rtd.conf) to specify routing table for this peer.
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/rt_default.fdx" : "rtd.conf";
|
||||
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/_sample.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/app_acct.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/app_diameap.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/app_radgw.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/app_redirect.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/app_sip.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dbg_interactive.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dbg_monitor.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dbg_msg_dumps.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dbg_msg_timings.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dbg_rt.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_3gpp2_avps.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dict_CreditControl.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dict_CxDx.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dict_Gx.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dict_NAS.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dict_Ro.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dict_Rx.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dict_S6mS6n.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dict_SGd.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dict_SLh.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dict_Sd.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dict_Sh.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dict_T4.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dict_T6aT6bT7.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dict_Tsp.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dict_dcca.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dict_dcca_3gpp.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dict_dcca_starent.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_draftload_avps.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dict_eap.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_etsi283034_avps.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dict_legacy_xml.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dict_mip6a.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dict_mip6i.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dict_nas_mipv6.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dict_nasreq.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc4004_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc4006bis_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc4072_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc4590_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc5447_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc5580_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc5777_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc5778_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc6734_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc6942_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc7155_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc7683_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc7944_avps.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dict_sip.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29061_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29128_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29154_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29173_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29212_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29214_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29215_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29217_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29229_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29272_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29273_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29329_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29336_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29337_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29338_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29343_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29344_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29345_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29368_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29468_avps.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_ts32299_avps.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/rt_busypeers.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/rt_default.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/rt_ereg.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/rt_ignore_dh.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/rt_load_balance.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/rt_randomize.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/rt_redirect.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/test_acct.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/test_app.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/test_hss.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/test_netemul.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/test_rt_any.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/test_sip.fdx";
|
||||
#LoadExtension = "/usr/local/lib/freeDiameter/dict_Rf.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_S6as6d.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_S6t.fdx";
|
||||
LoadExtension = "/usr/local/lib/freeDiameter/dict_S6c.fdx";
|
||||
|
||||
|
||||
# -------- Peers ---------
|
||||
|
||||
# The framework will actively attempt to establish and maintain a connection
|
||||
# with the peers listed here.
|
||||
# For only accepting incoming connections, see the acl_wl.fx extension.
|
||||
|
||||
# ConnectPeer
|
||||
# Declare a remote peer to which this peer must maintain a connection.
|
||||
# In addition, this allows specifying non-default parameters for this peer only
|
||||
# (for example disable SCTP with this peer, or use RFC3588-flavour TLS).
|
||||
# Note that by default, if a peer is not listed as a ConnectPeer entry, an
|
||||
# incoming connection from this peer will be rejected. If you want to accept
|
||||
# incoming connections from other peers, see the acl_wl.fdx? extension which
|
||||
# allows exactly this.
|
||||
|
||||
ConnectPeer= "@HSS_FQDN@" { ConnectTo = "@HSS_IP_ADDR@"; No_SCTP ; No_IPv6; Prefer_TCP; No_TLS; port = 3868;};
|
||||
@@ -0,0 +1,33 @@
|
||||
#
|
||||
# Copyright (c) 2016-present, Facebook, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under the BSD-style license found in the
|
||||
# LICENSE file in the root directory of this source tree. An additional grant
|
||||
# of patent rights can be found in the PATENTS file in the same directory.
|
||||
|
||||
# Jinja template for Redis configuration
|
||||
# See the default config file for options and explanations:
|
||||
# https://github.com/antirez/redis/blob/unstable/redis.conf
|
||||
|
||||
# TODO: make sensible, production-aware config decisions
|
||||
|
||||
bind 192.168.61.198
|
||||
port 6380
|
||||
|
||||
daemonize no
|
||||
loglevel notice
|
||||
|
||||
timeout 0
|
||||
databases 1
|
||||
|
||||
dbfilename redis_dump.rdb
|
||||
dir /data
|
||||
|
||||
# Save the DB on disk
|
||||
|
||||
save 900 1
|
||||
|
||||
save 300 10
|
||||
|
||||
save 60 1000
|
||||
@@ -309,6 +309,7 @@ endif()
|
||||
|
||||
#
|
||||
# add autotools definitions that were maybe used!
|
||||
|
||||
add_definitions("-DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP")
|
||||
|
||||
set(commonOpts "-pipe -Wno-packed-bitfield-compat -fPIC -Wall -fno-strict-aliasing -rdynamic")
|
||||
@@ -318,11 +319,7 @@ set(CMAKE_C_FLAGS
|
||||
set(CMAKE_CXX_FLAGS
|
||||
"${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} ${commonOpts} -std=c++11")
|
||||
|
||||
# cuda compiler bug (limitation) on complex macro definition
|
||||
if (CUDA_FOUND)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DCUDA_FLAG")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCUDA_FLAG")
|
||||
endif()
|
||||
|
||||
|
||||
if (SANITIZE_ADDRESS)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-common")
|
||||
@@ -332,11 +329,11 @@ endif ()
|
||||
add_definitions("-DASN_DISABLE_OER_SUPPORT")
|
||||
|
||||
#########################
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ggdb3 -Wl,-rpath -Wl,${CMAKE_CURRENT_BINARY_DIR}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ggdb2 -Wl,-rpath -Wl,${CMAKE_CURRENT_BINARY_DIR}")
|
||||
#########################
|
||||
# set a flag for changes in the source code
|
||||
# these changes are related to hardcoded path to include .h files
|
||||
set(debugOpt "-ggdb3 -DMALLOC_CHECK_=3 -fno-delete-null-pointer-checks")
|
||||
set(debugOpt "-ggdb2 -DMALLOC_CHECK_=3 -fno-delete-null-pointer-checks")
|
||||
set(CMAKE_C_FLAGS_DEBUG "${debugOpt} -O0")
|
||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${debugOpt} -O2")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-O3")
|
||||
@@ -1590,6 +1587,16 @@ set(PHY_LDPC_OPTIM8SEGMULTI_SRC
|
||||
${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c
|
||||
${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c
|
||||
)
|
||||
set(PHY_LDPC_CUDA_SRC
|
||||
${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu
|
||||
${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c
|
||||
)
|
||||
|
||||
set(PHY_LDPC_CL_SRC
|
||||
${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_CL.c
|
||||
${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c
|
||||
)
|
||||
|
||||
set(PHY_NR_CODINGIF
|
||||
${OPENAIR1_DIR}/PHY/CODING/nrLDPC_load.c;
|
||||
)
|
||||
@@ -1597,8 +1604,18 @@ set(PHY_NR_CODINGIF
|
||||
add_library(ldpc_orig MODULE ${PHY_LDPC_ORIG_SRC} )
|
||||
add_library(ldpc_optim MODULE ${PHY_LDPC_OPTIM_SRC} )
|
||||
add_library(ldpc_optim8seg MODULE ${PHY_LDPC_OPTIM8SEG_SRC} )
|
||||
add_library(ldpc_cl MODULE ${PHY_LDPC_CL_SRC} )
|
||||
target_link_libraries(ldpc_cl OpenCL)
|
||||
|
||||
if (CUDA_FOUND)
|
||||
cuda_add_library(ldpc_cuda MODULE ${PHY_LDPC_CUDA_SRC} )
|
||||
set_target_properties(ldpc_cuda PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
|
||||
# CUDA_ADD_CUFFT_TO_TARGET(ldpc_cuda)
|
||||
endif (CUDA_FOUND)
|
||||
|
||||
add_library(ldpc MODULE ${PHY_LDPC_OPTIM8SEGMULTI_SRC} )
|
||||
|
||||
|
||||
add_library(coding MODULE ${PHY_TURBOSRC} )
|
||||
|
||||
add_library(dfts MODULE ${OPENAIR1_DIR}/PHY/TOOLS/oai_dfts.c )
|
||||
@@ -1744,7 +1761,6 @@ set(PHY_SRC_UE
|
||||
|
||||
set(PHY_NR_SRC_COMMON
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_prach_common.c
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dci_tools_common.c
|
||||
)
|
||||
|
||||
set(PHY_NR_SRC
|
||||
@@ -1983,6 +1999,10 @@ set(NR_PDCP_SRC
|
||||
${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c
|
||||
)
|
||||
|
||||
set(NR_SDAP_SRC
|
||||
${OPENAIR2_DIR}/SDAP/nr_sdap/nr_sdap_gnb.c
|
||||
)
|
||||
|
||||
set(L2_SRC
|
||||
${PDCP_DIR}/pdcp.c
|
||||
${PDCP_DIR}/pdcp_fifo.c
|
||||
@@ -2026,6 +2046,7 @@ set(L2_LTE_SRC
|
||||
set(L2_NR_SRC
|
||||
${NR_RLC_SRC}
|
||||
${NR_PDCP_SRC}
|
||||
${NR_SDAP_SRC}
|
||||
${NR_RRC_DIR}/rrc_gNB.c
|
||||
${NR_RRC_DIR}/nr_rrc_common.c
|
||||
${NR_RRC_DIR}/L2_nr_interface.c
|
||||
@@ -2061,6 +2082,7 @@ set(L2_RRC_SRC_UE
|
||||
set(NR_L2_SRC_UE
|
||||
${NR_RLC_SRC}
|
||||
${NR_PDCP_SRC}
|
||||
${NR_SDAP_SRC}
|
||||
${NR_UE_RRC_DIR}/L2_interface_ue.c
|
||||
${NR_UE_RRC_DIR}/main_ue.c
|
||||
${NR_UE_RRC_DIR}/rrc_UE.c
|
||||
@@ -3113,7 +3135,11 @@ target_link_libraries (nr-uesoftmodem ${LIB_LMS_LIBRARIES})
|
||||
target_link_libraries (nr-uesoftmodem ${T_LIB})
|
||||
|
||||
add_dependencies( nr-uesoftmodem ldpc_orig ldpc_optim ldpc_optim8seg ldpc )
|
||||
|
||||
if (CUDA_FOUND)
|
||||
add_dependencies( nr-uesoftmodem ldpc_cuda)
|
||||
add_dependencies( nr-softmodem ldpc_cuda)
|
||||
add_dependencies( ocp-gnb ldpc_cuda)
|
||||
endif (CUDA_FOUND)
|
||||
###################################"
|
||||
# Addexecutables for tests
|
||||
####################################
|
||||
@@ -3173,46 +3199,18 @@ target_link_libraries(smallblocktest
|
||||
m pthread ${ATLAS_LIBRARIES} dl
|
||||
)
|
||||
|
||||
if (CUDA_FOUND)
|
||||
###################################################
|
||||
# For CUDA library
|
||||
###################################################
|
||||
|
||||
CUDA_ADD_LIBRARY(LDPC_CU
|
||||
${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu
|
||||
)
|
||||
CUDA_ADD_CUFFT_TO_TARGET(LDPC_CU)
|
||||
cuda_add_executable(ldpctest
|
||||
${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c
|
||||
${T_SOURCE}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
target_link_libraries(ldpctest -ldl
|
||||
-Wl,--start-group
|
||||
LDPC_CU UTIL SIMU PHY_NR CONFIG_LIB
|
||||
-Wl,--end-group
|
||||
m pthread ${ATLAS_LIBRARIES} dl
|
||||
)
|
||||
add_executable(ldpctest
|
||||
${PHY_NR_CODINGIF}
|
||||
${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c
|
||||
${T_SOURCE}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
|
||||
else (CUDA_FOUND)
|
||||
add_executable(ldpctest
|
||||
${PHY_NR_CODINGIF}
|
||||
${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c
|
||||
${T_SOURCE}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
|
||||
endif ()
|
||||
|
||||
|
||||
# add_executable(ldpctest
|
||||
# ${PHY_NR_CODINGIF}
|
||||
# ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c
|
||||
# ${T_SOURCE}
|
||||
# ${SHLIB_LOADER_SOURCES}
|
||||
# )
|
||||
add_dependencies( ldpctest ldpc_orig ldpc_optim ldpc_optim8seg ldpc )
|
||||
|
||||
if (CUDA_FOUND)
|
||||
add_dependencies( ldpctest ldpc_cuda)
|
||||
endif (CUDA_FOUND)
|
||||
target_link_libraries(ldpctest
|
||||
-Wl,--start-group UTIL SIMU_COMMON SIMU PHY_NR PHY_COMMON PHY_NR_COMMON CONFIG_LIB -Wl,--end-group
|
||||
m pthread ${ATLAS_LIBRARIES} dl
|
||||
|
||||
@@ -10,6 +10,10 @@ int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf)
|
||||
* If the farray pointer is null, looks for `< modname >_getfarray` symbol, calls the corresponding function when the symbol is found. `< modname >_getfarray` takes one argument, a pointer to a `loader_shlibfunc_t` array, and returns the number of items in this array, as defined by the `getfarrayfunc_t` type. The `loader_shlibfunc_t` array returned by the shared library must be fully filled (both `fname` and `fptr` fields).
|
||||
* looks for the `numf` function symbols listed in the `farray[i].fname` arguments and set the corresponding `farray[i].fptr`function pointers
|
||||
|
||||
```c
|
||||
int load_module_version_shlib(char *modname, char *version, loader_shlibfunc_t *farray, int numf)
|
||||
```
|
||||
Allows loading a specific library version, as specified by the `version` parameter. When version is not NULL the version that is possibly specified as a config module parameter is ignored. This call has been introduced for phy simulators executables which do not use the config module. It is used, for example, by the ldcp initialization (`load_nrLDPClib` function in [nrLDPC_load.c](../../../../../openair1/PHY/CODING/nrLDPC_load.c) to allow the `ldpctest` simulator to select the cuda accelerated ldcp implementation. `load_module_shlib` is just a define macro to switch to a `load_module_version_shlib` call, adding a NULL pointer for the version parameter.
|
||||
|
||||
```c
|
||||
void * get_shlibmodule_fptr(char *modname, char *fname)
|
||||
|
||||
@@ -63,7 +63,7 @@ void loader_init(void) {
|
||||
}
|
||||
|
||||
/* build the full shared lib name from the module name */
|
||||
char *loader_format_shlibpath(char *modname)
|
||||
char *loader_format_shlibpath(char *modname, char *version)
|
||||
{
|
||||
|
||||
char *tmpstr;
|
||||
@@ -97,7 +97,10 @@ int ret;
|
||||
shlibpath = loader_data.shlibpath ;
|
||||
}
|
||||
/* no specific shared lib version */
|
||||
if (shlibversion == NULL) {
|
||||
if (version != NULL) { // version specified as a function parameter
|
||||
shlibversion=version;
|
||||
}
|
||||
if (shlibversion == NULL) { // no specific version specified, neither as a config param or as a function param
|
||||
shlibversion = "" ;
|
||||
}
|
||||
/* alloc memory for full module shared lib file name */
|
||||
@@ -118,7 +121,7 @@ int ret;
|
||||
return tmpstr;
|
||||
}
|
||||
|
||||
int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf, void *autoinit_arg)
|
||||
int load_module_version_shlib(char *modname, char *version, loader_shlibfunc_t *farray, int numf, void *autoinit_arg)
|
||||
{
|
||||
void *lib_handle = NULL;
|
||||
initfunc_t fpi;
|
||||
@@ -138,7 +141,7 @@ int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf, void *
|
||||
loader_init();
|
||||
}
|
||||
|
||||
shlib_path = loader_format_shlibpath(modname);
|
||||
shlib_path = loader_format_shlibpath(modname, version);
|
||||
|
||||
for (int i = 0; i < loader_data.numshlibs; i++) {
|
||||
if (strcmp(loader_data.shlibs[i].name, modname) == 0) {
|
||||
|
||||
@@ -84,10 +84,11 @@ loader_data_t loader_data;
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------------*/
|
||||
#else /* LOAD_MODULE_SHLIB_MAIN */
|
||||
extern int load_module_shlib(char *modname, loader_shlibfunc_t *farray, int numf, void *initfunc_arg);
|
||||
|
||||
extern int load_module_version_shlib(char *modname, char *version, loader_shlibfunc_t *farray, int numf, void *initfunc_arg);
|
||||
extern void * get_shlibmodule_fptr(char *modname, char *fname);
|
||||
extern loader_data_t loader_data;
|
||||
#endif /* LOAD_MODULE_SHLIB_MAIN */
|
||||
|
||||
#define load_module_shlib(M, F, N, I) load_module_version_shlib(M, NULL, F, N, I)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -233,6 +233,30 @@ uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx) {
|
||||
}
|
||||
|
||||
|
||||
void get_coreset_rballoc(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)|
|
||||
(((uint64_t)FreqDomainResource[1])<<29)|
|
||||
(((uint64_t)FreqDomainResource[2])<<21)|
|
||||
(((uint64_t)FreqDomainResource[3])<<13)|
|
||||
(((uint64_t)FreqDomainResource[4])<<5)|
|
||||
(((uint64_t)FreqDomainResource[5])>>3);
|
||||
|
||||
for (int i=0; i<45; i++)
|
||||
if ((bitmap>>(44-i))&1) {
|
||||
count++;
|
||||
if (!start_set) {
|
||||
start = i;
|
||||
start_set = 1;
|
||||
}
|
||||
}
|
||||
*rb_offset = 6*start;
|
||||
*n_rb = 6*count;
|
||||
}
|
||||
|
||||
|
||||
int get_dmrs_port(int nl, uint16_t dmrs_ports) {
|
||||
|
||||
if (dmrs_ports == 0) return 0; // dci 1_0
|
||||
|
||||
@@ -51,6 +51,7 @@ typedef struct nr_bandentry_s {
|
||||
extern const size_t nr_bandtable_size;
|
||||
extern nr_bandentry_t nr_bandtable[];
|
||||
|
||||
void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset);
|
||||
int get_num_dmrs(uint16_t dmrs_mask);
|
||||
uint16_t config_bandwidth(int mu, int nb_rb, int nr_band);
|
||||
int get_nr_table_idx(int nr_bandP, uint8_t scs_index);
|
||||
|
||||
+1
-4
@@ -203,10 +203,7 @@ UE on machine 2:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[Selecting an alternative ldpc implementation at run time](../openair1/PHY/CODING/DOC/LDPCImplementation.md)
|
||||
|
||||
[oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
|
||||
|
||||
|
||||
@@ -436,7 +436,7 @@ int main( int argc, char **argv ) {
|
||||
itti_init(TASK_MAX, tasks_info);
|
||||
|
||||
init_opt() ;
|
||||
load_nrLDPClib();
|
||||
load_nrLDPClib(NULL);
|
||||
|
||||
if (ouput_vcd) {
|
||||
vcd_signal_dumper_init("/tmp/openair_dump_nrUE.vcd");
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
#LDPC coder/decoder implementation
|
||||
# LDPC coder/decoder implementation
|
||||
The LDPC coder and decoder are implemented in a shared library, dynamically loaded at run-time using the [oai shared library loader](file://../../../../common/utils/DOC/loader.md). The code loading the LDPC library is in [nrLDPC_load.c](file://../nrLDPC_load.c), in function `load_nrLDPClib`, which must be called at init time.
|
||||
|
||||
## Selecting the LDPC library at run time
|
||||
|
||||
By default the function `int load_nrLDPClib(void)` looks for `libldpc.so`, this default behavior can be changed using the oai loader configuration options in the configuration file or from the command line as shown below:
|
||||
|
||||
>loading `libldpc_optim8seg.so` instead of `libldpc.so`
|
||||
#### Examples of ldpc shared lib selection when running nr softmodem's:
|
||||
|
||||
loading `libldpc_optim8seg.so` instead of `libldpc.so`:
|
||||
|
||||
```
|
||||
./nr-softmodem -O libconfig:gnb.band78.tm1.106PRB.usrpx300.conf:dbgl5 --loader.ldpc.shlibversion _optim8seg
|
||||
@@ -18,9 +20,160 @@ By default the function `int load_nrLDPClib(void)` looks for `libldpc.so`, this
|
||||
........................
|
||||
```
|
||||
|
||||
Today, this mechanism is not available in the `ldpctest` phy simulator which doesn't initialize the [configuration module](file://../../../../common/config/DOC/config.md). loads `libldpc.so` and `libldpc_orig.so` to compare the performance of the two implementations.
|
||||
loading `libldpc_cl.so` instead of `libldpc.so`:
|
||||
|
||||
###LDPC libraries
|
||||
Libraries implementing the LDPC algorithms must be named `libldpc<_version>.so`, they must implement two functions: `nrLDPC_decod` and `nrLDPC_encod`. The prototypes for these functions is defined in [nrLDPC_defs.h](file://nrLDPC_defs.h).
|
||||
`make ldpc_cl`
|
||||
|
||||
`cp ../../../openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_kernels_CL.cl`
|
||||
|
||||
`./nr-softmodem -O libconfig:gnb.band78.sa.fr1.106PRB.usrpb210.conf:dbgl5 --rfsim --rfsimulator.serveraddr server --sa --log_config.gtpu_log_level info --loader.ldpc.shlibversion _cl`
|
||||
|
||||
``` [LOADER] library libldpc_cl.so successfully loaded
|
||||
------------------------------------------------
|
||||
[HW] Platform 0, OpenCL profile FULL_PROFILE
|
||||
[HW] Platform 0, OpenCL version OpenCL 2.1 LINUX
|
||||
[HW] Device 0 is available
|
||||
[HW] Device 0, type 2 = 0x00000002: cpu
|
||||
[HW] Device 0, number of Compute Units: 8
|
||||
[HW] Device 0, max Work Items dimension: 3
|
||||
[HW] Device 0, max Work Items size for dimension: 0 8192
|
||||
[HW] Device 0, max Work Items size for dimension: 1 8192
|
||||
[HW] Device 0, max Work Items size for dimension: 2 8192
|
||||
[New Thread 0x7fffcc258700 (LWP 3945123)]
|
||||
[New Thread 0x7fffc3e57700 (LWP 3945124)]
|
||||
[New Thread 0x7fffcbe57700 (LWP 3945125)]
|
||||
[New Thread 0x7fffcba56700 (LWP 3945126)]
|
||||
[New Thread 0x7fffcb254700 (LWP 3945128)]
|
||||
[New Thread 0x7fffcb655700 (LWP 3945127)]
|
||||
[New Thread 0x7fffcae53700 (LWP 3945129)]
|
||||
[HW] Platform 1, OpenCL profile FULL_PROFILE
|
||||
[HW] Platform 1, OpenCL version OpenCL 2.0 beignet 1.3
|
||||
[New Thread 0x7fffc965a700 (LWP 3945130)]
|
||||
[Thread 0x7fffc965a700 (LWP 3945130) exited]
|
||||
[HW] Device 0 is available
|
||||
[HW] Device 0, type 4 = 0x00000004: gpu
|
||||
[HW] Device 0, number of Compute Units: 20
|
||||
[HW] Device 0, max Work Items dimension: 3
|
||||
[HW] Device 0, max Work Items size for dimension: 0 512
|
||||
[HW] Device 0, max Work Items size for dimension: 1 512
|
||||
[HW] Device 0, max Work Items size for dimension: 2 512
|
||||
-----------------------------------------------------------------
|
||||
```
|
||||
|
||||
`./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --rfsim --sa -O libconfig:/usr/local/oai/conf/nrue_sim.conf:dbgl5 --nokrnmod --loader.ldpc.shlibversion _cl --log_config.hw_log_level info`
|
||||
|
||||
```[CONFIG] shlibversion set to _cl from command line
|
||||
............................................................
|
||||
[CONFIG] loader.ldpc 1 options set from command line
|
||||
[LOADER] library libldpc_cl.so successfully loaded
|
||||
[HW] Platform 0, OpenCL profile FULL_PROFILE
|
||||
[HW] Platform 0, OpenCL version OpenCL 2.1 LINUX
|
||||
[HW] Device 0 is available
|
||||
[HW] Device 0, type 2 = 0x00000002: cpu
|
||||
[HW] Device 0, number of Compute Units: 8
|
||||
[HW] Device 0, max Work Items dimension: 3
|
||||
[HW] Device 0, max Work Items size for dimension: 0 8192
|
||||
[HW] Device 0, max Work Items size for dimension: 1 8192
|
||||
[HW] Device 0, max Work Items size for dimension: 2 8192
|
||||
[New Thread 0x7fffecccc700 (LWP 3945413)]
|
||||
[New Thread 0x7fffec8cb700 (LWP 3945415)]
|
||||
[New Thread 0x7fffec4ca700 (LWP 3945414)]
|
||||
[New Thread 0x7fffdf7fd700 (LWP 3945417)]
|
||||
[New Thread 0x7fffdfbfe700 (LWP 3945418)]
|
||||
[New Thread 0x7fffdffff700 (LWP 3945416)]
|
||||
[New Thread 0x7fffd73fc700 (LWP 3945419)]
|
||||
[HW] Platform 1, OpenCL profile FULL_PROFILE
|
||||
[HW] Platform 1, OpenCL version OpenCL 2.0 beignet 1.3
|
||||
[New Thread 0x7fffde105700 (LWP 3945420)]
|
||||
[Thread 0x7fffde105700 (LWP 3945420) exited]
|
||||
[HW] Device 0 is available
|
||||
[HW] Device 0, type 4 = 0x00000004: gpu
|
||||
[HW] Device 0, number of Compute Units: 20
|
||||
[HW] Device 0, max Work Items dimension: 3
|
||||
[HW] Device 0, max Work Items size for dimension: 0 512
|
||||
[HW] Device 0, max Work Items size for dimension: 1 512
|
||||
[HW] Device 0, max Work Items size for dimension: 2 512
|
||||
------------------------------------------------------------
|
||||
```
|
||||
```
|
||||
|
||||
A mechanism to select ldpc implementation is also available in the `ldpctest` phy simulator via the `-v`option, which can be used to specify the version of the ldpc shared library to be used.
|
||||
|
||||
#### Examples of ldpc shared lib selection when running ldpctest:
|
||||
|
||||
Loading libldpc_cuda.so, the cuda implementation of the ldpc decoder:
|
||||
|
||||
```$ ./ldpctest -v _cuda
|
||||
Initializing random number generator, seed 0
|
||||
block length 8448:
|
||||
n_trials 1:
|
||||
SNR0 -2.000000:
|
||||
[CONFIG] get parameters from cmdline , debug flags: 0x00400000
|
||||
[CONFIG] log_config: 2/3 parameters successfully set
|
||||
[CONFIG] log_config: 53/53 parameters successfully set
|
||||
[CONFIG] log_config: 53/53 parameters successfully set
|
||||
[CONFIG] log_config: 16/16 parameters successfully set
|
||||
[CONFIG] log_config: 16/16 parameters successfully set
|
||||
log init done
|
||||
[CONFIG] loader: 2/2 parameters successfully set
|
||||
[CONFIG] loader.ldpc: 1/2 parameters successfully set
|
||||
[LOADER] library libldpc_cuda.so successfully loaded
|
||||
...................................
|
||||
```
|
||||
```
|
||||
|
||||
Loading libldpc_cl.so, the opencl implementation of the ldpc decoder:
|
||||
|
||||
`make ldpc_cl`
|
||||
|
||||
`cp ../../../openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_kernels_CL.cl`
|
||||
|
||||
`./ldpctest -v _cl`
|
||||
|
||||
```$ ./ldpctest -v _cl
|
||||
Initializing random number generator, seed 0
|
||||
block length 8448:
|
||||
n_trials 1:
|
||||
SNR0 -2.000000:
|
||||
[CONFIG] get parameters from cmdline , debug flags: 0x00400000
|
||||
[CONFIG] log_config: 2/3 parameters successfully set
|
||||
[CONFIG] log_config: 53/53 parameters successfully set
|
||||
[CONFIG] log_config: 53/53 parameters successfully set
|
||||
[CONFIG] log_config: 16/16 parameters successfully set
|
||||
[CONFIG] log_config: 16/16 parameters successfully set
|
||||
log init done
|
||||
[CONFIG] loader: 2/2 parameters successfully set
|
||||
[CONFIG] loader.ldpc: 1/2 parameters successfully set
|
||||
[LOADER] library libldpc_cl.so successfully loaded
|
||||
[HW] Platform 0, OpenCL profile FULL_PROFILE
|
||||
[HW] Platform 0, OpenCL version OpenCL 2.1 LINUX
|
||||
[HW] Device 0 is available
|
||||
[HW] Device 0, type 2 = 0x00000002: cpu
|
||||
[HW] Device 0, number of Compute Units: 8
|
||||
[HW] Device 0, max Work Items dimension: 3
|
||||
[HW] Device 0, max Work Items size for dimension: 0 8192
|
||||
[HW] Device 0, max Work Items size for dimension: 1 8192
|
||||
[HW] Device 0, max Work Items size for dimension: 2 8192
|
||||
[HW] Platform 1, OpenCL profile FULL_PROFILE
|
||||
[HW] Platform 1, OpenCL version OpenCL 2.0 beignet 1.3
|
||||
[HW] Device 0 is available
|
||||
[HW] Device 0, type 4 = 0x00000004: gpu
|
||||
[HW] Device 0, number of Compute Units: 20
|
||||
[HW] Device 0, max Work Items dimension: 3
|
||||
[HW] Device 0, max Work Items size for dimension: 0 512
|
||||
[HW] Device 0, max Work Items size for dimension: 1 512
|
||||
[HW] Device 0, max Work Items size for dimension: 2 512
|
||||
................................
|
||||
```
|
||||
```
|
||||
|
||||
|
||||
|
||||
### LDPC libraries
|
||||
Libraries implementing the LDPC algorithms must be named `libldpc<_version>.so`, they must implement three functions: `nrLDPC_initcall` `nrLDPC_decod` and `nrLDPC_encod`. The prototypes for these functions is defined in [nrLDPC_defs.h](file://nrLDPC_defs.h).
|
||||
|
||||
`libldpc_cuda.so`has been tested with the `ldpctest` executable, usage from the softmodem's has to be tested.
|
||||
|
||||
`libldpc_cl`is under development.
|
||||
|
||||
[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
|
||||
|
||||
@@ -101,8 +101,8 @@ int test_ldpc(short No_iteration,
|
||||
unsigned int *crc_misses,
|
||||
time_stats_t *time_optim,
|
||||
time_stats_t *time_decoder,
|
||||
n_iter_stats_t *dec_iter,
|
||||
short run_cuda)
|
||||
n_iter_stats_t *dec_iter
|
||||
)
|
||||
{
|
||||
//clock initiate
|
||||
//time_stats_t time,time_optim,tinput,tprep,tparity,toutput, time_decoder;
|
||||
@@ -393,28 +393,13 @@ int test_ldpc(short No_iteration,
|
||||
decParams.R=code_rate_vec[R_ind];//13;
|
||||
decParams.numMaxIter=No_iteration;
|
||||
decParams.outMode = nrLDPC_outMode_BIT;
|
||||
decParams.block_length=block_length;
|
||||
//decParams.outMode =nrLDPC_outMode_LLRINT8;
|
||||
#ifdef CUDA_FLAG
|
||||
set_compact_BG(Zc,BG);
|
||||
init_LLR_DMA_for_CUDA(&decParams, (int8_t*)channel_output_fixed[j], (int8_t*)estimated_output[j], block_length);
|
||||
#endif
|
||||
nrLDPC_initcall(&decParams, (int8_t*)channel_output_fixed[j], (int8_t*)estimated_output[j]);
|
||||
for(j=0;j<n_segments;j++) {
|
||||
start_meas(time_decoder);
|
||||
#ifdef CUDA_FLAG
|
||||
if(run_cuda){
|
||||
n_iter = nrLDPC_decoder_LYC(&decParams, (int8_t*)channel_output_fixed[j], (int8_t*)estimated_output[j], block_length, time_decoder);
|
||||
}
|
||||
else{
|
||||
// decode the sequence
|
||||
// decoder supports BG2, Z=128 & 256
|
||||
//esimated_output=ldpc_decoder(channel_output_fixed, block_length, No_iteration, (double)((float)nom_rate/(float)denom_rate));
|
||||
///nrLDPC_decoder(&decParams, channel_output_fixed, estimated_output, NULL);
|
||||
n_iter = nrLDPC_decoder(&decParams, (int8_t*)channel_output_fixed[j], (int8_t*)estimated_output[j], p_nrLDPC_procBuf, p_decoder_profiler);
|
||||
}
|
||||
#else
|
||||
n_iter = nrLDPC_decoder(&decParams, (int8_t*)channel_output_fixed[j], (int8_t*)estimated_output[j], p_nrLDPC_procBuf, p_decoder_profiler);
|
||||
#endif
|
||||
stop_meas(time_decoder);
|
||||
stop_meas(time_decoder);
|
||||
}
|
||||
|
||||
//for (i=(Kb+nrows) * Zc-5;i<(Kb+nrows) * Zc;i++)
|
||||
@@ -514,17 +499,14 @@ int test_ldpc(short No_iteration,
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#ifdef CUDA_FLAG
|
||||
warmup_for_GPU();
|
||||
#endif
|
||||
|
||||
unsigned int errors, errors_bit, crc_misses;
|
||||
double errors_bit_uncoded;
|
||||
short block_length=8448; // decoder supports length: 1201 -> 1280, 2401 -> 2560
|
||||
|
||||
char *ldpc_version=NULL; /* version of the ldpc decoder library to use (XXX suffix to use when loading libldpc_XXX.so */
|
||||
short No_iteration=5;
|
||||
int n_segments=1;
|
||||
//double rate=0.333;
|
||||
short run_cuda = 0;
|
||||
|
||||
int nom_rate=1;
|
||||
int denom_rate=3;
|
||||
@@ -544,7 +526,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
short BG=0,Zc,Kb=0;
|
||||
|
||||
while ((c = getopt (argc, argv, "q:r:s:S:l:G:n:d:i:t:u:h")) != -1)
|
||||
while ((c = getopt (argc, argv, "q:r:s:S:l:G:n:d:i:t:u:hv:")) != -1)
|
||||
switch (c)
|
||||
{
|
||||
case 'q':
|
||||
@@ -564,7 +546,7 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
|
||||
case 'G':
|
||||
run_cuda = atoi(optarg);
|
||||
ldpc_version="_cuda";
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
@@ -590,9 +572,11 @@ int main(int argc, char *argv[])
|
||||
case 'u':
|
||||
test_uncoded = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
ldpc_version=strdup(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
default:
|
||||
printf("CURRENTLY SUPPORTED CODE RATES: \n");
|
||||
printf("BG1 (blocklength > 3840): 1/3, 2/3, 22/25 (8/9) \n");
|
||||
printf("BG2 (blocklength <= 3840): 1/5, 1/3, 2/3 \n\n");
|
||||
@@ -609,6 +593,7 @@ int main(int argc, char *argv[])
|
||||
printf("-t SNR simulation step, Default: 0.1\n");
|
||||
printf("-i Max decoder iterations, Default: 5\n");
|
||||
printf("-u Set SNR per coded bit, Default: 0\n");
|
||||
printf("-v XXX Set ldpc shared library version. libldpc_XXX.so will be used \n");
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
@@ -619,7 +604,10 @@ int main(int argc, char *argv[])
|
||||
printf("SNR0 %f: \n", SNR0);
|
||||
|
||||
|
||||
load_nrLDPClib();
|
||||
if (ldpc_version != NULL)
|
||||
load_nrLDPClib(ldpc_version);
|
||||
else
|
||||
load_nrLDPClib(NULL);
|
||||
load_nrLDPClib_ref("_orig", &encoder_orig);
|
||||
//for (block_length=8;block_length<=MAX_BLOCK_LENGTH;block_length+=8)
|
||||
|
||||
@@ -691,8 +679,7 @@ int main(int argc, char *argv[])
|
||||
&crc_misses,
|
||||
time_optim,
|
||||
time_decoder,
|
||||
dec_iter,
|
||||
run_cuda);
|
||||
dec_iter);
|
||||
|
||||
printf("SNR %f, BLER %f (%u/%d)\n", SNR, (float)decoded_errors[i]/(float)n_trials, decoded_errors[i], n_trials);
|
||||
printf("SNR %f, BER %f (%u/%d)\n", SNR, (float)errors_bit/(float)n_trials/(float)block_length/(double)n_segments, decoded_errors[i], n_trials);
|
||||
|
||||
@@ -46,7 +46,8 @@
|
||||
#endif
|
||||
|
||||
static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, t_nrLDPC_procBuf* p_procBuf, uint32_t numLLR, t_nrLDPC_lut* p_lut, t_nrLDPC_dec_params* p_decParams, t_nrLDPC_time_stats* p_profiler);
|
||||
|
||||
void nrLDPC_initcall(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out) {
|
||||
}
|
||||
int32_t nrLDPC_decod(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, t_nrLDPC_procBuf* p_procBuf, t_nrLDPC_time_stats* p_profiler)
|
||||
{
|
||||
uint32_t numLLR;
|
||||
|
||||
@@ -0,0 +1,436 @@
|
||||
/*
|
||||
* 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.0 (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 nrLDPC_decoder_CL.c
|
||||
* \brief ldpc decoder, openCL implementaion
|
||||
* \author Francois TABURET
|
||||
* \date 2021
|
||||
* \version 1.0
|
||||
* \note initial implem - translation of cuda version
|
||||
*/
|
||||
/* uses HW component id for log messages ( --log_config.hw_log_level <warning| info|debug|trace>) */
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <cuda_runtime.h>
|
||||
#include <CL/opencl.h>
|
||||
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
|
||||
#include "PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h"
|
||||
#include "assertions.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
|
||||
#define MAX_ITERATION 2
|
||||
#define MC 1
|
||||
|
||||
#define MAX_OCLDEV 10
|
||||
#define MAX_OCLRUNTIME 5
|
||||
|
||||
|
||||
#define CLSETKERNELARG(A,B,C,D) \
|
||||
rt=clSetKernelArg(A,B,C,D) ;\
|
||||
AssertFatal(rt == CL_SUCCESS, "Error %d setting kernel argument index %d\n" , (int)rt, B);
|
||||
|
||||
typedef struct{
|
||||
char x;
|
||||
char y;
|
||||
short value;
|
||||
} h_element;
|
||||
#include "../nrLDPC_decoder_LYC/bgs/BG1_compact_in_C.h"
|
||||
|
||||
typedef struct{
|
||||
cl_uint max_CU;
|
||||
cl_uint max_WID;
|
||||
size_t *max_WIS;
|
||||
} ocldev_t;
|
||||
|
||||
typedef struct {
|
||||
cl_kernel cnp_kernel_1st;
|
||||
cl_kernel cnp_kernel;
|
||||
cl_kernel vnp_kernel_normal;
|
||||
cl_kernel pack_decoded_bit;
|
||||
} oclkernels_t;
|
||||
|
||||
typedef struct{
|
||||
cl_uint num_devices;
|
||||
cl_device_id devices[MAX_OCLDEV];
|
||||
ocldev_t ocldev[MAX_OCLDEV];
|
||||
cl_context context;
|
||||
cl_program program;
|
||||
cl_mem dev_h_compact1;
|
||||
cl_mem dev_h_compact2;
|
||||
cl_mem dev_const_llr;
|
||||
cl_mem dev_llr;
|
||||
cl_mem dev_dt;
|
||||
cl_mem dev_tmp;
|
||||
oclkernels_t kernels[MAX_OCLDEV];
|
||||
cl_command_queue queue[MAX_OCLDEV];
|
||||
} oclruntime_t;
|
||||
|
||||
typedef struct{
|
||||
oclruntime_t runtime[MAX_OCLRUNTIME];
|
||||
} ocl_t;
|
||||
|
||||
|
||||
|
||||
ocl_t ocl;
|
||||
|
||||
|
||||
void set_compact_BG(int Zc,short BG){
|
||||
cl_uint rt;
|
||||
int row,col;
|
||||
if(BG == 1){
|
||||
row = 46;
|
||||
col = 68;
|
||||
}
|
||||
else{
|
||||
row = 42;
|
||||
col = 52;
|
||||
}
|
||||
int compact_row = 30;
|
||||
int compact_col = 19;
|
||||
if(BG==2){compact_row = 10, compact_col = 23;}
|
||||
int memorySize_h_compact1 = row * compact_col * sizeof(h_element);
|
||||
int memorySize_h_compact2 = compact_row * col * sizeof(h_element);
|
||||
int lift_index = 0;
|
||||
short lift_set[][9] = {
|
||||
{2,4,8,16,32,64,128,256},
|
||||
{3,6,12,24,48,96,192,384},
|
||||
{5,10,20,40,80,160,320},
|
||||
{7,14,28,56,112,224},
|
||||
{9,18,36,72,144,288},
|
||||
{11,22,44,88,176,352},
|
||||
{13,26,52,104,208},
|
||||
{15,30,60,120,240},
|
||||
{0}
|
||||
};
|
||||
|
||||
for(int i = 0; lift_set[i][0] != 0; i++){
|
||||
for(int j = 0; lift_set[i][j] != 0; j++){
|
||||
if(Zc == lift_set[i][j]){
|
||||
lift_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("\nZc = %d BG = %d\n",Zc,BG);
|
||||
ocl.runtime[0].dev_h_compact1 = clCreateBuffer(ocl.runtime[0].context, CL_MEM_READ_ONLY|CL_MEM_HOST_WRITE_ONLY, memorySize_h_compact1, NULL, (cl_int *)&rt);
|
||||
AssertFatal(rt == CL_SUCCESS, "Error %d creating buffer dev_h_compact1 for platform %i \n" , (int)rt, 0);
|
||||
ocl.runtime[0].dev_h_compact2 = clCreateBuffer(ocl.runtime[0].context, CL_MEM_READ_ONLY|CL_MEM_HOST_WRITE_ONLY, memorySize_h_compact2, NULL, (cl_int *)&rt);
|
||||
AssertFatal(rt == CL_SUCCESS, "Error %d creating buffer dev_h_compact2 for platform %i \n" , (int)rt, 0);
|
||||
h_element *h1;
|
||||
h_element *h2;
|
||||
switch(lift_index){
|
||||
case 0:
|
||||
h1 = host_h_compact1_I0;
|
||||
h2 = host_h_compact2_I0;
|
||||
break;
|
||||
case 1:
|
||||
h1 = host_h_compact1_I1;
|
||||
h2 = host_h_compact2_I1;
|
||||
break;
|
||||
case 2:
|
||||
h1 = host_h_compact1_I2;
|
||||
h2 = host_h_compact2_I2;
|
||||
break;
|
||||
case 3:
|
||||
h1 = host_h_compact1_I3;
|
||||
h2 = host_h_compact2_I3;
|
||||
break;
|
||||
case 4:
|
||||
h1 = host_h_compact1_I4;
|
||||
h2 = host_h_compact2_I4;
|
||||
break;
|
||||
case 5:
|
||||
h1 = host_h_compact1_I5;
|
||||
h2 = host_h_compact2_I5;
|
||||
break;
|
||||
case 6:
|
||||
h1 = host_h_compact1_I6;
|
||||
h2 = host_h_compact2_I6;
|
||||
break;
|
||||
case 7:
|
||||
h1 = host_h_compact1_I7;
|
||||
h2 = host_h_compact2_I7;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(0, "Invalid lift_index value %i\n" , lift_index);
|
||||
break;
|
||||
}
|
||||
rt = clEnqueueWriteBuffer(ocl.runtime[0].queue[0], ocl.runtime[0].dev_h_compact1, CL_TRUE, 0,memorySize_h_compact1, h1, 0, NULL, NULL);
|
||||
AssertFatal(rt == CL_SUCCESS, "Error %d moving h_compact1 memory to pltf %i dev %i\n" , (int)rt, 0,0);
|
||||
rt = clEnqueueWriteBuffer(ocl.runtime[0].queue[0], ocl.runtime[0].dev_h_compact2, CL_TRUE, 0,memorySize_h_compact2, h2, 0, NULL, NULL);
|
||||
AssertFatal(rt == CL_SUCCESS, "Error %d moving h_compact2 memory to pltf %i dev %i\n" , (int)rt, 0,0);
|
||||
// return 0;
|
||||
}
|
||||
void cl_error_callback(const char* errinfo, const void* private_info, size_t cb, void* user_data) {
|
||||
oclruntime_t *runtime = (oclruntime_t *)user_data;
|
||||
LOG_E(HW,"OpenCL accelerator error %s\n", errinfo );
|
||||
}
|
||||
|
||||
char *clutil_getstrdev(int intdev) {
|
||||
static char retstring[255]="";
|
||||
char *retptr=retstring;
|
||||
retptr+=sprintf(retptr,"0x%08x: ",(uint32_t)intdev);
|
||||
if (intdev & CL_DEVICE_TYPE_CPU)
|
||||
retptr+=sprintf(retptr,"%s","cpu ");
|
||||
if (intdev & CL_DEVICE_TYPE_GPU)
|
||||
retptr+=sprintf(retptr,"%s","gpu ");
|
||||
if (intdev & CL_DEVICE_TYPE_ACCELERATOR)
|
||||
retptr+=sprintf(retptr,"%s","acc ");
|
||||
return retstring;
|
||||
}
|
||||
|
||||
void get_CompilErr(cl_program program, int pltf) {
|
||||
|
||||
// Determine the size of the log
|
||||
size_t log_size;
|
||||
for(int i=0; i<ocl.runtime[pltf].num_devices;i++) {
|
||||
clGetProgramBuildInfo(program, ocl.runtime[pltf].devices[i], CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size);
|
||||
// Allocate memory for the log
|
||||
char *log = (char *) malloc(log_size);
|
||||
// Get the log
|
||||
clGetProgramBuildInfo(program, ocl.runtime[pltf].devices[i], CL_PROGRAM_BUILD_LOG, log_size, log, NULL);
|
||||
// Print the log
|
||||
printf("%s\n", log);
|
||||
free(log);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
size_t load_source(char **source_str) {
|
||||
int MAX_SOURCE_SIZE=(500*132);
|
||||
FILE *fp;
|
||||
size_t source_size;
|
||||
|
||||
fp = fopen("nrLDPC_decoder_kernels_CL.cl", "r");
|
||||
AssertFatal(fp,"failed to open cl source: %s\n",strerror(errno));
|
||||
|
||||
*source_str = (char*)malloc(MAX_SOURCE_SIZE);
|
||||
source_size = fread( *source_str, 1, MAX_SOURCE_SIZE, fp);
|
||||
fclose( fp );
|
||||
return source_size;
|
||||
}
|
||||
|
||||
/* from here: entry points in decoder shared lib */
|
||||
int ldpc_autoinit(void) { // called by the library loader
|
||||
cl_platform_id platforms[10];
|
||||
cl_uint num_platforms_found;
|
||||
int context_ok=0;
|
||||
cl_uint rt = clGetPlatformIDs( sizeof(platforms)/sizeof(cl_platform_id), platforms, &num_platforms_found );
|
||||
AssertFatal(rt == CL_SUCCESS, "clGetPlatformIDs error %d\n" , (int)rt);
|
||||
AssertFatal( num_platforms_found>0 , "clGetPlatformIDs: no cl compatible platform found\n");
|
||||
for (int i=0 ; i<(int)num_platforms_found ; i++) {
|
||||
char stringval[255];
|
||||
rt = clGetPlatformInfo(platforms[i],CL_PLATFORM_PROFILE, sizeof(stringval),stringval,NULL);
|
||||
AssertFatal(rt == CL_SUCCESS, "clGetPlatformInfo PROFILE error %d\n" , (int)rt);
|
||||
LOG_I(HW,"Platform %i, OpenCL profile %s\n", i,stringval );
|
||||
rt = clGetPlatformInfo(platforms[i],CL_PLATFORM_VERSION, sizeof(stringval),stringval,NULL);
|
||||
AssertFatal(rt == CL_SUCCESS, "clGetPlatformInfo VERSION error %d\n" , (int)rt);
|
||||
LOG_I(HW,"Platform %i, OpenCL version %s\n", i,stringval );
|
||||
rt = clGetDeviceIDs(platforms[i],CL_DEVICE_TYPE_ALL, sizeof(ocl.runtime[i].devices)/sizeof(cl_device_id),ocl.runtime[i].devices,&(ocl.runtime[i].num_devices));
|
||||
AssertFatal(rt == CL_SUCCESS, "clGetDeviceIDs error %d\n" , (int)rt);
|
||||
int devok=0;
|
||||
for (int j=0; j<ocl.runtime[i].num_devices; j++) {
|
||||
cl_bool abool;
|
||||
rt = clGetDeviceInfo(ocl.runtime[i].devices[j],CL_DEVICE_AVAILABLE, sizeof(abool),&abool,NULL);
|
||||
AssertFatal(rt == CL_SUCCESS, "clGetDeviceInfo DEVICE_AVAILABLE error %d\n" , (int)rt);
|
||||
LOG_I(HW,"Device %i is %s available\n", j, (abool==CL_TRUE?"":"not"));
|
||||
cl_device_type devtype;
|
||||
rt = clGetDeviceInfo(ocl.runtime[i].devices[j],CL_DEVICE_TYPE, sizeof(cl_device_type),&devtype,NULL);
|
||||
AssertFatal(rt == CL_SUCCESS, "clGetDeviceInfo DEVICE_TYPE error %d\n" , (int)rt);
|
||||
LOG_I(HW,"Device %i, type %d = %s\n", j,(int)devtype, clutil_getstrdev(devtype));
|
||||
rt = clGetDeviceInfo(ocl.runtime[i].devices[j],CL_DEVICE_MAX_COMPUTE_UNITS,sizeof(ocl.runtime[i].ocldev[j].max_CU),&(ocl.runtime[i].ocldev[j].max_CU),NULL);
|
||||
AssertFatal(rt == CL_SUCCESS, "clGetDeviceInfo MAX_COMPUTE_UNITS error %d\n" , (int)rt);
|
||||
LOG_I(HW,"Device %i, number of Compute Units: %d\n", j,ocl.runtime[i].ocldev[j].max_CU);
|
||||
rt = clGetDeviceInfo(ocl.runtime[i].devices[j],CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS,sizeof(ocl.runtime[i].ocldev[j].max_WID),&(ocl.runtime[i].ocldev[j].max_WID),NULL);
|
||||
AssertFatal(rt == CL_SUCCESS, "clGetDeviceInfo MAX_WORK_ITEM_DIMENSIONS error %d\n" , (int)rt);
|
||||
LOG_I(HW,"Device %i, max Work Items dimension: %d\n", j,ocl.runtime[i].ocldev[j].max_WID);
|
||||
ocl.runtime[i].ocldev[j].max_WIS = (size_t *)malloc(ocl.runtime[i].ocldev[j].max_WID * sizeof(size_t));
|
||||
rt = clGetDeviceInfo(ocl.runtime[i].devices[j],CL_DEVICE_MAX_WORK_ITEM_SIZES,sizeof(ocl.runtime[i].ocldev[j].max_WID)*sizeof(size_t),ocl.runtime[i].ocldev[j].max_WIS,NULL);
|
||||
AssertFatal(rt == CL_SUCCESS, "clGetDeviceInfo MAX_WORK_ITEM_SIZES error %d\n" , (int)rt);
|
||||
for(int k=0; k<ocl.runtime[i].ocldev[j].max_WID;k++)
|
||||
LOG_I(HW,"Device %i, max Work Items size for dimension: %d %u\n", j,k,(uint32_t)ocl.runtime[i].ocldev[j].max_WIS[k]);
|
||||
devok++;
|
||||
}
|
||||
if (devok >0) {
|
||||
ocl.runtime[i].context = clCreateContext(NULL, ocl.runtime[i].num_devices, ocl.runtime[i].devices, cl_error_callback, &(ocl.runtime[i]), (cl_int *)&rt);
|
||||
AssertFatal(rt == CL_SUCCESS, "Error %d creating context for platform %i\n" , (int)rt, i);
|
||||
for(int dev=0; dev<ocl.runtime[i].num_devices; dev++) {
|
||||
ocl.runtime[i].queue[dev] = clCreateCommandQueueWithProperties(ocl.runtime[i].context,ocl.runtime[i].devices[dev] , 0, (cl_int *)&rt);
|
||||
AssertFatal(rt == CL_SUCCESS, "Error %d creating command queue for platform %i device %i\n" , (int)rt, i,dev);
|
||||
}
|
||||
ocl.runtime[i].dev_const_llr = clCreateBuffer(ocl.runtime[i].context, CL_MEM_READ_ONLY|CL_MEM_HOST_WRITE_ONLY, 68*384, NULL, (cl_int *)&rt);
|
||||
AssertFatal(rt == CL_SUCCESS, "Error %d creating buffer dev_const_llr for platform %i \n" , (int)rt, i);
|
||||
ocl.runtime[i].dev_llr = clCreateBuffer(ocl.runtime[i].context, CL_MEM_READ_WRITE|CL_MEM_HOST_WRITE_ONLY, 68*384, NULL, (cl_int *)&rt);
|
||||
AssertFatal(rt == CL_SUCCESS, "Error %d creating buffer dev_llr for platform %i \n" , (int)rt, i);
|
||||
ocl.runtime[i].dev_dt = clCreateBuffer(ocl.runtime[i].context, CL_MEM_READ_WRITE|CL_MEM_HOST_NO_ACCESS, 46*68*384, NULL, (cl_int *)&rt);
|
||||
AssertFatal(rt == CL_SUCCESS, "Error %d creating buffer dev_dt for platform %i \n" , (int)rt, i);
|
||||
ocl.runtime[i].dev_tmp = clCreateBuffer(ocl.runtime[i].context, CL_MEM_READ_ONLY|CL_MEM_HOST_WRITE_ONLY, 68*384, NULL, (cl_int *)&rt);
|
||||
AssertFatal(rt == CL_SUCCESS, "Error %d creating buffer dev_tmp for platform %i \n" , (int)rt, i);
|
||||
char *source_str;
|
||||
size_t source_size=load_source(&source_str);
|
||||
cl_program program = clCreateProgramWithSource(ocl.runtime[i].context, 1,
|
||||
(const char **)&source_str, (const size_t *)&source_size, (cl_int *)&rt);
|
||||
AssertFatal(rt == CL_SUCCESS, "Error %d creating program for platform %i \n" , (int)rt, i);
|
||||
rt = clBuildProgram(program, ocl.runtime[i].num_devices,ocl.runtime[i].devices, NULL, NULL, NULL);
|
||||
if (rt == CL_BUILD_PROGRAM_FAILURE) {
|
||||
get_CompilErr(program,i);
|
||||
}
|
||||
AssertFatal(rt == CL_SUCCESS, "Error %d buildding program for platform %i \n" , rt, i);
|
||||
|
||||
for(int dev=0; dev<ocl.runtime[i].num_devices; dev++) {
|
||||
ocl.runtime[i].kernels[dev].cnp_kernel_1st = clCreateKernel(program, "ldpc_cnp_kernel_1st_iter", (cl_int *)&rt);
|
||||
AssertFatal(rt == CL_SUCCESS, "Error %d creating kernel %s platform %i, dev %i\n" , (int)rt,"ldpc_cnp_kernel_1st_iter", i,dev);
|
||||
ocl.runtime[i].kernels[dev].cnp_kernel = clCreateKernel(program, "ldpc_cnp_kernel", (cl_int *)&rt);
|
||||
AssertFatal(rt == CL_SUCCESS, "Error %d creating kernel %s platform %i, dev %i\n" , (int)rt,"ldpc_cnp_kernel", i,dev);
|
||||
ocl.runtime[i].kernels[dev].vnp_kernel_normal = clCreateKernel(program, "ldpc_vnp_kernel_normal", (cl_int *)&rt);
|
||||
AssertFatal(rt == CL_SUCCESS, "Error %d creating kernel %s platform %i, dev %i\n" , (int)rt,"ldpc_vnp_kernel_normal", i,dev);
|
||||
ocl.runtime[i].kernels[dev].pack_decoded_bit = clCreateKernel(program, "pack_decoded_bit", (cl_int *)&rt);
|
||||
AssertFatal(rt == CL_SUCCESS, "Error %d creating kernel %s platform %i, dev %i\n" , (int)rt,"pack_decoded_bit", i,dev);
|
||||
}
|
||||
context_ok++;
|
||||
}
|
||||
devok=0;
|
||||
}
|
||||
AssertFatal(context_ok>0, "No openCL device available to accelerate ldpc\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void nrLDPC_initcall(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out) {
|
||||
set_compact_BG(p_decParams->Z,p_decParams->BG);
|
||||
// init_LLR_DMA(p_decParams, p_llr, p_out);
|
||||
}
|
||||
|
||||
|
||||
int32_t nrLDPC_decod(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out,t_nrLDPC_procBuf* p_procBuf, t_nrLDPC_time_stats *time_decoder)
|
||||
{
|
||||
uint16_t Zc = p_decParams->Z;
|
||||
uint8_t BG = p_decParams->BG;
|
||||
// uint8_t numMaxIter = p_decParams->numMaxIter;
|
||||
int block_length = p_decParams->block_length;
|
||||
// e_nrLDPC_outMode outMode = p_decParams->outMode;
|
||||
uint8_t row,col;
|
||||
if(BG == 1){
|
||||
row = 46;
|
||||
col = 68;
|
||||
}
|
||||
else{
|
||||
row = 42;
|
||||
col = 52;
|
||||
}
|
||||
|
||||
// alloc memory
|
||||
// unsigned char *hard_decision = (unsigned char*)p_out;
|
||||
// gpu
|
||||
int memorySize_llr = col * Zc * sizeof(char) * MC;
|
||||
// cudaCheck( cudaMemcpyToSymbol(dev_const_llr, p_llr, memorySize_llr_cuda) );
|
||||
// cudaCheck( cudaMemcpyToSymbol(dev_llr, p_llr, memorySize_llr_cuda) );
|
||||
int rt = clEnqueueWriteBuffer(ocl.runtime[0].queue[0], ocl.runtime[0].dev_const_llr, CL_TRUE, 0,
|
||||
memorySize_llr, p_llr, 0, NULL, NULL);
|
||||
AssertFatal(rt == CL_SUCCESS, "Error %d moving p_llr data to read only memory in pltf %i dev %i\n" , (int)rt, 0,0);
|
||||
rt = clEnqueueWriteBuffer(ocl.runtime[0].queue[0], ocl.runtime[0].dev_llr, CL_TRUE, 0,
|
||||
memorySize_llr, p_llr, 0, NULL, NULL);
|
||||
AssertFatal(rt == CL_SUCCESS, "Error %d moving p_llr data to read-write memory in pltf %i dev %i\n" , (int)rt, 0,0);
|
||||
// Define CUDA kernel dimension
|
||||
// int blockSizeX = Zc;
|
||||
// dim3 dimGridKernel1(row, MC, 1); // dim of the thread blocks
|
||||
// dim3 dimBlockKernel1(blockSizeX, 1, 1);
|
||||
|
||||
// dim3 dimGridKernel2(col, MC, 1);
|
||||
// dim3 dimBlockKernel2(blockSizeX, 1, 1);
|
||||
// cudaDeviceSynchronize();
|
||||
|
||||
// lauch kernel
|
||||
size_t global_item_sizek0[2] = {row*Zc,MC}; // Process the entire lists
|
||||
size_t global_item_sizek1[2] = {col*Zc,MC}; // Process the entire lists
|
||||
size_t local_item_sizek[2] = {128,1}; // Divide work items into groups of 128
|
||||
|
||||
for(int ii = 0; ii < MAX_ITERATION; ii++){
|
||||
// first kernel
|
||||
if(ii == 0){
|
||||
// ldpc_cnp_kernel_1st_iter
|
||||
// <<<dimGridKernel1, dimBlockKernel1>>>
|
||||
// ( BG, row, col, Zc);
|
||||
CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel_1st, 0, sizeof(cl_mem), (void *)&(ocl.runtime[0].dev_llr));
|
||||
CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel_1st, 1, sizeof(cl_mem), (void *)&(ocl.runtime[0].dev_dt));
|
||||
CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel_1st, 2, sizeof(cl_mem), (void *)&(ocl.runtime[0].dev_h_compact1));
|
||||
CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel_1st, 3, sizeof(int), (void *)&(BG));
|
||||
CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel_1st, 4, sizeof(int), (void *)&(row));
|
||||
CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel_1st, 5, sizeof(int), (void *)&(col));
|
||||
CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel_1st, 6, sizeof(int), (void *)&(Zc));
|
||||
rt = clEnqueueNDRangeKernel(ocl.runtime[0].queue[0], ocl.runtime[0].kernels[0].cnp_kernel_1st, 2, NULL,
|
||||
global_item_sizek0, local_item_sizek, 0, NULL, NULL);
|
||||
AssertFatal(rt == CL_SUCCESS, "Error %d enqueing cnp_kernel_1st \n" , (int)rt);
|
||||
}else{
|
||||
// ldpc_cnp_kernel
|
||||
// <<<dimGridKernel1, dimBlockKernel1>>>
|
||||
// ( BG, row, col, Zc);
|
||||
CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel, 0, sizeof(cl_mem), (void *)&(ocl.runtime[0].dev_llr));
|
||||
CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel, 1, sizeof(cl_mem), (void *)&(ocl.runtime[0].dev_dt));
|
||||
CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel, 2, sizeof(cl_mem), (void *)&(ocl.runtime[0].dev_h_compact1));
|
||||
CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel, 3, sizeof(int), (void *)&(BG));
|
||||
CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel, 4, sizeof(int), (void *)&(row));
|
||||
CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel, 5, sizeof(int), (void *)&(col));
|
||||
CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel, 6, sizeof(int), (void *)&(Zc));
|
||||
rt = clEnqueueNDRangeKernel(ocl.runtime[0].queue[0], ocl.runtime[0].kernels[0].cnp_kernel, 2, NULL,
|
||||
global_item_sizek0, local_item_sizek, 0, NULL, NULL);
|
||||
AssertFatal(rt == CL_SUCCESS, "Error %d enqueing cnp_kernel\n" , (int)rt);
|
||||
}
|
||||
// second kernel
|
||||
// ldpc_vnp_kernel_normal
|
||||
// <<<dimGridKernel2, dimBlockKernel2>>>
|
||||
// // (dev_llr, dev_const_llr,BG, row, col, Zc);
|
||||
// (BG, row, col, Zc);
|
||||
CLSETKERNELARG(ocl.runtime[0].kernels[0].vnp_kernel_normal, 0, sizeof(cl_mem), (void *)&(ocl.runtime[0].dev_llr));
|
||||
CLSETKERNELARG(ocl.runtime[0].kernels[0].vnp_kernel_normal, 1, sizeof(cl_mem), (void *)&(ocl.runtime[0].dev_dt));
|
||||
CLSETKERNELARG(ocl.runtime[0].kernels[0].vnp_kernel_normal, 2, sizeof(cl_mem), (void *)&(ocl.runtime[0].dev_const_llr));
|
||||
CLSETKERNELARG(ocl.runtime[0].kernels[0].vnp_kernel_normal, 3, sizeof(cl_mem), (void *)&(ocl.runtime[0].dev_h_compact2));
|
||||
CLSETKERNELARG(ocl.runtime[0].kernels[0].vnp_kernel_normal, 4, sizeof(int), (void *)&(BG));
|
||||
CLSETKERNELARG(ocl.runtime[0].kernels[0].vnp_kernel_normal, 5, sizeof(int), (void *)&(row));
|
||||
CLSETKERNELARG(ocl.runtime[0].kernels[0].vnp_kernel_normal, 6, sizeof(int), (void *)&(col));
|
||||
CLSETKERNELARG(ocl.runtime[0].kernels[0].vnp_kernel_normal, 7, sizeof(int), (void *)&(Zc));
|
||||
rt = clEnqueueNDRangeKernel(ocl.runtime[0].queue[0], ocl.runtime[0].kernels[0].vnp_kernel_normal, 2, NULL,
|
||||
global_item_sizek1, local_item_sizek, 0, NULL, NULL);
|
||||
AssertFatal(rt == CL_SUCCESS, "Error %d enqueing vnp_kernel_normal \n" , (int)rt);
|
||||
}
|
||||
|
||||
// int pack = (block_length/128)+1;
|
||||
// dim3 pack_block(pack, MC, 1);
|
||||
// pack_decoded_bit<<<pack_block,128>>>( col, Zc);
|
||||
CLSETKERNELARG(ocl.runtime[0].kernels[0].pack_decoded_bit, 0, sizeof(cl_mem), (void *)&(ocl.runtime[0].dev_llr));
|
||||
CLSETKERNELARG(ocl.runtime[0].kernels[0].pack_decoded_bit, 1, sizeof(cl_mem), (void *)&(ocl.runtime[0].dev_tmp));
|
||||
CLSETKERNELARG(ocl.runtime[0].kernels[0].pack_decoded_bit, 2, sizeof(int), (void *)&(col));
|
||||
CLSETKERNELARG(ocl.runtime[0].kernels[0].pack_decoded_bit, 3, sizeof(int), (void *)&(Zc));
|
||||
|
||||
// Execute the OpenCL kernel on the list
|
||||
size_t global_item_size[2] = {block_length,MC}; // Process the entire lists
|
||||
size_t local_item_size[2] = {128,1}; // Divide work items into groups of 128
|
||||
rt = clEnqueueNDRangeKernel(ocl.runtime[0].queue[0], ocl.runtime[0].kernels[0].pack_decoded_bit, 2, NULL,
|
||||
global_item_size, local_item_size, 0, NULL, NULL);
|
||||
AssertFatal(rt == CL_SUCCESS, "Error %d enqueing pack_decoded_bit \n" , (int)rt);
|
||||
// cudaCheck( cudaMemcpyFromSymbol((void*)hard_decision, (const void*)dev_tmp, (block_length/8)*sizeof(unsigned char)) );
|
||||
// cudaDeviceSynchronize();
|
||||
|
||||
rt = clEnqueueReadBuffer(ocl.runtime[0].queue[0], ocl.runtime[0].dev_tmp, CL_TRUE, 0,
|
||||
(block_length/8)*sizeof(unsigned char) , p_llr, 0, NULL, NULL);
|
||||
AssertFatal(rt == CL_SUCCESS, "Error %d moving p_llr data to pltf %i dev %i\n" , (int)rt, 0,0);
|
||||
return MAX_ITERATION;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,302 @@
|
||||
/*
|
||||
* 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.0 (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/CODING/nrLDPC_decoder_kernels_CL.cl
|
||||
* \brief kernel functions for ldpc decoder accelerated via openCL
|
||||
* \author Francois TABURET
|
||||
* \date 2021
|
||||
* \version 1.0
|
||||
* \company Nokia BellLabs France
|
||||
* \email: francois.taburet@nokia-bell-labs.com
|
||||
* \note initial implem - translation of cuda version
|
||||
* \warning
|
||||
*/
|
||||
#define define MAX_ITERATION 2
|
||||
#define MC 1
|
||||
|
||||
#define INT32_MAX 2147483647
|
||||
|
||||
typedef struct{
|
||||
char x;
|
||||
char y;
|
||||
short value;
|
||||
} h_element;
|
||||
|
||||
//__global char dev_dt [46*68*384];
|
||||
//__local char *dev_t;
|
||||
//__global char dev_llr[68*384];
|
||||
//__global unsigned char dev_tmp[68*384];
|
||||
|
||||
|
||||
|
||||
|
||||
//__constant h_element dev_h_compact1[46*19] = {}; // used in kernel 1
|
||||
//__constant h_element dev_h_compact2[68*30] = {}; // used in kernel 2
|
||||
|
||||
// __device__ __constantant__ h_element dev_h_compact1[46*19]; // used in kernel 1
|
||||
// __device__ __constantant__ h_element dev_h_compact2[68*30]; // used in kernel 2
|
||||
|
||||
// row and col element count
|
||||
__constant char h_ele_row_bg1_count[46] = {
|
||||
19, 19, 19, 19, 3, 8, 9, 7, 10, 9,
|
||||
7, 8, 7, 6, 7, 7, 6, 6, 6, 6,
|
||||
6, 6, 5, 5, 6, 5, 5, 4, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 4, 5, 5,
|
||||
4, 5, 4, 5, 5, 4};
|
||||
__constant char h_ele_col_bg1_count[68] = {
|
||||
30, 28, 7, 11, 9, 4, 8, 12, 8, 7,
|
||||
12, 10, 12, 11, 10, 7, 10, 10, 13, 7,
|
||||
8, 11, 12, 5, 6, 6, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1};
|
||||
__constant char h_ele_row_bg2_count[42] = {
|
||||
8, 10, 8, 10, 4, 6, 6, 6, 4, 5,
|
||||
5, 5, 4, 5, 5, 4, 5, 5, 4, 4,
|
||||
4, 4, 3, 4, 4, 3, 5, 3, 4, 3,
|
||||
5, 3, 4, 4, 4, 4, 4, 3, 4, 4,
|
||||
4, 4};
|
||||
__constant char h_ele_col_bg2_count[52] = {
|
||||
22, 23, 10, 5, 5, 14, 7, 13, 6, 8,
|
||||
9, 16, 9, 12, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1};
|
||||
|
||||
|
||||
|
||||
// Kernel 1
|
||||
__kernel void ldpc_cnp_kernel_1st_iter( __global char * dev_llr, __global char * dev_dt, __local h_element *dev_h_compact1, int BG, int row, int col, int Zc)
|
||||
{
|
||||
// int iMCW = blockIdx.y; // codeword id
|
||||
// int iBlkRow = blockIdx.x; // block row in h_base
|
||||
// int iSubRow = threadIdx.x; // row index in sub_block of h_base
|
||||
// if(blockIdx.x == 0 && threadIdx.x == 1) printf("cnp %d\n", threadIdx.x);
|
||||
int iMCW = get_group_id(1); // codeword id
|
||||
int iBlkRow = get_group_id(0); // block row in h_base
|
||||
int iBlkCol; // block col in h_base
|
||||
int iSubRow = get_local_id(0);; // row index in sub_block of h_base
|
||||
int iCol; // overall col index in h_base
|
||||
int offsetR;
|
||||
int shift_t;
|
||||
|
||||
// For 2-min algorithm.
|
||||
int Q_sign = 0;
|
||||
int sq;
|
||||
int Q, Q_abs;
|
||||
int R_temp;
|
||||
|
||||
int sign = 1;
|
||||
int rmin1 = INT32_MAX;
|
||||
int rmin2 = INT32_MAX;
|
||||
char idx_min = 0;
|
||||
|
||||
h_element h_element_t;
|
||||
int s = (BG==1)? h_ele_row_bg1_count[iBlkRow]:h_ele_row_bg2_count[iBlkRow];
|
||||
offsetR = (iMCW * row*col*Zc) + iBlkRow * Zc + iSubRow; // row*col*Zc = size of dev_dt
|
||||
// if(blockIdx.x == 0 && threadIdx.x == 1) printf("s: %d, offset %d\n", s, offsetR);
|
||||
// The 1st recursion
|
||||
for(int i = 0; i < s; i++) // loop through all the ZxZ sub-blocks in a row
|
||||
{
|
||||
h_element_t = dev_h_compact1[i*row+iBlkRow]; // compact_col == row
|
||||
|
||||
iBlkCol = h_element_t.y;
|
||||
shift_t = h_element_t.value;
|
||||
|
||||
shift_t = (iSubRow + shift_t) % Zc;
|
||||
iCol = (iMCW * col*Zc) + iBlkCol * Zc + shift_t; // col*Zc = size of llr
|
||||
Q = dev_llr[iCol];
|
||||
Q_abs = (Q>0)? Q : -Q;
|
||||
sq = Q < 0;
|
||||
// if(blockIdx.x == 0 && threadIdx.x == 1) printf("i %d, icol %d, Q: %d\n", i, iCol, Q);
|
||||
// quick version
|
||||
sign = sign * (1 - sq * 2);
|
||||
Q_sign |= sq << i;
|
||||
|
||||
if (Q_abs < rmin1){
|
||||
rmin2 = rmin1;
|
||||
rmin1 = Q_abs;
|
||||
idx_min = i;
|
||||
} else if (Q_abs < rmin2){
|
||||
rmin2 = Q_abs;
|
||||
}
|
||||
}
|
||||
|
||||
// if(blockIdx.x == 0 && threadIdx.x == 1)printf("min1 %d, min2 %d, min1_idx %d\n", rmin1, rmin2, idx_min);
|
||||
|
||||
// The 2nd recursion
|
||||
for(int i = 0; i < s; i++){
|
||||
// v0: Best performance so far. 0.75f is the value of alpha.
|
||||
sq = 1 - 2 * ((Q_sign >> i) & 0x01);
|
||||
R_temp = 0.75f * sign * sq * (i != idx_min ? rmin1 : rmin2);
|
||||
// write results to global memory
|
||||
h_element_t = dev_h_compact1[i*row+iBlkRow];
|
||||
int addr_temp = offsetR + h_element_t.y * row * Zc;
|
||||
dev_dt[addr_temp] = R_temp;
|
||||
// if(blockIdx.x == 0 && threadIdx.x == 1)printf("R_temp %d, temp_addr %d\n", R_temp, addr_temp);
|
||||
}
|
||||
}
|
||||
|
||||
// Kernel_1
|
||||
__kernel void ldpc_cnp_kernel( __global char * dev_llr, __global char * dev_dt, __local h_element *dev_h_compact1, int BG, int row, int col, int Zc)
|
||||
{
|
||||
// if(blockIdx.x == 0 && threadIdx.x == 1) printf("cnp\n");
|
||||
// int iMCW = blockIdx.y;
|
||||
// int iBlkRow = blockIdx.x; // block row in h_base // block col in h_base
|
||||
// int iSubRow = threadIdx.x; // row index in sub_block of h_base
|
||||
int iMCW = get_group_id(1);
|
||||
int iBlkRow = get_group_id(0); // block row in h_base
|
||||
int iBlkCol; // block col in h_base
|
||||
int iSubRow = get_local_id(0);; // row index in sub_block of h_base
|
||||
int iCol; // overall col index in h_base
|
||||
int offsetR;
|
||||
int shift_t;
|
||||
|
||||
// For 2-min algorithm.
|
||||
int Q_sign = 0;
|
||||
int sq;
|
||||
int Q, Q_abs;
|
||||
int R_temp;
|
||||
|
||||
int sign = 1;
|
||||
int rmin1 = INT32_MAX;
|
||||
int rmin2 = INT32_MAX;
|
||||
char idx_min = 0;
|
||||
|
||||
h_element h_element_t;
|
||||
int s = (BG==1)? h_ele_row_bg1_count[iBlkRow]: h_ele_row_bg2_count[iBlkRow];
|
||||
offsetR = (iMCW *row*col*Zc) + iBlkRow * Zc + iSubRow; // row * col * Zc = size of dev_dt
|
||||
// if(blockIdx.x == 0 && threadIdx.x == 1) printf("s: %d, offset %d\n", s, offsetR);
|
||||
// The 1st recursion
|
||||
for(int i = 0; i < s; i++) // loop through all the ZxZ sub-blocks in a row
|
||||
{
|
||||
h_element_t = dev_h_compact1[i*row+iBlkRow];
|
||||
|
||||
iBlkCol = h_element_t.y;
|
||||
shift_t = h_element_t.value;
|
||||
shift_t = (iSubRow + shift_t) % Zc;
|
||||
iCol = iBlkCol * Zc + shift_t;
|
||||
|
||||
R_temp = dev_dt[offsetR + iBlkCol * row * Zc];
|
||||
|
||||
Q = dev_llr[iMCW * (col*Zc) + iCol] - R_temp;
|
||||
Q_abs = (Q>0)? Q : -Q;
|
||||
// if(blockIdx.x == 0 && threadIdx.x == 1) printf("i %d, icol %d, Q: %d\n", i, iCol, Q);
|
||||
sq = Q < 0;
|
||||
sign = sign * (1 - sq * 2);
|
||||
Q_sign |= sq << i;
|
||||
|
||||
if (Q_abs < rmin1){
|
||||
rmin2 = rmin1;
|
||||
rmin1 = Q_abs;
|
||||
idx_min = i;
|
||||
} else if (Q_abs < rmin2){
|
||||
rmin2 = Q_abs;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// if(blockIdx.x == 0 && threadIdx.x == 1)printf("min1 %d, min2 %d, min1_idx %d\n", rmin1, rmin2, idx_min);
|
||||
|
||||
// The 2nd recursion
|
||||
for(int i = 0; i < s; i ++){
|
||||
sq = 1 - 2 * ((Q_sign >> i) & 0x01);
|
||||
R_temp = 0.75f * sign * sq * (i != idx_min ? rmin1 : rmin2);
|
||||
|
||||
|
||||
// write results to global memory
|
||||
h_element_t = dev_h_compact1[i*row+iBlkRow];
|
||||
int addr_temp = h_element_t.y * row * Zc + offsetR;
|
||||
dev_dt[addr_temp] = R_temp;
|
||||
// if(blockIdx.x == 0 && threadIdx.x == 1)printf("R_temp %d, temp_addr %d\n", R_temp, addr_temp);
|
||||
}
|
||||
}
|
||||
|
||||
// Kernel 2: VNP processing
|
||||
__kernel void
|
||||
ldpc_vnp_kernel_normal(__global char * dev_llr, __global char * dev_dt, __global char * dev_const_llr, __local h_element *dev_h_compact2, int BG, int row, int col, int Zc)
|
||||
{
|
||||
// int iMCW = blockIdx.y;
|
||||
// int iBlkCol = blockIdx.x;
|
||||
// int iSubCol = threadIdx.x;
|
||||
int iMCW = get_group_id(1);
|
||||
int iBlkCol = get_group_id(0);
|
||||
int iBlkRow;
|
||||
int iSubCol = get_local_id(0);
|
||||
int iRow;
|
||||
int iCol;
|
||||
|
||||
int shift_t, sf;
|
||||
int APP;
|
||||
|
||||
h_element h_element_t;
|
||||
|
||||
// update all the llr values
|
||||
iCol = iBlkCol * Zc + iSubCol;
|
||||
APP = dev_const_llr[iMCW *col*Zc + iCol];
|
||||
int offsetDt = iMCW *row*col*Zc + iBlkCol * row * Zc;
|
||||
int s = (BG==1)? h_ele_col_bg1_count[iBlkCol]:h_ele_col_bg2_count[iBlkCol];
|
||||
|
||||
for(int i = 0; i < s; i++)
|
||||
{
|
||||
h_element_t = dev_h_compact2[i*col+iBlkCol];
|
||||
|
||||
shift_t = h_element_t.value%Zc;
|
||||
iBlkRow = h_element_t.x;
|
||||
|
||||
sf = iSubCol - shift_t;
|
||||
sf = (sf + Zc) % Zc;
|
||||
|
||||
iRow = iBlkRow * Zc + sf;
|
||||
APP = APP + dev_dt[offsetDt + iRow];
|
||||
}
|
||||
if(APP > SCHAR_MAX) APP = SCHAR_MAX;
|
||||
if(APP < SCHAR_MIN) APP = SCHAR_MIN;
|
||||
// write back to device global memory
|
||||
dev_llr[iMCW *col*Zc + iCol] = APP;
|
||||
}
|
||||
|
||||
|
||||
__kernel void pack_decoded_bit(__global unsigned char * dev_llr, __global unsigned char * dev_tmp, int col, int Zc)
|
||||
{
|
||||
// int iMCW = blockIdx.y;
|
||||
// int btid = threadIdx.x;
|
||||
unsigned char tmp[128];
|
||||
int iMCW = get_group_id(1);
|
||||
int btid = get_local_id(0);
|
||||
int tid = iMCW * col*Zc + get_group_id(0)*128 + btid;
|
||||
tmp[btid] = 0;
|
||||
|
||||
if(dev_llr[tid] < 0){
|
||||
tmp[btid] = 1 << (7-(btid&7));
|
||||
}
|
||||
// __syncthreads();
|
||||
|
||||
if(btid < 16){
|
||||
dev_tmp[iMCW * col*Zc + get_group_id(0)*16+btid] = 0;
|
||||
for(int i = 0; i < 8; i++){
|
||||
dev_tmp[iMCW * col*Zc + get_group_id(0)*16+btid] += tmp[btid*8+i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ typedef struct nrLDPC_dec_params {
|
||||
uint16_t Z; /**< Lifting size */
|
||||
uint8_t R; /**< Decoding rate: Format 15,13,... for code rates 1/5, 1/3,... */
|
||||
uint8_t numMaxIter; /**< Maximum number of iterations */
|
||||
int block_length;
|
||||
e_nrLDPC_outMode outMode; /**< Output format */
|
||||
} t_nrLDPC_dec_params;
|
||||
|
||||
|
||||
@@ -7,14 +7,14 @@
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <cuda_runtime.h>
|
||||
#include <cuda.h>
|
||||
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
|
||||
#include "PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h"
|
||||
|
||||
#include "assertions.h"
|
||||
#include "bgs/BG1_I0"
|
||||
#include "bgs/BG1_I1"
|
||||
#include "bgs/BG1_I2"
|
||||
@@ -462,10 +462,11 @@ void read_BG(int BG, int *h, int row, int col)
|
||||
}
|
||||
|
||||
extern "C"
|
||||
void init_LLR_DMA_for_CUDA(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, int block_length){
|
||||
void init_LLR_DMA(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out){
|
||||
|
||||
uint16_t Zc = p_decParams->Z;
|
||||
uint8_t BG = p_decParams->BG;
|
||||
int block_length = p_decParams->block_length;
|
||||
uint8_t row,col;
|
||||
if(BG == 1){
|
||||
row = 46;
|
||||
@@ -483,14 +484,60 @@ void init_LLR_DMA_for_CUDA(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8
|
||||
|
||||
}
|
||||
|
||||
using namespace std ;
|
||||
|
||||
/* from here: entry points in decoder shared lib */
|
||||
extern "C"
|
||||
int32_t nrLDPC_decoder_LYC(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, int block_length, time_stats_t *time_decoder)
|
||||
int ldpc_autoinit(void) { // called by the library loader
|
||||
/*int devices = 0;
|
||||
|
||||
cudaError_t err = cudaGetDeviceCount(&devices);
|
||||
AssertFatal(devices>0,"\nNo cuda GPU found\n\n");
|
||||
|
||||
const int kb = 1024;
|
||||
const int mb = kb * kb;
|
||||
wcout << "NBody.GPU" << endl << "=========" << endl << endl;
|
||||
|
||||
wcout << "CUDA version: v" << CUDART_VERSION << endl;
|
||||
|
||||
|
||||
wcout << "CUDA Devices: " << endl << endl;
|
||||
|
||||
for(int i = 0; i < devices; ++i)
|
||||
{
|
||||
cudaDeviceProp props;
|
||||
cudaGetDeviceProperties(&props, i);
|
||||
wcout << i << ": " << props.name << ": " << props.major << "." << props.minor << endl;
|
||||
wcout << " Global memory: " << props.totalGlobalMem / mb << "mb" << endl;
|
||||
wcout << " Shared memory: " << props.sharedMemPerBlock / kb << "kb" << endl;
|
||||
wcout << " Constant memory: " << props.totalConstMem / kb << "kb" << endl;
|
||||
wcout << " Block registers: " << props.regsPerBlock << endl << endl;
|
||||
|
||||
wcout << " Warp size: " << props.warpSize << endl;
|
||||
wcout << " Threads per block: " << props.maxThreadsPerBlock << endl;
|
||||
wcout << " Max block dimensions: [ " << props.maxThreadsDim[0] << ", " << props.maxThreadsDim[1] << ", " << props.maxThreadsDim[2] << " ]" << endl;
|
||||
wcout << " Max grid dimensions: [ " << props.maxGridSize[0] << ", " << props.maxGridSize[1] << ", " << props.maxGridSize[2] << " ]" << endl;
|
||||
wcout << endl;
|
||||
}
|
||||
*/
|
||||
warmup_for_GPU();
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
void nrLDPC_initcall(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out) {
|
||||
set_compact_BG(p_decParams->Z,p_decParams->BG);
|
||||
init_LLR_DMA(p_decParams, p_llr, p_out);
|
||||
}
|
||||
|
||||
|
||||
extern "C"
|
||||
int32_t nrLDPC_decod(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out,t_nrLDPC_procBuf* p_procBuf, t_nrLDPC_time_stats *time_decoder)
|
||||
{
|
||||
|
||||
|
||||
uint16_t Zc = p_decParams->Z;
|
||||
uint8_t BG = p_decParams->BG;
|
||||
uint8_t numMaxIter = p_decParams->numMaxIter;
|
||||
int block_length = p_decParams->block_length;
|
||||
e_nrLDPC_outMode outMode = p_decParams->outMode;
|
||||
cudaError_t cudaStatus;
|
||||
uint8_t row,col;
|
||||
|
||||
@@ -45,6 +45,7 @@ typedef struct {
|
||||
time_stats_t *toutput;
|
||||
}encoder_implemparams_t;
|
||||
#define INIT0_LDPCIMPLEMPARAMS {0,0,0,NULL,NULL,NULL,NULL}
|
||||
typedef void(*nrLDPC_initcallfunc_t)(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out);
|
||||
typedef int(*nrLDPC_encoderfunc_t)(unsigned char **,unsigned char **,int,int,short, short, encoder_implemparams_t*);
|
||||
//============================================================================================================================
|
||||
// decoder interface
|
||||
@@ -56,4 +57,4 @@ typedef int(*nrLDPC_encoderfunc_t)(unsigned char **,unsigned char **,int,int,sho
|
||||
\param p_profiler LDPC profiler statistics
|
||||
*/
|
||||
typedef int32_t(*nrLDPC_decoderfunc_t)(t_nrLDPC_dec_params* , int8_t*, int8_t* , t_nrLDPC_procBuf* , t_nrLDPC_time_stats* );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -23,13 +23,16 @@
|
||||
#ifdef LDPC_LOADER
|
||||
nrLDPC_decoderfunc_t nrLDPC_decoder;
|
||||
nrLDPC_encoderfunc_t nrLDPC_encoder;
|
||||
nrLDPC_initcallfunc_t nrLDPC_initcall;
|
||||
#else
|
||||
/* functions to load the LDPC shared lib, implemented in openair1/PHY/CODING/nrLDPC_load.c */
|
||||
extern int load_nrLDPClib(void) ;
|
||||
extern int load_nrLDPClib(char *version) ;
|
||||
extern int load_nrLDPClib_ref(char *libversion, nrLDPC_encoderfunc_t * nrLDPC_encoder_ptr); // for ldpctest
|
||||
/* ldpc coder/decoder functions, as loaded by load_nrLDPClib(). */
|
||||
extern nrLDPC_initcallfunc_t nrLDPC_initcall;
|
||||
|
||||
extern nrLDPC_decoderfunc_t nrLDPC_decoder;
|
||||
extern nrLDPC_encoderfunc_t nrLDPC_encoder;
|
||||
// inline functions:
|
||||
#include "openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -42,22 +42,32 @@
|
||||
|
||||
|
||||
/* function description array, to be used when loading the encoding/decoding shared lib */
|
||||
static loader_shlibfunc_t shlib_fdesc[2];
|
||||
static loader_shlibfunc_t shlib_fdesc[3];
|
||||
|
||||
char *arg[64]={"ldpctest","-O","cmdlineonly::dbgl0"};
|
||||
/* arguments used when called from phy simulators exec's which do not use the config module */
|
||||
/* arg is used to initialize the config module so that the loader works as expected */
|
||||
char *arg[64]={"ldpctest","-O","cmdlineonly::dbgl0",NULL,NULL};
|
||||
|
||||
int load_nrLDPClib(void) {
|
||||
int load_nrLDPClib(char *version) {
|
||||
char *ptr = (char*)config_get_if();
|
||||
char libname[64]="ldpc";
|
||||
|
||||
if ( ptr==NULL ) {// phy simulators, config module possibly not loaded
|
||||
load_configmodule(3,(char **)arg,CONFIG_ENABLECMDLINEONLY) ;
|
||||
load_configmodule(0,(char **)NULL,CONFIG_ENABLECMDLINEONLY) ;
|
||||
logInit();
|
||||
}
|
||||
shlib_fdesc[0].fname = "nrLDPC_decod";
|
||||
shlib_fdesc[1].fname = "nrLDPC_encod";
|
||||
int ret=load_module_shlib("ldpc",shlib_fdesc,sizeof(shlib_fdesc)/sizeof(loader_shlibfunc_t),NULL);
|
||||
shlib_fdesc[2].fname = "nrLDPC_initcall";
|
||||
int ret;
|
||||
if (version)
|
||||
ret=load_module_version_shlib(libname,version,shlib_fdesc,sizeof(shlib_fdesc)/sizeof(loader_shlibfunc_t),NULL);
|
||||
else
|
||||
ret=load_module_shlib(libname,shlib_fdesc,sizeof(shlib_fdesc)/sizeof(loader_shlibfunc_t),NULL);
|
||||
AssertFatal( (ret >= 0),"Error loading ldpc decoder");
|
||||
nrLDPC_decoder = (nrLDPC_decoderfunc_t)shlib_fdesc[0].fptr;
|
||||
nrLDPC_encoder = (nrLDPC_encoderfunc_t)shlib_fdesc[1].fptr;
|
||||
nrLDPC_initcall = (nrLDPC_initcallfunc_t)shlib_fdesc[2].fptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -65,10 +75,8 @@ int load_nrLDPClib_ref(char *libversion, nrLDPC_encoderfunc_t * nrLDPC_encoder_p
|
||||
loader_shlibfunc_t shlib_encoder_fdesc;
|
||||
|
||||
shlib_encoder_fdesc.fname = "nrLDPC_encod";
|
||||
char libpath[64];
|
||||
sprintf(libpath,"ldpc%s",libversion);
|
||||
int ret=load_module_shlib(libpath,&shlib_encoder_fdesc,1,NULL);
|
||||
AssertFatal( (ret >= 0),"Error loading ldpc encoder %s\n",libpath);
|
||||
int ret=load_module_version_shlib("ldpc",libversion,&shlib_encoder_fdesc,1,NULL);
|
||||
AssertFatal( (ret >= 0),"Error loading ldpc encoder %s\n",(libversion==NULL)?"":libversion);
|
||||
*nrLDPC_encoder_ptr = (nrLDPC_encoderfunc_t)shlib_encoder_fdesc.fptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
|
||||
crcTableInit();
|
||||
init_scrambling_luts();
|
||||
init_pucch2_luts();
|
||||
load_nrLDPClib();
|
||||
load_nrLDPClib(NULL);
|
||||
// PBCH DMRS gold sequences generation
|
||||
nr_init_pbch_dmrs(gNB);
|
||||
//PDCCH DMRS init
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "nr_dlsch.h"
|
||||
#include "nr_sch_dmrs.h"
|
||||
#include "PHY/MODULATION/nr_modulation.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
|
||||
//#define DEBUG_PDCCH_DMRS
|
||||
//#define DEBUG_DCI
|
||||
|
||||
@@ -59,6 +59,4 @@ void nr_fill_ul_dci(PHY_VARS_gNB *gNB,
|
||||
|
||||
void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m,nfapi_nr_dl_tti_pdcch_pdu_rel15_t *);
|
||||
|
||||
void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset);
|
||||
|
||||
#endif //__PHY_NR_TRANSPORT_DCI__H
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
*/
|
||||
|
||||
#include "nr_dci.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
|
||||
//#define DEBUG_FILL_DCI
|
||||
|
||||
|
||||
@@ -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_dci_tools_common.c
|
||||
* \brief
|
||||
* \author
|
||||
* \date 2018
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email:
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#include "nr_dci.h"
|
||||
|
||||
//#define DEBUG_FILL_DCI
|
||||
|
||||
#include "nr_dlsch.h"
|
||||
|
||||
|
||||
void get_coreset_rballoc(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)|
|
||||
(((uint64_t)FreqDomainResource[1])<<29)|
|
||||
(((uint64_t)FreqDomainResource[2])<<21)|
|
||||
(((uint64_t)FreqDomainResource[3])<<13)|
|
||||
(((uint64_t)FreqDomainResource[4])<<5)|
|
||||
(((uint64_t)FreqDomainResource[5])>>3);
|
||||
|
||||
for (int i=0; i<45; i++)
|
||||
if ((bitmap>>(44-i))&1) {
|
||||
count++;
|
||||
if (!start_set) {
|
||||
start = i;
|
||||
start_set = 1;
|
||||
}
|
||||
}
|
||||
*rb_offset = 6*start;
|
||||
*n_rb = 6*count;
|
||||
}
|
||||
|
||||
@@ -238,7 +238,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
|
||||
// x_n contains the sequence r_u_v_alpha_delta(n)
|
||||
|
||||
int n,i,l;
|
||||
int n,i;
|
||||
int prb_offset[2] = {pucch_pdu->bwp_start+pucch_pdu->prb_start, pucch_pdu->bwp_start+pucch_pdu->prb_start};
|
||||
|
||||
nr_group_sequence_hopping(pucch_GroupHopping,pucch_pdu->hopping_id,0,slot,&u[0],&v[0]); // calculating u and v value first hop
|
||||
@@ -266,14 +266,14 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
int64_t xrtmag=0,xrtmag_next=0;
|
||||
uint8_t maxpos=0;
|
||||
uint8_t index=0;
|
||||
for (l=0; l<pucch_pdu->nr_of_symbols; l++) {
|
||||
for (int l=0; l<pucch_pdu->nr_of_symbols; l++) {
|
||||
for (int aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++) {
|
||||
memset((void*)xr[aarx][l],0,24*sizeof(int16_t));
|
||||
}
|
||||
}
|
||||
int n2;
|
||||
|
||||
for (l=0; l<pucch_pdu->nr_of_symbols; l++) {
|
||||
for (int l=0; l<pucch_pdu->nr_of_symbols; l++) {
|
||||
l2 = l+pucch_pdu->start_symbol_index;
|
||||
re_offset[l] = (12*prb_offset[l]) + frame_parms->first_carrier_offset;
|
||||
if (re_offset[l]>= frame_parms->ofdm_symbol_size)
|
||||
@@ -300,11 +300,10 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
//int32_t no_corr = 0;
|
||||
int seq_index;
|
||||
int64_t temp;
|
||||
int64_t av_corr=0;
|
||||
|
||||
for(i=0;i<nr_sequences;i++){
|
||||
|
||||
for (l=0;l<pucch_pdu->nr_of_symbols;l++) {
|
||||
for (int l=0;l<pucch_pdu->nr_of_symbols;l++) {
|
||||
seq_index = (pucch_pdu->initial_cyclic_shift+
|
||||
mcs[i]+
|
||||
gNB->pucch0_lut.lut[cs_ind][slot][l+pucch_pdu->start_symbol_index])%12;
|
||||
@@ -322,26 +321,30 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
}
|
||||
}
|
||||
LOG_D(PHY,"PUCCH IDFT[%d/%d] = (%d,%d)=>%f\n",mcs[i],seq_index,corr_re[0][0],corr_im[0][0],10*log10((double)corr_re[0][0]*corr_re[0][0] + (double)corr_im[0][0]*corr_im[0][0]));
|
||||
if (l>1) LOG_D(PHY,"PUCCH 2nd symbol IDFT[%d/%d] = (%d,%d)=>%f\n",mcs[i],seq_index,corr_re[0][1],corr_im[0][1],10*log10((double)corr_re[0][1]*corr_re[0][1] + (double)corr_im[0][1]*corr_im[0][1]));
|
||||
if (pucch_pdu->freq_hop_flag == 0 && l==1) {// non-coherent correlation
|
||||
temp=0;
|
||||
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++)
|
||||
temp+=(int64_t)corr_re[aa][0]*corr_re[aa][0] + (int64_t)corr_im[aa][0]*corr_im[aa][0];
|
||||
}
|
||||
|
||||
else if (pucch_pdu->freq_hop_flag == 0 && l==2) {
|
||||
int64_t corr_re2=0;
|
||||
int64_t corr_im2=0;
|
||||
temp=0;
|
||||
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++) {
|
||||
corr_re2 = (int64_t)corr_re[aa][0]+corr_re[aa][1];
|
||||
corr_im2 = (int64_t)corr_im[aa][0]+corr_im[aa][1];
|
||||
// coherent combining of 2 symbols and then complex modulus for single-frequency case
|
||||
temp+=corr_re2*corr_re2 + corr_im2*corr_im2;
|
||||
}
|
||||
}
|
||||
else if (pucch_pdu->freq_hop_flag == 1) {
|
||||
LOG_D(PHY,"PUCCH IDFT[%d/%d] = (%d,%d)=>%f\n",
|
||||
mcs[i],seq_index,corr_re[0][0],corr_im[0][0],
|
||||
10*log10((double)corr_re[0][0]*corr_re[0][0] + (double)corr_im[0][0]*corr_im[0][0]));
|
||||
if (pucch_pdu->nr_of_symbols==2)
|
||||
LOG_D(PHY,"PUCCH 2nd symbol IDFT[%d/%d] = (%d,%d)=>%f\n",
|
||||
mcs[i],seq_index,corr_re[0][1],corr_im[0][1],
|
||||
10*log10((double)corr_re[0][1]*corr_re[0][1] + (double)corr_im[0][1]*corr_im[0][1]));
|
||||
if (pucch_pdu->freq_hop_flag == 0) {
|
||||
if (pucch_pdu->nr_of_symbols==1) {// non-coherent correlation
|
||||
temp=0;
|
||||
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++)
|
||||
temp+=(int64_t)corr_re[aa][0]*corr_re[aa][0] + (int64_t)corr_im[aa][0]*corr_im[aa][0];
|
||||
} else {
|
||||
int64_t corr_re2=0;
|
||||
int64_t corr_im2=0;
|
||||
temp=0;
|
||||
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++) {
|
||||
corr_re2 = (int64_t)corr_re[aa][0]+corr_re[aa][1];
|
||||
corr_im2 = (int64_t)corr_im[aa][0]+corr_im[aa][1];
|
||||
// coherent combining of 2 symbols and then complex modulus for single-frequency case
|
||||
temp+=corr_re2*corr_re2 + corr_im2*corr_im2;
|
||||
}
|
||||
}
|
||||
} else if (pucch_pdu->freq_hop_flag == 1) {
|
||||
// full non-coherent combining of 2 symbols for frequency-hopping case
|
||||
temp=0;
|
||||
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++)
|
||||
@@ -349,7 +352,6 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
else AssertFatal(1==0,"shouldn't happen\n");
|
||||
|
||||
av_corr+=temp;
|
||||
if (temp>xrtmag) {
|
||||
xrtmag_next = xrtmag;
|
||||
xrtmag=temp;
|
||||
@@ -359,19 +361,19 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
int64_t temp2=0,temp3=0;;
|
||||
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++) {
|
||||
temp2 += ((int64_t)corr_re[aa][0]*corr_re[aa][0] + (int64_t)corr_im[aa][0]*corr_im[aa][0]);
|
||||
if (l==2) temp3 += ((int64_t)corr_re[aa][1]*corr_re[aa][1] + (int64_t)corr_im[aa][1]*corr_im[aa][1]);
|
||||
if (pucch_pdu->nr_of_symbols==2)
|
||||
temp3 += ((int64_t)corr_re[aa][1]*corr_re[aa][1] + (int64_t)corr_im[aa][1]*corr_im[aa][1]);
|
||||
}
|
||||
uci_stats->current_pucch0_stat0= dB_fixed64(temp2);
|
||||
if (l==2) uci_stats->current_pucch0_stat1= dB_fixed64(temp3);
|
||||
if ( pucch_pdu->nr_of_symbols==2)
|
||||
uci_stats->current_pucch0_stat1= dB_fixed64(temp3);
|
||||
}
|
||||
else if (temp>xrtmag_next)
|
||||
xrtmag_next = temp;
|
||||
}
|
||||
|
||||
av_corr/=nr_sequences/l;
|
||||
|
||||
int xrtmag_dBtimes10 = 10*(int)dB_fixed64(xrtmag/(12*l));
|
||||
int xrtmag_next_dBtimes10 = 10*(int)dB_fixed64(xrtmag_next/(12*l));
|
||||
int xrtmag_dBtimes10 = 10*(int)dB_fixed64(xrtmag/(12*pucch_pdu->nr_of_symbols));
|
||||
int xrtmag_next_dBtimes10 = 10*(int)dB_fixed64(xrtmag_next/(12*pucch_pdu->nr_of_symbols));
|
||||
#ifdef DEBUG_NR_PUCCH_RX
|
||||
printf("PUCCH 0 : maxpos %d\n",maxpos);
|
||||
#endif
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
#include "PHY/phy_extern_nr_ue.h"
|
||||
#include "PHY/CODING/coding_extern.h"
|
||||
#include "PHY/sse_intrin.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_dci.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
|
||||
#include "assertions.h"
|
||||
#include "T.h"
|
||||
|
||||
@@ -497,6 +497,8 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
}
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_IN);
|
||||
p_decParams->block_length=length_dec;
|
||||
nrLDPC_initcall(p_decParams, (int8_t*)&pl[0], llrProcBuf);
|
||||
no_iteration_ldpc = nrLDPC_decoder(p_decParams,
|
||||
(int8_t *)&pl[0],
|
||||
llrProcBuf,
|
||||
@@ -956,7 +958,8 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
for (i=0, j=0; j < ((kc*harq_process->Z)>>4)+1; i+=2, j++) {
|
||||
pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
|
||||
}
|
||||
|
||||
p_decParams->block_length=length_dec;
|
||||
nrLDPC_initcall(p_decParams, (int8_t*)&pl[0], llrProcBuf);
|
||||
no_iteration_ldpc = nrLDPC_decoder(p_decParams,
|
||||
(int8_t *)&pl[0],
|
||||
llrProcBuf,
|
||||
@@ -1340,7 +1343,8 @@ void nr_dlsch_decoding_process(void *arg) {
|
||||
for (i=0, j=0; j < ((kc*harq_process->Z)>>4)+1; i+=2, j++) {
|
||||
pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
|
||||
}
|
||||
|
||||
p_decParams->block_length=length_dec;
|
||||
nrLDPC_initcall(p_decParams, (int8_t*)&pl[0], llrProcBuf);
|
||||
no_iteration_ldpc = nrLDPC_decoder(p_decParams,
|
||||
(int8_t *)&pl[0],
|
||||
llrProcBuf,
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
|
||||
#include "SCHED_NR_UE/defs.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
|
||||
#include "common_lib.h"
|
||||
#include <math.h>
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
#define CONFIG_STRING_MACRLC_REMOTE_S_PORTC "remote_s_portc"
|
||||
#define CONFIG_STRING_MACRLC_LOCAL_S_PORTD "local_s_portd"
|
||||
#define CONFIG_STRING_MACRLC_REMOTE_S_PORTD "remote_s_portd"
|
||||
#define CONFIG_STRING_MACRLC_ULSCH_MAX_SLOTS_INACTIVITY "ulsch_max_slots_inactivity"
|
||||
#define CONFIG_STRING_MACRLC_ULSCH_MAX_FRAME_INACTIVITY "ulsch_max_frame_inactivity"
|
||||
#define CONFIG_STRING_MACRLC_PUSCHTARGETSNRX10 "pusch_TargetSNRx10"
|
||||
#define CONFIG_STRING_MACRLC_PUCCHTARGETSNRX10 "pucch_TargetSNRx10"
|
||||
#define CONFIG_STRING_MACRLC_PUCCHFAILURETHRES "pucch_FailureThres"
|
||||
@@ -83,7 +83,7 @@
|
||||
{CONFIG_STRING_MACRLC_REMOTE_S_PORTC, NULL, 0, uptr:NULL, defintval:50020, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_MACRLC_LOCAL_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_MACRLC_REMOTE_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_MACRLC_ULSCH_MAX_SLOTS_INACTIVITY, "Maximum number of slots before a UE is scheduled ULSCH due to inactivity", 0, uptr:NULL, defintval:200, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_MACRLC_ULSCH_MAX_FRAME_INACTIVITY, NULL, 0, uptr:NULL, defintval:10, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_MACRLC_PUSCHTARGETSNRX10, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \
|
||||
{CONFIG_STRING_MACRLC_PUCCHTARGETSNRX10, NULL, 0, iptr:NULL, defintval:150, TYPE_INT, 0}, \
|
||||
{CONFIG_STRING_MACRLC_PUCCHFAILURETHRES, NULL, 0, iptr:NULL, defintval:10, TYPE_INT, 0}, \
|
||||
@@ -106,7 +106,7 @@
|
||||
#define MACRLC_REMOTE_S_PORTC_IDX 14
|
||||
#define MACRLC_LOCAL_S_PORTD_IDX 15
|
||||
#define MACRLC_REMOTE_S_PORTD_IDX 16
|
||||
#define MACRLC_ULSCH_MAX_SLOTS_INACTIVITY 17
|
||||
#define MACRLC_ULSCH_MAX_FRAME_INACTIVITY 17
|
||||
#define MACRLC_PUSCHTARGETSNRX10_IDX 18
|
||||
#define MACRLC_PUCCHTARGETSNRX10_IDX 19
|
||||
#define MACRLC_PUCCHFAILURETHRES_IDX 20
|
||||
|
||||
@@ -771,7 +771,7 @@ void RCconfig_nr_macrlc() {
|
||||
}else { // other midhaul
|
||||
AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr));
|
||||
}
|
||||
RC.nrmac[j]->ulsch_max_slots_inactivity = *(MacRLC_ParamList.paramarray[j][MACRLC_ULSCH_MAX_SLOTS_INACTIVITY].uptr);
|
||||
RC.nrmac[j]->ulsch_max_frame_inactivity = *(MacRLC_ParamList.paramarray[j][MACRLC_ULSCH_MAX_FRAME_INACTIVITY].uptr);
|
||||
RC.nrmac[j]->num_ulprbbl = num_prbbl;
|
||||
LOG_I(NR_MAC,"Blacklisted PRBS %d\n",num_prbbl);
|
||||
memcpy(RC.nrmac[j]->ulprbbl,prbbl,275*sizeof(prbbl[0]));
|
||||
|
||||
@@ -40,6 +40,9 @@
|
||||
|
||||
#include "NR_SubcarrierSpacing.h"
|
||||
|
||||
#define NR_SHORT_BSR_TABLE_SIZE 32
|
||||
#define NR_LONG_BSR_TABLE_SIZE 256
|
||||
|
||||
#define TABLE_38213_13_1_NUM_INDEXES 15
|
||||
#define TABLE_38213_13_2_NUM_INDEXES 14
|
||||
#define TABLE_38213_13_3_NUM_INDEXES 9
|
||||
@@ -65,6 +68,11 @@ typedef enum frequency_range_e {
|
||||
FR2
|
||||
} frequency_range_t;
|
||||
|
||||
#define NR_BSR_TRIGGER_NONE (0) /* No BSR Trigger */
|
||||
#define NR_BSR_TRIGGER_REGULAR (1) /* For Regular and ReTxBSR Expiry Triggers */
|
||||
#define NR_BSR_TRIGGER_PERIODIC (2) /* For BSR Periodic Timer Expiry Trigger */
|
||||
#define NR_BSR_TRIGGER_PADDING (4) /* For Padding BSR Trigger */
|
||||
|
||||
// For both DL/UL-SCH
|
||||
// Except:
|
||||
// - UL/DL-SCH: fixed-size MAC CE(known by LCID)
|
||||
|
||||
@@ -48,6 +48,33 @@ void reverse_n_bits(uint8_t *value, uint16_t bitlen) {
|
||||
}
|
||||
}
|
||||
|
||||
//38.321 Table 6.1.3.1-1
|
||||
const uint32_t NR_SHORT_BSR_TABLE[NR_SHORT_BSR_TABLE_SIZE] = {
|
||||
0, 10, 14, 20, 28, 38, 53, 74,
|
||||
102, 142, 198, 276, 384, 535, 745, 1038,
|
||||
1446, 2014, 2806, 3909, 5446, 7587, 10570, 14726,
|
||||
20516, 28581, 39818, 55474, 77284, 107669, 150000, 300000
|
||||
};
|
||||
|
||||
//38.321 Table 6.1.3.1-2
|
||||
const uint32_t NR_LONG_BSR_TABLE[NR_LONG_BSR_TABLE_SIZE] ={
|
||||
0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 23, 25, 26,
|
||||
28, 30, 32, 34, 36, 38, 40, 43, 46, 49, 52, 55, 59, 62, 66, 71,
|
||||
75, 80, 85, 91, 97, 103, 110, 117, 124, 132, 141, 150, 160, 170, 181, 193,
|
||||
205, 218, 233, 248, 264, 281, 299, 318, 339, 361, 384, 409, 436, 464, 494, 526,
|
||||
560, 597, 635, 677, 720, 767, 817, 870, 926, 987, 1051, 1119, 1191, 1269, 1351, 1439,
|
||||
1532, 1631, 1737, 1850, 1970, 2098, 2234, 2379, 2533, 2698, 2873, 3059, 3258, 3469, 3694, 3934,
|
||||
4189, 4461, 4751, 5059, 5387, 5737, 6109, 6506, 6928, 7378, 7857, 8367, 8910, 9488, 10104, 10760,
|
||||
11458, 12202, 12994, 13838, 14736, 15692, 16711, 17795, 18951, 20181, 21491, 22885, 24371, 25953, 27638, 29431,
|
||||
31342, 33376, 35543, 37850, 40307, 42923, 45709, 48676, 51836, 55200, 58784, 62599, 66663, 70990, 75598, 80505,
|
||||
85730, 91295, 97221, 103532, 110252, 117409, 125030, 133146, 141789, 150992, 160793, 171231, 182345, 194182, 206786, 220209,
|
||||
234503, 249725, 265935, 283197, 301579, 321155, 342002, 364202, 387842, 413018, 439827, 468377, 498780, 531156, 565634, 602350,
|
||||
641449, 683087, 727427, 774645, 824928, 878475, 935498, 996222, 1060888, 1129752, 1203085, 1281179, 1364342, 1452903, 1547213, 1647644,
|
||||
1754595, 1868488, 1989774, 2118933, 2256475, 2402946, 2558924, 2725027, 2901912, 3090279, 3290873, 3504487, 3731968, 3974215, 4232186, 4506902,
|
||||
4799451, 5110989, 5442750, 5796046, 6172275, 6572925, 6999582, 7453933, 7937777, 8453028, 9001725, 9586039, 10208280, 10870913, 11576557, 12328006,
|
||||
13128233, 13980403, 14887889, 15854280, 16883401, 17979324, 19146385, 20389201, 21712690, 23122088, 24622972, 26221280, 27923336, 29735875, 31666069, 33721553,
|
||||
35910462, 38241455, 40723756, 43367187, 46182206, 49179951, 52372284, 55771835, 59392055, 63247269, 67352729, 71724679, 76380419, 81338368, 162676736, 4294967295
|
||||
};
|
||||
|
||||
// start symbols for SSB types A,B,C,D,E
|
||||
uint16_t symbol_ssb_AC[8]={2,8,16,22,30,36,44,50};
|
||||
|
||||
@@ -76,6 +76,9 @@ extern boolean_t pre_scd_activeUE[NUMBER_OF_UE_MAX];
|
||||
extern eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
|
||||
#endif*/
|
||||
|
||||
extern const uint32_t NR_SHORT_BSR_TABLE[NR_SHORT_BSR_TABLE_SIZE];
|
||||
extern const uint32_t NR_LONG_BSR_TABLE[NR_LONG_BSR_TABLE_SIZE];
|
||||
|
||||
// Type0-PDCCH search space
|
||||
extern const int32_t table_38213_13_1_c1[16];
|
||||
extern const int32_t table_38213_13_1_c2[16];
|
||||
|
||||
Executable → Regular
+23
@@ -643,6 +643,18 @@ void configure_ss_coreset(NR_UE_MAC_INST_t *mac,
|
||||
}
|
||||
}
|
||||
|
||||
// todo handle mac_LogicalChannelConfig
|
||||
int nr_rrc_mac_config_req_ue_logicalChannelBearer(
|
||||
module_id_t module_id,
|
||||
int cc_idP,
|
||||
uint8_t gNB_index,
|
||||
long logicalChannelIdentity,
|
||||
boolean_t status){
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
||||
mac->logicalChannelBearer_exist[logicalChannelIdentity] = status;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nr_rrc_mac_config_req_ue(
|
||||
module_id_t module_id,
|
||||
int cc_idP,
|
||||
@@ -706,6 +718,17 @@ int nr_rrc_mac_config_req_ue(
|
||||
LOG_I(MAC,"Applying CellGroupConfig from gNodeB\n");
|
||||
mac->cg = cell_group_config;
|
||||
mac->servCellIndex = cell_group_config->spCellConfig->servCellIndex ? *cell_group_config->spCellConfig->servCellIndex : 0;
|
||||
|
||||
mac->scheduling_info.periodicBSR_SF =
|
||||
MAC_UE_BSR_TIMER_NOT_RUNNING;
|
||||
mac->scheduling_info.retxBSR_SF =
|
||||
MAC_UE_BSR_TIMER_NOT_RUNNING;
|
||||
mac->BSR_reporting_active = NR_BSR_TRIGGER_NONE;
|
||||
LOG_D(MAC, "[UE %d]: periodic BSR %d (SF), retx BSR %d (SF)\n",
|
||||
module_id,
|
||||
mac->scheduling_info.periodicBSR_SF,
|
||||
mac->scheduling_info.retxBSR_SF);
|
||||
|
||||
config_control_ue(mac);
|
||||
//config_common_ue(mac,module_id,cc_idP);
|
||||
/*
|
||||
|
||||
Executable → Regular
+11
-12
@@ -182,9 +182,9 @@ typedef struct {
|
||||
uint16_t All_lcid_buffer_size_lastTTI;
|
||||
/// buffer status for each lcid
|
||||
uint8_t LCID_status[NR_MAX_NUM_LCID];
|
||||
/// SR pending as defined in 36.321
|
||||
/// SR pending as defined in 38.321
|
||||
uint8_t SR_pending;
|
||||
/// SR_COUNTER as defined in 36.321
|
||||
/// SR_COUNTER as defined in 38.321
|
||||
uint16_t SR_COUNTER;
|
||||
/// logical channel group ide for each LCID
|
||||
uint8_t LCGID[NR_MAX_NUM_LCID];
|
||||
@@ -328,15 +328,6 @@ typedef struct {
|
||||
|
||||
} RAR_grant_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
uint8_t phr_reporting;
|
||||
uint16_t truncated_bsr;
|
||||
uint16_t short_bsr;
|
||||
uint16_t long_bsr;
|
||||
|
||||
} NR_UE_MAC_CE_t;
|
||||
|
||||
typedef struct {
|
||||
int n_HARQ_ACK;
|
||||
uint32_t ack_payload;
|
||||
@@ -353,6 +344,7 @@ typedef struct {
|
||||
int8_t delta_pucch;
|
||||
} PUCCH_sched_t;
|
||||
|
||||
|
||||
/*!\brief Top level UE MAC structure */
|
||||
typedef struct {
|
||||
|
||||
@@ -419,8 +411,15 @@ typedef struct {
|
||||
nr_ue_if_module_t *if_module;
|
||||
nr_phy_config_t phy_config;
|
||||
|
||||
/// BSR report flag management
|
||||
uint8_t BSR_reporting_active;
|
||||
|
||||
/// LogicalChannelConfig has bearer.
|
||||
boolean_t logicalChannelBearer_exist[NR_MAX_NUM_LCID];
|
||||
NR_UE_SCHEDULING_INFO scheduling_info;
|
||||
NR_UE_MAC_CE_t nr_ue_mac_ce;
|
||||
|
||||
/// PHR
|
||||
uint8_t PHR_reporting_active;
|
||||
|
||||
NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config;
|
||||
NR_SearchSpace_t *search_space_zero;
|
||||
|
||||
Executable → Regular
+73
-3
@@ -40,6 +40,10 @@
|
||||
#define NR_DL_MAX_DAI (4) /* TS 38.213 table 9.1.3-1 Value of counter DAI for DCI format 1_0 and 1_1 */
|
||||
#define NR_DL_MAX_NB_CW (2) /* number of downlink code word */
|
||||
|
||||
/**\brief initialize the field in nr_mac instance
|
||||
\param module_id module id */
|
||||
void nr_ue_init_mac(module_id_t module_idP);
|
||||
|
||||
/**\brief decode mib pdu in NR_UE, from if_module ul_ind with P7 tx_ind message
|
||||
\param module_id module id
|
||||
\param cc_id component carrier id
|
||||
@@ -74,6 +78,20 @@ int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id,
|
||||
uint8_t *pduP,
|
||||
uint32_t pdu_len);
|
||||
|
||||
/**\brief primitive from RRC layer to MAC layer to set if bearer exists for a logical channel. todo handle mac_LogicalChannelConfig
|
||||
\param module_id module id
|
||||
\param cc_id component carrier id
|
||||
\param gNB_index gNB index
|
||||
\param long logicalChannelIdentity
|
||||
\param boolean_t status*/
|
||||
int nr_rrc_mac_config_req_ue_logicalChannelBearer(
|
||||
module_id_t module_id,
|
||||
int cc_idP,
|
||||
uint8_t gNB_index,
|
||||
long logicalChannelIdentity,
|
||||
boolean_t status
|
||||
);
|
||||
|
||||
/**\brief primitive from RRC layer to MAC layer for configuration L1/L2, now supported 4 rrc messages: MIB, cell_group_config for MAC/PHY, spcell_config(serving cell config)
|
||||
\param module_id module id
|
||||
\param cc_id component carrier id
|
||||
@@ -125,7 +143,53 @@ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response,
|
||||
int slot,
|
||||
int thread_id);
|
||||
|
||||
int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, int slotP);
|
||||
/*! \fn int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, slot_t slotP);
|
||||
\brief Called by PHY to get sdu for PUSCH transmission. It performs the following operations: Checks BSR for DCCH, DCCH1 and DTCH corresponding to previous values computed either in SR or BSR procedures. It gets rlc status indications on DCCH,DCCH1 and DTCH and forms BSR elements and PHR in MAC header. CRNTI element is not supported yet. It computes transport block for up to 3 SDUs and generates header and forms the complete MAC SDU.
|
||||
\param[in] Mod_id Instance id of UE in machine
|
||||
\param[in] frameP subframe number
|
||||
\param[in] slotP slot number
|
||||
*/
|
||||
int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, slot_t slotP);
|
||||
|
||||
/*! \fn boolean_t update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_index)
|
||||
\brief get the rlc stats and update the bsr level for each lcid
|
||||
\param[in] Mod_id instance of the UE
|
||||
\param[in] frameP Frame index
|
||||
\param[in] slot slotP number
|
||||
\param[in] uint8_t gNB_index
|
||||
*/
|
||||
boolean_t nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_index);
|
||||
|
||||
/*! \fn nr_locate_BsrIndexByBufferSize (int *table, int size, int value)
|
||||
\brief locate the BSR level in the table as defined in 38.321. This function requires that he values in table to be monotonic, either increasing or decreasing. The returned value is not less than 0, nor greater than n-1, where n is the size of table.
|
||||
\param[in] *table Pointer to BSR table
|
||||
\param[in] size Size of the table
|
||||
\param[in] value Value of the buffer
|
||||
\return the index in the BSR_LEVEL table
|
||||
*/
|
||||
uint8_t nr_locate_BsrIndexByBufferSize(const uint32_t *table, int size,
|
||||
int value);
|
||||
|
||||
/*! \fn int nr_get_sf_periodicBSRTimer(uint8_t periodicBSR_Timer)
|
||||
\brief get the number of subframe from the periodic BSR timer configured by the higher layers
|
||||
\param[in] periodicBSR_Timer timer for periodic BSR
|
||||
\return the number of subframe
|
||||
*/
|
||||
int nr_get_sf_periodicBSRTimer(uint8_t bucketSize);
|
||||
|
||||
/*! \fn int nr_get_ms_bucketsizeduration(uint8_t bucketSize)
|
||||
\brief get the time in ms form the bucket size duration configured by the higher layer
|
||||
\param[in] bucketSize the bucket size duration
|
||||
\return the time in ms
|
||||
*/
|
||||
int nr_get_ms_bucketsizeduration(uint8_t bucketsizeduration);
|
||||
|
||||
/*! \fn int nr_get_sf_retxBSRTimer(uint8_t retxBSR_Timer)
|
||||
\brief get the number of subframe form the bucket size duration configured by the higher layer
|
||||
\param[in] retxBSR_Timer timer for regular BSR
|
||||
\return the time in sf
|
||||
*/
|
||||
int nr_get_sf_retxBSRTimer(uint8_t retxBSR_Timer);
|
||||
|
||||
int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, frame_t frame, int slot, dci_pdu_rel15_t *dci, fapi_nr_dci_indication_pdu_t *dci_ind);
|
||||
int nr_ue_process_dci_indication_pdu(module_id_t module_id, int cc_id, int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci);
|
||||
@@ -170,7 +234,13 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
||||
int pdu_id);
|
||||
|
||||
int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
|
||||
NR_UE_MAC_INST_t *mac);
|
||||
NR_UE_MAC_INST_t *mac,
|
||||
uint8_t power_headroom, // todo: NR_POWER_HEADROOM_CMD *power_headroom,
|
||||
uint16_t *crnti,
|
||||
NR_BSR_SHORT *truncated_bsr,
|
||||
NR_BSR_SHORT *short_bsr,
|
||||
NR_BSR_LONG *long_bsr
|
||||
);
|
||||
|
||||
void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15);
|
||||
|
||||
@@ -330,7 +400,7 @@ void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot);
|
||||
If the UE is not in PUSCH mode for a particular eNB index, this is assumed to be an Msg3 and MAC
|
||||
attempts to retrieves the CCCH message from RRC. If the UE is in PUSCH mode for a particular eNB
|
||||
index and PUCCH format 0 (Scheduling Request) is not activated, the MAC may use this resource for
|
||||
andom-access to transmit a BSR along with the C-RNTI control element (see 5.1.4 from 36.321)
|
||||
andom-access to transmit a BSR along with the C-RNTI control element (see 5.1.4 from 38.321)
|
||||
@param mod_id Index of UE instance
|
||||
@param CC_id Component Carrier Index
|
||||
@param frame
|
||||
|
||||
@@ -52,8 +52,9 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) {
|
||||
//init mac here
|
||||
nr_ue_mac_inst = (NR_UE_MAC_INST_t *)calloc(sizeof(NR_UE_MAC_INST_t),NB_NR_UE_MAC_INST);
|
||||
|
||||
for (int j=0;j<NB_NR_UE_MAC_INST;j++)
|
||||
for (int i=0;i<NR_MAX_HARQ_PROCESSES;i++) nr_ue_mac_inst[j].first_ul_tx[i]=1;
|
||||
for (int j=0;j<NB_NR_UE_MAC_INST;j++) {
|
||||
nr_ue_init_mac(j);
|
||||
}
|
||||
|
||||
|
||||
if (rrc_inst && rrc_inst->scell_group_config) {
|
||||
|
||||
@@ -742,7 +742,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
|
||||
|
||||
} else {
|
||||
|
||||
size_sdu = nr_write_ce_ulsch_pdu(pdu, mac);
|
||||
size_sdu = nr_write_ce_ulsch_pdu(pdu, mac, 0, &(mac->crnti), NULL, NULL, NULL);
|
||||
pdu += size_sdu;
|
||||
ra->Msg3_size = size_sdu;
|
||||
|
||||
|
||||
@@ -134,6 +134,55 @@ const initial_pucch_resource_t initial_pucch_resource[16] = {
|
||||
};
|
||||
|
||||
|
||||
void nr_ue_init_mac(module_id_t module_idP) {
|
||||
int i;
|
||||
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
|
||||
// default values as deined in 38.331 sec 9.2.2
|
||||
LOG_I(NR_MAC, "[UE%d] Applying default macMainConfig\n", module_idP);
|
||||
//mac->scheduling_info.macConfig=NULL;
|
||||
mac->scheduling_info.retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf10240;
|
||||
mac->scheduling_info.periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_infinity;
|
||||
// mac->scheduling_info.periodicPHR_Timer = NR_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20;
|
||||
// mac->scheduling_info.prohibitPHR_Timer = NR_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20;
|
||||
// mac->scheduling_info.PathlossChange_db = NR_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1;
|
||||
// mac->PHR_state = NR_MAC_MainConfig__phr_Config_PR_setup;
|
||||
mac->scheduling_info.SR_COUNTER = 0;
|
||||
mac->scheduling_info.sr_ProhibitTimer = 0;
|
||||
mac->scheduling_info.sr_ProhibitTimer_Running = 0;
|
||||
// mac->scheduling_info.maxHARQ_Tx = NR_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5;
|
||||
// mac->scheduling_info.ttiBundling = 0;
|
||||
// mac->scheduling_info.extendedBSR_Sizes_r10 = 0;
|
||||
// mac->scheduling_info.extendedPHR_r10 = 0;
|
||||
// mac->scheduling_info.drx_config = NULL;
|
||||
// mac->scheduling_info.phr_config = NULL;
|
||||
// set init value 0xFFFF, make sure periodic timer and retx time counters are NOT active, after bsr transmission set the value configured by the NW.
|
||||
mac->scheduling_info.periodicBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING;
|
||||
mac->scheduling_info.retxBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING;
|
||||
mac->BSR_reporting_active = BSR_TRIGGER_NONE;
|
||||
// mac->scheduling_info.periodicPHR_SF = nr_get_sf_perioidicPHR_Timer(mac->scheduling_info.periodicPHR_Timer);
|
||||
// mac->scheduling_info.prohibitPHR_SF = nr_get_sf_prohibitPHR_Timer(mac->scheduling_info.prohibitPHR_Timer);
|
||||
// mac->scheduling_info.PathlossChange_db = nr_get_db_dl_PathlossChange(mac->scheduling_info.PathlossChange);
|
||||
// mac->PHR_reporting_active = 0;
|
||||
|
||||
for (i = 0; i < NR_MAX_NUM_LCID; i++) {
|
||||
LOG_D(NR_MAC, "[UE%d] Applying default logical channel config for LCGID %d\n",
|
||||
module_idP, i);
|
||||
mac->scheduling_info.Bj[i] = -1;
|
||||
mac->scheduling_info.bucket_size[i] = -1;
|
||||
|
||||
if (i < UL_SCH_LCID_DTCH) { // initialize all control channels lcgid to 0
|
||||
mac->scheduling_info.LCGID[i] = 0;
|
||||
} else { // initialize all the data channels lcgid to 1
|
||||
mac->scheduling_info.LCGID[i] = 1;
|
||||
}
|
||||
|
||||
mac->scheduling_info.LCID_status[i] = LCID_EMPTY;
|
||||
mac->scheduling_info.LCID_buffer_remain[i] = 0;
|
||||
for (int i=0;i<NR_MAX_HARQ_PROCESSES;i++) mac->first_ul_tx[i]=1;
|
||||
}
|
||||
}
|
||||
|
||||
void get_bwp_info(NR_UE_MAC_INST_t *mac,
|
||||
int dl_bwp_id,
|
||||
int ul_bwp_id,
|
||||
@@ -2218,9 +2267,54 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac,
|
||||
return false;
|
||||
}
|
||||
|
||||
int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, slot_t slot){
|
||||
// no UL-SCH resources available for this tti && UE has a valid PUCCH resources for SR configuration for this tti
|
||||
DevCheck(module_idP < (int) NB_UE_INST, module_idP, NB_NR_UE_MAC_INST, 0);
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
|
||||
DSR_TRANSMAX_t dsr_TransMax = sr_n64; // todo
|
||||
LOG_D(NR_MAC, "[UE %d] Frame %d slot %d send SR indication (SR_COUNTER/dsr_TransMax %d/%d), SR_pending %d\n",
|
||||
module_idP, frameP, slot,
|
||||
mac->scheduling_info.SR_COUNTER,
|
||||
(1 << (2 + dsr_TransMax)),
|
||||
mac->scheduling_info.SR_pending); // todo
|
||||
|
||||
int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, int slotP){
|
||||
return 0;
|
||||
if ((mac->scheduling_info.SR_pending == 1) &&
|
||||
(mac->scheduling_info.SR_COUNTER < (1 << (2 + dsr_TransMax)))) {
|
||||
LOG_D(NR_MAC, "[UE %d] Frame %d slot %d PHY asks for SR (SR_COUNTER/dsr_TransMax %d/%d), SR_pending %d, increment SR_COUNTER\n",
|
||||
module_idP, frameP, slot,
|
||||
mac->scheduling_info.SR_COUNTER,
|
||||
(1 << (2 + dsr_TransMax)),
|
||||
mac->scheduling_info.SR_pending); // todo
|
||||
mac->scheduling_info.SR_COUNTER++;
|
||||
|
||||
// start the sr-prohibittimer : rel 9 and above
|
||||
if (mac->scheduling_info.sr_ProhibitTimer > 0) { // timer configured
|
||||
mac->scheduling_info.sr_ProhibitTimer--;
|
||||
mac->scheduling_info.
|
||||
sr_ProhibitTimer_Running = 1;
|
||||
} else {
|
||||
mac->scheduling_info.
|
||||
sr_ProhibitTimer_Running = 0;
|
||||
}
|
||||
//mac->ul_active =1;
|
||||
return (1); //instruct phy to signal SR
|
||||
} else {
|
||||
// notify RRC to relase PUCCH/SRS
|
||||
// clear any configured dl/ul
|
||||
// initiate RA
|
||||
if (mac->scheduling_info.SR_pending) {
|
||||
// release all pucch resource
|
||||
//mac->physicalConfigDedicated = NULL; // todo
|
||||
//mac->ul_active = 0; // todo
|
||||
mac->BSR_reporting_active =
|
||||
NR_BSR_TRIGGER_NONE;
|
||||
LOG_I(NR_MAC, "[UE %d] Release all SRs \n", module_idP);
|
||||
}
|
||||
|
||||
mac->scheduling_info.SR_pending = 0;
|
||||
mac->scheduling_info.SR_COUNTER = 0;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3491,13 +3585,17 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
||||
* Return: number of written bytes
|
||||
*/
|
||||
int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
|
||||
NR_UE_MAC_INST_t *mac) {
|
||||
NR_UE_MAC_INST_t *mac,
|
||||
uint8_t power_headroom, // todo: NR_POWER_HEADROOM_CMD *power_headroom,
|
||||
uint16_t *crnti,
|
||||
NR_BSR_SHORT *truncated_bsr,
|
||||
NR_BSR_SHORT *short_bsr,
|
||||
NR_BSR_LONG *long_bsr) {
|
||||
|
||||
int mac_ce_len = 0;
|
||||
uint8_t mac_ce_size = 0;
|
||||
NR_UE_MAC_CE_t *nr_ue_mac_ce = &mac->nr_ue_mac_ce;
|
||||
|
||||
if (nr_ue_mac_ce->phr_reporting && mac->phr_Config != NULL) {
|
||||
uint8_t *pdu = mac_ce;
|
||||
if (power_headroom) {
|
||||
|
||||
// MAC CE fixed subheader
|
||||
((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0;
|
||||
@@ -3505,21 +3603,22 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
|
||||
mac_ce++;
|
||||
|
||||
// PHR MAC CE (1 octet)
|
||||
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PH = 0;
|
||||
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PH = power_headroom;
|
||||
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->R1 = 0;
|
||||
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PCMAX = 0;
|
||||
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PCMAX = 0; // todo
|
||||
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->R2 = 0;
|
||||
|
||||
// update pointer and length
|
||||
mac_ce_size = sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE);
|
||||
mac_ce += mac_ce_size;
|
||||
mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED);
|
||||
|
||||
LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : power_headroom pdu %p mac_ce %p b\n",
|
||||
pdu, mac_ce);
|
||||
}
|
||||
|
||||
if (!get_softmodem_params()->sa && get_softmodem_params()->do_ra && mac->ra.ra_state != RA_SUCCEEDED) {
|
||||
if (crnti && (!get_softmodem_params()->sa && get_softmodem_params()->do_ra && mac->ra.ra_state != RA_SUCCEEDED)) {
|
||||
|
||||
LOG_D(NR_MAC, "In %s: generating C-RNTI MAC CE with C-RNTI %x\n", __FUNCTION__, mac->crnti);
|
||||
LOG_D(NR_MAC, "In %s: generating C-RNTI MAC CE with C-RNTI %x\n", __FUNCTION__, (*crnti));
|
||||
|
||||
// MAC CE fixed subheader
|
||||
((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0;
|
||||
@@ -3527,7 +3626,7 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
|
||||
mac_ce++;
|
||||
|
||||
// C-RNTI MAC CE (2 octets)
|
||||
*(uint16_t *) mac_ce = mac->crnti;
|
||||
*(uint16_t *) mac_ce = (*crnti);
|
||||
|
||||
// update pointer and length
|
||||
mac_ce_size = sizeof(uint16_t);
|
||||
@@ -3536,55 +3635,110 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
|
||||
|
||||
}
|
||||
|
||||
if (nr_ue_mac_ce->truncated_bsr) {
|
||||
if (truncated_bsr) {
|
||||
|
||||
LOG_D(NR_MAC, "In %s: generating short truncated BSR MAC CE with command %x\n", __FUNCTION__, nr_ue_mac_ce->truncated_bsr);
|
||||
|
||||
// MAC CE fixed subheader
|
||||
// MAC CE fixed subheader
|
||||
((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0;
|
||||
((NR_MAC_SUBHEADER_FIXED *) mac_ce)->LCID = UL_SCH_LCID_S_TRUNCATED_BSR;
|
||||
mac_ce++;
|
||||
|
||||
// Short truncated BSR MAC CE (1 octet)
|
||||
((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> Buffer_size = 0;
|
||||
((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> LcgID = 0;
|
||||
((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> Buffer_size = truncated_bsr->Buffer_size;
|
||||
((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> LcgID = truncated_bsr->LcgID;;
|
||||
|
||||
// update pointer and length
|
||||
mac_ce_size = sizeof(NR_BSR_SHORT_TRUNCATED);
|
||||
mac_ce += mac_ce_size;
|
||||
mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED);
|
||||
LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : truncated_bsr Buffer_size %d LcgID %d pdu %p mac_ce %p\n",
|
||||
truncated_bsr->Buffer_size, truncated_bsr->LcgID, pdu, mac_ce);
|
||||
|
||||
} else if (nr_ue_mac_ce->short_bsr) {
|
||||
} else if (short_bsr) {
|
||||
|
||||
LOG_D(NR_MAC, "In %s: generating short BSR MAC CE with command %x\n", __FUNCTION__, nr_ue_mac_ce->short_bsr);
|
||||
|
||||
// MAC CE fixed subheader
|
||||
// MAC CE fixed subheader
|
||||
((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0;
|
||||
((NR_MAC_SUBHEADER_FIXED *) mac_ce)->LCID = UL_SCH_LCID_S_BSR;
|
||||
mac_ce++;
|
||||
|
||||
// Short truncated BSR MAC CE (1 octet)
|
||||
((NR_BSR_SHORT *) mac_ce)->Buffer_size = nr_ue_mac_ce->short_bsr;
|
||||
((NR_BSR_SHORT *) mac_ce)->LcgID = 0;
|
||||
((NR_BSR_SHORT *) mac_ce)->Buffer_size = short_bsr->Buffer_size;
|
||||
((NR_BSR_SHORT *) mac_ce)->LcgID = short_bsr->LcgID;
|
||||
|
||||
// update pointer and length
|
||||
mac_ce_size = sizeof(NR_BSR_SHORT);
|
||||
mac_ce += mac_ce_size;
|
||||
mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED);
|
||||
LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : short_bsr Buffer_size %d LcgID %d pdu %p mac_ce %p\n",
|
||||
short_bsr->Buffer_size, short_bsr->LcgID, pdu, mac_ce);
|
||||
} else if (long_bsr) {
|
||||
|
||||
} else if (nr_ue_mac_ce->long_bsr) {
|
||||
// MAC CE variable subheader
|
||||
// todo ch 6.1.3.1. TS 38.321
|
||||
// ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->R = 0;
|
||||
// ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->F = 0;
|
||||
// ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->LCID = UL_SCH_LCID_L_BSR;
|
||||
// ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->L = 0;
|
||||
// sh_size = 2;
|
||||
// MAC CE variable subheader
|
||||
// ch 6.1.3.1. TS 38.321
|
||||
((NR_MAC_SUBHEADER_SHORT *) mac_ce)->R = 0;
|
||||
((NR_MAC_SUBHEADER_SHORT *) mac_ce)->F = 0;
|
||||
((NR_MAC_SUBHEADER_SHORT *) mac_ce)->LCID = UL_SCH_LCID_L_BSR;
|
||||
|
||||
// Short truncated BSR MAC CE (1 octet)
|
||||
// ((NR_BSR_LONG *) mac_ce)->Buffer_size0 = short_bsr;
|
||||
// ((NR_BSR_LONG *) mac_ce)->LCGID0 = 0;
|
||||
// mac_ce_size = sizeof(NR_BSR_LONG); // size is variable
|
||||
NR_MAC_SUBHEADER_SHORT *mac_pdu_subheader_ptr = (NR_MAC_SUBHEADER_SHORT *) mac_ce;
|
||||
mac_ce += 2;
|
||||
|
||||
// Could move to nr_get_sdu()
|
||||
uint8_t *Buffer_size_ptr= (uint8_t*) mac_ce + 1;
|
||||
//int NR_BSR_LONG_SIZE = 1;
|
||||
if (long_bsr->Buffer_size0 == 0) {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID0 = 0;
|
||||
} else {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID0 = 1;
|
||||
*Buffer_size_ptr++ = long_bsr->Buffer_size0;
|
||||
}
|
||||
if (long_bsr->Buffer_size1 == 0) {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID1 = 0;
|
||||
} else {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID1 = 1;
|
||||
*Buffer_size_ptr++ = long_bsr->Buffer_size1;
|
||||
}
|
||||
if (long_bsr->Buffer_size2 == 0) {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID2 = 0;
|
||||
} else {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID2 = 1;
|
||||
*Buffer_size_ptr++ = long_bsr->Buffer_size2;
|
||||
}
|
||||
if (long_bsr->Buffer_size3 == 0) {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID3 = 0;
|
||||
} else {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID3 = 1;
|
||||
*Buffer_size_ptr++ = long_bsr->Buffer_size3;
|
||||
}
|
||||
if (long_bsr->Buffer_size4 == 0) {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID4 = 0;
|
||||
} else {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID4 = 1;
|
||||
*Buffer_size_ptr++ = long_bsr->Buffer_size4;
|
||||
}
|
||||
if (long_bsr->Buffer_size5 == 0) {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID5 = 0;
|
||||
} else {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID5 = 1;
|
||||
*Buffer_size_ptr++ = long_bsr->Buffer_size5;
|
||||
}
|
||||
if (long_bsr->Buffer_size6 == 0) {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID6 = 0;
|
||||
} else {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID6 = 1;
|
||||
*Buffer_size_ptr++ = long_bsr->Buffer_size6;
|
||||
}
|
||||
if (long_bsr->Buffer_size7 == 0) {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID7 = 0;
|
||||
} else {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID7 = 1;
|
||||
*Buffer_size_ptr++ = long_bsr->Buffer_size7;
|
||||
}
|
||||
((NR_MAC_SUBHEADER_SHORT *) mac_pdu_subheader_ptr)->L = mac_ce_size = (uint8_t*) Buffer_size_ptr - (uint8_t*) mac_ce;
|
||||
LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : long_bsr size %d Lcgbit 0x%02x Buffer_size %d %d %d %d %d %d %d %d\n", mac_ce_size, *((uint8_t*) mac_ce),
|
||||
((NR_BSR_LONG *) mac_ce)->Buffer_size0, ((NR_BSR_LONG *) mac_ce)->Buffer_size1, ((NR_BSR_LONG *) mac_ce)->Buffer_size2, ((NR_BSR_LONG *) mac_ce)->Buffer_size3,
|
||||
((NR_BSR_LONG *) mac_ce)->Buffer_size4, ((NR_BSR_LONG *) mac_ce)->Buffer_size5, ((NR_BSR_LONG *) mac_ce)->Buffer_size6, ((NR_BSR_LONG *) mac_ce)->Buffer_size7);
|
||||
// update pointer and length
|
||||
mac_ce = Buffer_size_ptr;
|
||||
mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_SHORT);
|
||||
}
|
||||
|
||||
return mac_ce_len;
|
||||
|
||||
@@ -53,6 +53,8 @@
|
||||
|
||||
#include <executables/softmodem-common.h>
|
||||
|
||||
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
|
||||
|
||||
static prach_association_pattern_t prach_assoc_pattern;
|
||||
static ssb_list_info_t ssb_list;
|
||||
|
||||
@@ -168,13 +170,26 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con
|
||||
|
||||
NR_ServingCellConfigCommon_t *scc = mac->scc;
|
||||
NR_BWP_Id_t ul_bwp_id = mac->UL_BWP_Id;
|
||||
NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup;
|
||||
NR_BWP_UplinkDedicated_t *ubwpd=NULL;
|
||||
|
||||
if (mac->cg &&
|
||||
mac->cg->spCellConfig &&
|
||||
mac->cg->spCellConfig->spCellConfigDedicated &&
|
||||
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig &&
|
||||
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP)
|
||||
ubwpd = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP;
|
||||
|
||||
NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[ul_bwp_id-1] ?
|
||||
mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup :
|
||||
(ubwpd?
|
||||
ubwpd->pusch_Config->choice.setup:
|
||||
NULL);
|
||||
|
||||
long transformPrecoder;
|
||||
if (pusch_Config->transformPrecoder)
|
||||
if (pusch_Config && pusch_Config->transformPrecoder)
|
||||
transformPrecoder = *pusch_Config->transformPrecoder;
|
||||
else {
|
||||
if(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder)
|
||||
if(scc && scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder)
|
||||
transformPrecoder = NR_PUSCH_Config__transformPrecoder_enabled;
|
||||
else
|
||||
transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled;
|
||||
@@ -1014,10 +1029,324 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
||||
}
|
||||
}
|
||||
|
||||
if (dl_info) {
|
||||
return (CONNECTION_OK);
|
||||
}
|
||||
module_id_t mod_id = ul_info->module_id;
|
||||
frame_t txFrameP = ul_info->frame_tx;
|
||||
slot_t txSlotP = ul_info->slot_tx;
|
||||
|
||||
// Handle the SR/BSR procedures per subframe
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
|
||||
uint8_t gNB_indexP=0;
|
||||
|
||||
// Call BSR procedure as described in Section 5.4.5 in 38.321
|
||||
|
||||
// First check ReTxBSR Timer because it is always configured
|
||||
// Decrement ReTxBSR Timer if it is running and not null
|
||||
if ((mac->scheduling_info.retxBSR_SF != MAC_UE_BSR_TIMER_NOT_RUNNING) && (mac->scheduling_info.retxBSR_SF != 0)) {
|
||||
mac->scheduling_info.retxBSR_SF--;
|
||||
}
|
||||
|
||||
// Decrement Periodic Timer if it is running and not null
|
||||
if ((mac->scheduling_info.periodicBSR_SF != MAC_UE_BSR_TIMER_NOT_RUNNING) && (mac->scheduling_info.periodicBSR_SF != 0)) {
|
||||
mac->scheduling_info.periodicBSR_SF--;
|
||||
}
|
||||
|
||||
//Check whether Regular BSR is triggered
|
||||
if (nr_update_bsr(mod_id, txFrameP, txSlotP, gNB_indexP) == TRUE) {
|
||||
// call SR procedure to generate pending SR and BSR for next PUCCH/PUSCH TxOp. This should implement the procedures
|
||||
// outlined in Sections 5.4.4 an 5.4.5 of 38.321
|
||||
mac->scheduling_info.SR_pending = 1;
|
||||
// Regular BSR trigger
|
||||
mac->BSR_reporting_active |= NR_BSR_TRIGGER_REGULAR;
|
||||
LOG_D(NR_MAC, "[UE %d][BSR] Regular BSR Triggered Frame %d slot %d SR for PUSCH is pending\n",
|
||||
mod_id, txFrameP, txSlotP);
|
||||
}
|
||||
return UE_CONNECTION_OK;
|
||||
|
||||
}
|
||||
|
||||
boolean_t
|
||||
nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_index) {
|
||||
mac_rlc_status_resp_t rlc_status;
|
||||
boolean_t bsr_regular_triggered = FALSE;
|
||||
uint8_t lcid;
|
||||
uint8_t lcgid;
|
||||
uint8_t num_lcid_with_data = 0; // for LCID with data only if LCGID is defined
|
||||
uint32_t lcgid_buffer_remain[NR_MAX_NUM_LCGID] = {0,0,0,0,0,0,0,0};
|
||||
int32_t lcid_bytes_in_buffer[NR_MAX_NUM_LCID];
|
||||
/* Array for ordering LCID with data per decreasing priority order */
|
||||
uint8_t lcid_reordered_array[NR_MAX_NUM_LCID]=
|
||||
{NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,
|
||||
NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,
|
||||
NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,
|
||||
NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,
|
||||
};
|
||||
uint8_t pos_next = 0;
|
||||
//uint8_t highest_priority = 16;
|
||||
uint8_t array_index = 0;
|
||||
// Reset All BSR Infos
|
||||
lcid_bytes_in_buffer[0] = 0;
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
|
||||
for (lcid=DCCH; lcid < NR_MAX_NUM_LCID; lcid++) {
|
||||
// Reset transmission status
|
||||
lcid_bytes_in_buffer[lcid] = 0;
|
||||
mac->scheduling_info.LCID_status[lcid]=LCID_EMPTY;
|
||||
}
|
||||
|
||||
for (lcgid=0; lcgid < NR_MAX_NUM_LCGID; lcgid++) {
|
||||
// Reset Buffer Info
|
||||
mac->scheduling_info.BSR[lcgid]=0;
|
||||
mac->scheduling_info.BSR_bytes[lcgid]=0;
|
||||
}
|
||||
|
||||
//Get Buffer Occupancy and fill lcid_reordered_array
|
||||
for (lcid=DCCH; lcid < NR_MAX_NUM_LCID; lcid++) {
|
||||
//if (mac->logicalChannelConfig[lcid]) {
|
||||
if (mac->logicalChannelBearer_exist[lcid] ) { // todo
|
||||
lcgid = mac->scheduling_info.LCGID[lcid];
|
||||
|
||||
// Store already available data to transmit per Group
|
||||
if (lcgid < NR_MAX_NUM_LCGID) {
|
||||
lcgid_buffer_remain[lcgid] += mac->scheduling_info.LCID_buffer_remain[lcid];
|
||||
}
|
||||
|
||||
rlc_status = mac_rlc_status_ind(module_idP, mac->crnti,gNB_index,frameP,slotP,ENB_FLAG_NO,MBMS_FLAG_NO, lcid, 0, 0);
|
||||
|
||||
lcid_bytes_in_buffer[lcid] = rlc_status.bytes_in_buffer;
|
||||
|
||||
if (rlc_status.bytes_in_buffer > 0) {
|
||||
LOG_D(NR_MAC,"[UE %d] PDCCH Tick : LCID%d LCGID%d has data to transmit =%d bytes at frame %d slot %d\n",
|
||||
module_idP, lcid,lcgid,rlc_status.bytes_in_buffer,frameP,slotP);
|
||||
mac->scheduling_info.LCID_status[lcid] = LCID_NOT_EMPTY;
|
||||
|
||||
//Update BSR_bytes and position in lcid_reordered_array only if Group is defined
|
||||
if (lcgid < NR_MAX_NUM_LCGID) {
|
||||
num_lcid_with_data ++;
|
||||
// sum lcid buffer which has same lcgid
|
||||
mac->scheduling_info.BSR_bytes[lcgid] += rlc_status.bytes_in_buffer;
|
||||
//Fill in the array
|
||||
array_index = 0;
|
||||
|
||||
do {
|
||||
//if (mac->logicalChannelConfig[lcid]->ul_SpecificParameters->priority <= highest_priority) {
|
||||
if (1) { // todo
|
||||
//Insert if priority is higher or equal (lower or equal in value)
|
||||
for (pos_next=num_lcid_with_data-1; pos_next > array_index; pos_next--) {
|
||||
lcid_reordered_array[pos_next] = lcid_reordered_array[pos_next - 1];
|
||||
}
|
||||
|
||||
lcid_reordered_array[array_index] = lcid;
|
||||
break;
|
||||
}
|
||||
|
||||
array_index ++;
|
||||
} while ((array_index < num_lcid_with_data) && (array_index < NR_MAX_NUM_LCID));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check whether a regular BSR can be triggered according to the first cases in 38.321
|
||||
if (num_lcid_with_data) {
|
||||
LOG_D(NR_MAC, "[UE %d] PDCCH Tick at frame %d slot %d: NumLCID with data=%d Reordered LCID0=%d LCID1=%d LCID2=%d\n",
|
||||
module_idP, frameP, slotP, num_lcid_with_data,
|
||||
lcid_reordered_array[0], lcid_reordered_array[1],
|
||||
lcid_reordered_array[2]);
|
||||
|
||||
for (array_index = 0; array_index < num_lcid_with_data; array_index++) {
|
||||
lcid = lcid_reordered_array[array_index];
|
||||
|
||||
/* UL data, for a logical channel which belongs to a LCG, becomes available for transmission in the RLC entity
|
||||
either the data belongs to a logical channel with higher priority than the priorities of the logical channels
|
||||
which belong to any LCG and for which data is already available for transmission
|
||||
*/
|
||||
{
|
||||
bsr_regular_triggered = TRUE;
|
||||
LOG_D(NR_MAC, "[UE %d] PDCCH Tick : MAC BSR Triggered LCID%d LCGID%d data become available at frame %d slot %d\n",
|
||||
module_idP, lcid,
|
||||
mac->scheduling_info.LCGID[lcid],
|
||||
frameP, slotP);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger Regular BSR if ReTxBSR Timer has expired and UE has data for transmission
|
||||
if (mac->scheduling_info.retxBSR_SF == 0) {
|
||||
bsr_regular_triggered = TRUE;
|
||||
|
||||
if ((mac->BSR_reporting_active & NR_BSR_TRIGGER_REGULAR) == 0) {
|
||||
LOG_I(NR_MAC, "[UE %d] PDCCH Tick : MAC BSR Triggered ReTxBSR Timer expiry at frame %d slot %d\n",
|
||||
module_idP, frameP, slotP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Store Buffer Occupancy in remain buffers for next TTI
|
||||
for (lcid = DCCH; lcid < NR_MAX_NUM_LCID; lcid++) {
|
||||
mac->scheduling_info.LCID_buffer_remain[lcid] = lcid_bytes_in_buffer[lcid];
|
||||
}
|
||||
|
||||
return bsr_regular_triggered;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
nr_locate_BsrIndexByBufferSize(const uint32_t *table, int size, int value) {
|
||||
uint8_t ju, jm, jl;
|
||||
int ascend;
|
||||
//DevAssert(size > 0);
|
||||
//DevAssert(size <= 256);
|
||||
|
||||
if (value == 0) {
|
||||
return 0; //elseif (value > 150000) return 63;
|
||||
}
|
||||
|
||||
jl = 0; // lower bound
|
||||
ju = size - 1; // upper bound
|
||||
ascend = (table[ju] >= table[jl]) ? 1 : 0; // determine the order of the the table: 1 if ascending order of table, 0 otherwise
|
||||
|
||||
while (ju - jl > 1) { //If we are not yet done,
|
||||
jm = (ju + jl) >> 1; //compute a midpoint,
|
||||
|
||||
if ((value >= table[jm]) == ascend) {
|
||||
jl = jm; // replace the lower limit
|
||||
} else {
|
||||
ju = jm; //replace the upper limit
|
||||
}
|
||||
|
||||
LOG_T(NR_MAC, "[UE] searching BSR index %d for (BSR TABLE %d < value %d)\n",
|
||||
jm, table[jm], value);
|
||||
}
|
||||
|
||||
if (value == table[jl]) {
|
||||
return jl;
|
||||
} else {
|
||||
return jl + 1; //equally ju
|
||||
}
|
||||
}
|
||||
|
||||
int nr_get_sf_periodicBSRTimer(uint8_t sf_offset) {
|
||||
switch (sf_offset) {
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf1:
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf5:
|
||||
return 5;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf10:
|
||||
return 10;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf16:
|
||||
return 16;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf20:
|
||||
return 20;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf32:
|
||||
return 32;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf40:
|
||||
return 40;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf64:
|
||||
return 64;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf80:
|
||||
return 80;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf128:
|
||||
return 128;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf160:
|
||||
return 160;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf320:
|
||||
return 320;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf640:
|
||||
return 640;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf1280:
|
||||
return 1280;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf2560:
|
||||
return 2560;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_infinity:
|
||||
default:
|
||||
return 0xFFFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int nr_get_sf_retxBSRTimer(uint8_t sf_offset) {
|
||||
switch (sf_offset) {
|
||||
case NR_BSR_Config__retxBSR_Timer_sf10:
|
||||
return 10;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__retxBSR_Timer_sf20:
|
||||
return 20;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__retxBSR_Timer_sf40:
|
||||
return 40;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__retxBSR_Timer_sf80:
|
||||
return 80;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__retxBSR_Timer_sf160:
|
||||
return 160;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__retxBSR_Timer_sf320:
|
||||
return 320;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__retxBSR_Timer_sf640:
|
||||
return 640;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__retxBSR_Timer_sf1280:
|
||||
return 1280;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__retxBSR_Timer_sf2560:
|
||||
return 2560;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__retxBSR_Timer_sf5120:
|
||||
return 5120;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__retxBSR_Timer_sf10240:
|
||||
return 10240;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// PUSCH scheduler:
|
||||
// - Calculate the slot in which ULSCH should be scheduled. This is current slot + K2,
|
||||
// - where K2 is the offset between the slot in which UL DCI is received and the slot
|
||||
@@ -2053,6 +2382,261 @@ void nr_ue_sib1_scheduler(module_id_t module_idP,
|
||||
|
||||
|
||||
#define MAX_LCID 8 // NR_MAX_NUM_LCID shall be used but the mac_rlc_data_req function can fetch data for max 8 LCID
|
||||
typedef struct {
|
||||
uint8_t bsr_len;
|
||||
uint8_t bsr_ce_len;
|
||||
uint8_t bsr_header_len;
|
||||
uint8_t phr_len;
|
||||
uint8_t phr_ce_len;
|
||||
uint8_t phr_header_len;
|
||||
uint16_t sdu_length_total;
|
||||
NR_BSR_SHORT *bsr_s;
|
||||
NR_BSR_LONG *bsr_l;
|
||||
NR_BSR_SHORT *bsr_t;
|
||||
//NR_POWER_HEADROOM_CMD *phr_pr;
|
||||
int tot_mac_ce_len;
|
||||
uint8_t total_mac_pdu_header_len;
|
||||
} NR_UE_MAC_CE_INFO;
|
||||
|
||||
/*
|
||||
nr_ue_get_sdu_mac_ce_pre finds length in various mac_ce field
|
||||
Need nothing from mac_ce_p:
|
||||
Update the following in mac_ce_p:
|
||||
bsr_len;
|
||||
bsr_ce_len;
|
||||
bsr_header_len;
|
||||
phr_len; TBD
|
||||
phr_ce_len; TBD
|
||||
phr_header_len; TBD
|
||||
*/
|
||||
int nr_ue_get_sdu_mac_ce_pre(module_id_t module_idP,
|
||||
int CC_id,
|
||||
frame_t frameP,
|
||||
sub_frame_t subframe,
|
||||
uint8_t gNB_index,
|
||||
uint8_t *ulsch_buffer,
|
||||
uint16_t buflen,
|
||||
NR_UE_MAC_CE_INFO *mac_ce_p) {
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
|
||||
|
||||
int num_lcg_id_with_data = 0;
|
||||
// Preparing the MAC CEs sub-PDUs and get the total size
|
||||
mac_ce_p->bsr_header_len = 0;
|
||||
mac_ce_p->phr_header_len = 0; //sizeof(SCH_SUBHEADER_FIXED);
|
||||
int lcg_id = 0;
|
||||
while (lcg_id < NR_MAX_NUM_LCGID) {
|
||||
if (mac->scheduling_info.BSR_bytes[lcg_id]) {
|
||||
num_lcg_id_with_data++;
|
||||
}
|
||||
|
||||
lcg_id++;
|
||||
}
|
||||
|
||||
//Restart ReTxBSR Timer at new grant indication (38.321)
|
||||
if (mac->scheduling_info.retxBSR_SF != MAC_UE_BSR_TIMER_NOT_RUNNING) {
|
||||
mac->scheduling_info.retxBSR_SF = nr_get_sf_retxBSRTimer(mac->scheduling_info.retxBSR_Timer);
|
||||
}
|
||||
|
||||
// periodicBSR-Timer expires, trigger BSR
|
||||
if ((mac->scheduling_info.periodicBSR_Timer != NR_BSR_Config__periodicBSR_Timer_infinity)
|
||||
&& (mac->scheduling_info.periodicBSR_SF == 0)) {
|
||||
// Trigger BSR Periodic
|
||||
mac->BSR_reporting_active |= NR_BSR_TRIGGER_PERIODIC;
|
||||
LOG_D(NR_MAC, "[UE %d] MAC BSR Triggered PeriodicBSR Timer expiry at frame%d subframe %d TBS=%d\n",
|
||||
module_idP, frameP, subframe, buflen);
|
||||
}
|
||||
|
||||
//Compute BSR Length if Regular or Periodic BSR is triggered
|
||||
//WARNING: if BSR long is computed, it may be changed to BSR short during or after multiplexing if there remains less than 1 LCGROUP with data after Tx
|
||||
if (mac->BSR_reporting_active) {
|
||||
AssertFatal((mac->BSR_reporting_active & NR_BSR_TRIGGER_PADDING) == 0,
|
||||
"Inconsistent BSR Trigger=%d !\n",
|
||||
mac->BSR_reporting_active);
|
||||
|
||||
//A Regular or Periodic BSR can only be sent if TBS is sufficient as transmitting only a BSR is not allowed if UE has data to transmit
|
||||
if (num_lcg_id_with_data <= 1) {
|
||||
if (buflen >= (sizeof(NR_BSR_SHORT)+sizeof(NR_MAC_SUBHEADER_FIXED)+1)) {
|
||||
mac_ce_p->bsr_ce_len = sizeof(NR_BSR_SHORT); //1 byte
|
||||
mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_FIXED); //1 byte
|
||||
}
|
||||
} else {
|
||||
if (buflen >= (num_lcg_id_with_data+1+sizeof(NR_MAC_SUBHEADER_SHORT)+1)) {
|
||||
mac_ce_p->bsr_ce_len = num_lcg_id_with_data + 1; //variable size
|
||||
mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_SHORT); //2 bytes
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mac_ce_p->bsr_len = mac_ce_p->bsr_ce_len + mac_ce_p->bsr_header_len;
|
||||
return (mac_ce_p->bsr_len + mac_ce_p->phr_len);
|
||||
}
|
||||
|
||||
/*
|
||||
nr_ue_get_sdu_mac_ce_post recalculates length and prepares the mac_ce field
|
||||
Need the following from mac_ce_p:
|
||||
bsr_ce_len
|
||||
bsr_len
|
||||
sdu_length_total
|
||||
total_mac_pdu_header_len
|
||||
Update the following in mac_ce_p:
|
||||
bsr_ce_len
|
||||
bsr_header_len
|
||||
bsr_len
|
||||
tot_mac_ce_len
|
||||
total_mac_pdu_header_len
|
||||
bsr_s
|
||||
bsr_l
|
||||
bsr_t
|
||||
*/
|
||||
void nr_ue_get_sdu_mac_ce_post(module_id_t module_idP,
|
||||
int CC_id,
|
||||
frame_t frameP,
|
||||
sub_frame_t subframe,
|
||||
uint8_t gNB_index,
|
||||
uint8_t *ulsch_buffer,
|
||||
uint16_t buflen,
|
||||
NR_UE_MAC_CE_INFO *mac_ce_p) {
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
|
||||
|
||||
// Compute BSR Values and update Nb LCGID with data after multiplexing
|
||||
unsigned short padding_len = 0;
|
||||
uint8_t lcid = 0;
|
||||
int lcg_id = 0;
|
||||
int num_lcg_id_with_data = 0;
|
||||
int lcg_id_bsr_trunc = 0;
|
||||
for (lcg_id = 0; lcg_id < NR_MAX_NUM_LCGID; lcg_id++) {
|
||||
if (mac_ce_p->bsr_ce_len == sizeof(NR_BSR_SHORT)) {
|
||||
mac->scheduling_info.BSR[lcg_id] = nr_locate_BsrIndexByBufferSize(NR_SHORT_BSR_TABLE, NR_SHORT_BSR_TABLE_SIZE, mac->scheduling_info.BSR_bytes[lcg_id]);
|
||||
} else {
|
||||
mac->scheduling_info.BSR[lcg_id] = nr_locate_BsrIndexByBufferSize(NR_LONG_BSR_TABLE, NR_LONG_BSR_TABLE_SIZE, mac->scheduling_info.BSR_bytes[lcg_id]);
|
||||
}
|
||||
if (mac->scheduling_info.BSR_bytes[lcg_id]) {
|
||||
num_lcg_id_with_data++;
|
||||
lcg_id_bsr_trunc = lcg_id;
|
||||
}
|
||||
}
|
||||
|
||||
// TS 38.321 Section 5.4.5
|
||||
// Check BSR padding: it is done after PHR according to Logical Channel Prioritization order
|
||||
// Check for max padding size, ie MAC Hdr for last RLC PDU = 1
|
||||
/* For Padding BSR:
|
||||
- if the number of padding bits is equal to or larger than the size of the Short BSR plus its subheader but smaller than the size of the Long BSR plus its subheader:
|
||||
- if more than one LCG has data available for transmission in the TTI where the BSR is transmitted: report Truncated BSR of the LCG with the highest priority logical channel with data available for transmission;
|
||||
- else report Short BSR.
|
||||
- else if the number of padding bits is equal to or larger than the size of the Long BSR plus its subheader, report Long BSR.
|
||||
*/
|
||||
if (mac_ce_p->sdu_length_total) {
|
||||
padding_len = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total);
|
||||
}
|
||||
|
||||
if ((padding_len) && (mac_ce_p->bsr_len == 0)) {
|
||||
/* if the number of padding bits is equal to or larger than the size of the Long BSR plus its subheader, report Long BSR */
|
||||
if (padding_len >= (num_lcg_id_with_data+1+sizeof(NR_MAC_SUBHEADER_SHORT))) {
|
||||
mac_ce_p->bsr_ce_len = num_lcg_id_with_data + 1; //variable size
|
||||
mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_SHORT); //2 bytes
|
||||
// Trigger BSR Padding
|
||||
mac->BSR_reporting_active |= NR_BSR_TRIGGER_PADDING;
|
||||
} else if (padding_len >= (sizeof(NR_BSR_SHORT)+sizeof(NR_MAC_SUBHEADER_FIXED))) {
|
||||
mac_ce_p->bsr_ce_len = sizeof(NR_BSR_SHORT); //1 byte
|
||||
mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_FIXED); //1 byte
|
||||
|
||||
if (num_lcg_id_with_data > 1) {
|
||||
// REPORT SHORT TRUNCATED BSR
|
||||
//Get LCGID of highest priority LCID with data (todo)
|
||||
for (lcid = DCCH; lcid < NR_MAX_NUM_LCID; lcid++) {
|
||||
lcg_id = mac->scheduling_info.LCGID[lcid];
|
||||
if ((lcg_id < NR_MAX_NUM_LCGID) && (mac->scheduling_info.BSR_bytes[lcg_id])) {
|
||||
lcg_id_bsr_trunc = lcg_id;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//Report SHORT BSR, clear bsr_t
|
||||
mac_ce_p->bsr_t = NULL;
|
||||
}
|
||||
|
||||
// Trigger BSR Padding
|
||||
mac->BSR_reporting_active |= NR_BSR_TRIGGER_PADDING;
|
||||
}
|
||||
|
||||
mac_ce_p->bsr_len = mac_ce_p->bsr_header_len + mac_ce_p->bsr_ce_len;
|
||||
mac_ce_p->tot_mac_ce_len += mac_ce_p->bsr_len;
|
||||
mac_ce_p->total_mac_pdu_header_len += mac_ce_p->bsr_len;
|
||||
}
|
||||
|
||||
//Fill BSR Infos
|
||||
if (mac_ce_p->bsr_ce_len == 0) {
|
||||
mac_ce_p->bsr_s = NULL;
|
||||
mac_ce_p->bsr_l = NULL;
|
||||
mac_ce_p->bsr_t = NULL;
|
||||
} else if (mac_ce_p->bsr_header_len == sizeof(NR_MAC_SUBHEADER_SHORT)) {
|
||||
mac_ce_p->bsr_s = NULL;
|
||||
mac_ce_p->bsr_t = NULL;
|
||||
mac_ce_p->bsr_l->Buffer_size0 = mac->scheduling_info.BSR[0];
|
||||
mac_ce_p->bsr_l->Buffer_size1 = mac->scheduling_info.BSR[1];
|
||||
mac_ce_p->bsr_l->Buffer_size2 = mac->scheduling_info.BSR[2];
|
||||
mac_ce_p->bsr_l->Buffer_size3 = mac->scheduling_info.BSR[3];
|
||||
mac_ce_p->bsr_l->Buffer_size4 = mac->scheduling_info.BSR[4];
|
||||
mac_ce_p->bsr_l->Buffer_size5 = mac->scheduling_info.BSR[5];
|
||||
mac_ce_p->bsr_l->Buffer_size6 = mac->scheduling_info.BSR[6];
|
||||
mac_ce_p->bsr_l->Buffer_size7 = mac->scheduling_info.BSR[7];
|
||||
LOG_D(NR_MAC, "[UE %d] Frame %d subframe %d BSR Trig=%d report LONG BSR (level LCGID0 %d,level LCGID1 %d,level LCGID2 %d,level LCGID3 %d level LCGID4 %d,level LCGID5 %d,level LCGID6 %d,level LCGID7 %d)\n",
|
||||
module_idP, frameP, subframe,
|
||||
mac->BSR_reporting_active,
|
||||
mac->scheduling_info.BSR[0],
|
||||
mac->scheduling_info.BSR[1],
|
||||
mac->scheduling_info.BSR[2],
|
||||
mac->scheduling_info.BSR[3],
|
||||
mac->scheduling_info.BSR[4],
|
||||
mac->scheduling_info.BSR[5],
|
||||
mac->scheduling_info.BSR[6],
|
||||
mac->scheduling_info.BSR[7]);
|
||||
} else if (mac_ce_p->bsr_header_len == sizeof(NR_MAC_SUBHEADER_FIXED)) {
|
||||
mac_ce_p->bsr_l = NULL;
|
||||
|
||||
if ((mac_ce_p->bsr_t != NULL) && (mac->BSR_reporting_active & NR_BSR_TRIGGER_PADDING)) {
|
||||
//Truncated BSR
|
||||
mac_ce_p->bsr_s = NULL;
|
||||
mac_ce_p->bsr_t->LcgID = lcg_id_bsr_trunc;
|
||||
mac_ce_p->bsr_t->Buffer_size = mac->scheduling_info.BSR[lcg_id_bsr_trunc];
|
||||
LOG_D(NR_MAC, "[UE %d] Frame %d subframe %d BSR Trig=%d report TRUNCATED BSR with level %d for LCGID %d\n",
|
||||
module_idP, frameP, subframe,
|
||||
mac->BSR_reporting_active,
|
||||
mac->scheduling_info.BSR[lcg_id_bsr_trunc], lcg_id_bsr_trunc);
|
||||
} else {
|
||||
mac_ce_p->bsr_t = NULL;
|
||||
mac_ce_p->bsr_s->LcgID = lcg_id_bsr_trunc;
|
||||
mac_ce_p->bsr_s->Buffer_size = mac->scheduling_info.BSR[lcg_id_bsr_trunc];
|
||||
LOG_D(NR_MAC, "[UE %d] Frame %d subframe %d BSR Trig=%d report SHORT BSR with level %d for LCGID %d\n",
|
||||
module_idP, frameP, subframe,
|
||||
mac->BSR_reporting_active,
|
||||
mac->scheduling_info.BSR[lcg_id_bsr_trunc], lcg_id_bsr_trunc);
|
||||
}
|
||||
}
|
||||
|
||||
LOG_D(NR_MAC, "[UE %d][SR] Gave SDU to PHY, clearing any scheduling request\n", module_idP);
|
||||
mac->scheduling_info.SR_pending = 0;
|
||||
mac->scheduling_info.SR_COUNTER = 0;
|
||||
|
||||
/* Actions when a BSR is sent */
|
||||
if (mac_ce_p->bsr_ce_len) {
|
||||
LOG_D(NR_MAC, "[UE %d] MAC BSR Sent !! bsr (ce%d,hdr%d) buff_len %d\n",
|
||||
module_idP, mac_ce_p->bsr_ce_len, mac_ce_p->bsr_header_len, buflen);
|
||||
// Reset ReTx BSR Timer
|
||||
mac->scheduling_info.retxBSR_SF = nr_get_sf_retxBSRTimer(mac->scheduling_info.retxBSR_Timer);
|
||||
LOG_D(NR_MAC, "[UE %d] MAC ReTx BSR Timer Reset =%d\n", module_idP, mac->scheduling_info.retxBSR_SF);
|
||||
|
||||
// Reset Periodic Timer except when BSR is truncated
|
||||
if ((mac_ce_p->bsr_t == NULL) && (mac->scheduling_info.periodicBSR_Timer != NR_BSR_Config__periodicBSR_Timer_infinity)) {
|
||||
mac->scheduling_info.periodicBSR_SF = nr_get_sf_periodicBSRTimer(mac->scheduling_info.periodicBSR_Timer);
|
||||
LOG_D(NR_MAC, "[UE %d] MAC Periodic BSR Timer Reset =%d\n",
|
||||
module_idP,
|
||||
mac->scheduling_info.periodicBSR_SF);
|
||||
}
|
||||
|
||||
// Reset BSR Trigger flags
|
||||
mac->BSR_reporting_active = BSR_TRIGGER_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function: to fetch data to be transmitted from RLC, place it in the ULSCH PDU buffer
|
||||
@@ -2073,31 +2657,45 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
|
||||
uint8_t gNB_index,
|
||||
uint8_t *ulsch_buffer,
|
||||
uint16_t buflen) {
|
||||
|
||||
NR_UE_MAC_CE_INFO mac_ce_info;
|
||||
NR_UE_MAC_CE_INFO *mac_ce_p=&mac_ce_info;
|
||||
int16_t buflen_remain = 0;
|
||||
mac_ce_p->bsr_len = 0;
|
||||
mac_ce_p->bsr_ce_len = 0;
|
||||
mac_ce_p->bsr_header_len = 0;
|
||||
mac_ce_p->phr_len = 0;
|
||||
//mac_ce_p->phr_ce_len = 0;
|
||||
//mac_ce_p->phr_header_len = 0;
|
||||
|
||||
uint8_t lcid = 0;
|
||||
uint16_t sdu_length = 0;
|
||||
uint16_t num_sdus = 0;
|
||||
uint16_t sdu_length_total = 0;
|
||||
mac_ce_p->sdu_length_total = 0;
|
||||
NR_BSR_SHORT bsr_short, bsr_truncated;
|
||||
NR_BSR_LONG bsr_long;
|
||||
mac_ce_p->bsr_s = &bsr_short;
|
||||
mac_ce_p->bsr_l = &bsr_long;
|
||||
mac_ce_p->bsr_t = &bsr_truncated;
|
||||
//NR_POWER_HEADROOM_CMD phr;
|
||||
//mac_ce_p->phr_p = &phr;
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
|
||||
//int highest_priority = 16;
|
||||
const uint8_t sh_size = sizeof(NR_MAC_SUBHEADER_LONG);
|
||||
|
||||
// Pointer used to build the MAC PDU by placing the RLC SDUs in the ULSCH buffer
|
||||
uint8_t *pdu = ulsch_buffer;
|
||||
|
||||
// Preparing the MAC CEs sub-PDUs and get the total size
|
||||
unsigned char mac_header_control_elements[16] = {0};
|
||||
int tot_mac_ce_len = nr_write_ce_ulsch_pdu(&mac_header_control_elements[0], mac);
|
||||
uint8_t total_mac_pdu_header_len = tot_mac_ce_len;
|
||||
//nr_ue_get_sdu_mac_ce_pre updates all mac_ce related header field related to length
|
||||
mac_ce_p->tot_mac_ce_len = nr_ue_get_sdu_mac_ce_pre(module_idP, CC_id, frameP, subframe, gNB_index, ulsch_buffer, buflen, mac_ce_p);
|
||||
mac_ce_p->total_mac_pdu_header_len = mac_ce_p->tot_mac_ce_len;
|
||||
|
||||
LOG_D(NR_MAC, "In %s: [UE %d] [%d.%d] process UL transport block at with size TBS = %d bytes \n", __FUNCTION__, module_idP, frameP, subframe, buflen);
|
||||
|
||||
// Check for DCCH first
|
||||
// TO DO: Multiplex in the order defined by the logical channel prioritization
|
||||
for (lcid = UL_SCH_LCID_SRB1;
|
||||
lcid < MAX_LCID; lcid++) {
|
||||
for (lcid = UL_SCH_LCID_SRB1; lcid < MAX_LCID; lcid++) {
|
||||
|
||||
buflen_remain = buflen - (total_mac_pdu_header_len + sdu_length_total + sh_size);
|
||||
buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total + sh_size);
|
||||
|
||||
LOG_D(NR_MAC, "In %s: [UE %d] [%d.%d] UL-DXCH -> ULSCH, RLC with LCID 0x%02x (TBS %d bytes, sdu_length_total %d bytes, MAC header len %d bytes, buflen_remain %d bytes)\n",
|
||||
__FUNCTION__,
|
||||
@@ -2106,8 +2704,8 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
|
||||
subframe,
|
||||
lcid,
|
||||
buflen,
|
||||
sdu_length_total,
|
||||
tot_mac_ce_len,
|
||||
mac_ce_p->sdu_length_total,
|
||||
mac_ce_p->tot_mac_ce_len,
|
||||
buflen_remain);
|
||||
|
||||
while (buflen_remain > 0){
|
||||
@@ -2137,7 +2735,7 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
|
||||
|
||||
if (sdu_length > 0) {
|
||||
|
||||
LOG_D(MAC, "In %s: Generating UL MAC sub-PDU for SDU %d, length %d bytes, RB with LCID 0x%02x (buflen (TBS) %d bytes)\n", __FUNCTION__,
|
||||
LOG_D(NR_MAC, "In %s: Generating UL MAC sub-PDU for SDU %d, length %d bytes, RB with LCID 0x%02x (buflen (TBS) %d bytes)\n", __FUNCTION__,
|
||||
num_sdus + 1,
|
||||
sdu_length,
|
||||
lcid,
|
||||
@@ -2157,40 +2755,53 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
|
||||
#endif
|
||||
|
||||
pdu += sdu_length;
|
||||
sdu_length_total += sdu_length;
|
||||
total_mac_pdu_header_len += sh_size;
|
||||
mac_ce_p->sdu_length_total += sdu_length;
|
||||
mac_ce_p->total_mac_pdu_header_len += sh_size;
|
||||
|
||||
num_sdus++;
|
||||
|
||||
} else {
|
||||
pdu -= sh_size;
|
||||
LOG_D(MAC, "In %s: no data to transmit for RB with LCID 0x%02x\n", __FUNCTION__, lcid);
|
||||
LOG_D(NR_MAC, "In %s: no data to transmit for RB with LCID 0x%02x\n", __FUNCTION__, lcid);
|
||||
break;
|
||||
}
|
||||
|
||||
buflen_remain = buflen - (total_mac_pdu_header_len + sdu_length_total + sh_size);
|
||||
buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total + sh_size);
|
||||
|
||||
//Update Buffer remain and BSR bytes after transmission
|
||||
mac->scheduling_info.LCID_buffer_remain[lcid] -= sdu_length;
|
||||
mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]] -= sdu_length;
|
||||
LOG_D(NR_MAC, "[UE %d] Update BSR [%d.%d] BSR_bytes for LCG%d=%d\n",
|
||||
module_idP, frameP, subframe, mac->scheduling_info.LCGID[lcid],
|
||||
mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]]);
|
||||
if (mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]] < 0)
|
||||
mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (tot_mac_ce_len > 0) {
|
||||
//nr_ue_get_sdu_mac_ce_post recalculates all mac_ce related header fields since buffer has been changed after mac_rlc_data_req.
|
||||
//Also, BSR padding is handled here after knowing mac_ce_p->sdu_length_total.
|
||||
nr_ue_get_sdu_mac_ce_post(module_idP, CC_id, frameP, subframe, gNB_index, ulsch_buffer, buflen, mac_ce_p);
|
||||
|
||||
LOG_D(NR_MAC, "In %s copying %d bytes of MAC CEs to the UL PDU \n", __FUNCTION__, tot_mac_ce_len);
|
||||
memcpy((void *) pdu, (void *) mac_header_control_elements, tot_mac_ce_len);
|
||||
pdu += (unsigned char) tot_mac_ce_len;
|
||||
if (mac_ce_p->tot_mac_ce_len > 0) {
|
||||
|
||||
LOG_D(NR_MAC, "In %s copying %d bytes of MAC CEs to the UL PDU \n", __FUNCTION__, mac_ce_p->tot_mac_ce_len);
|
||||
nr_write_ce_ulsch_pdu(pdu, mac, 0, NULL, mac_ce_p->bsr_t, mac_ce_p->bsr_s, mac_ce_p->bsr_l);
|
||||
pdu += (unsigned char) mac_ce_p->tot_mac_ce_len;
|
||||
|
||||
#ifdef ENABLE_MAC_PAYLOAD_DEBUG
|
||||
LOG_I(NR_MAC, "In %s: dumping MAC CE with length tot_mac_ce_len %d: \n", __FUNCTION__, tot_mac_ce_len);
|
||||
log_dump(NR_MAC, mac_header_control_elements, tot_mac_ce_len, LOG_DUMP_CHAR, "\n");
|
||||
LOG_I(NR_MAC, "In %s: dumping MAC CE with length tot_mac_ce_len %d: \n", __FUNCTION__, mac_ce_p->tot_mac_ce_len);
|
||||
log_dump(NR_MAC, mac_header_control_elements, mac_ce_p->tot_mac_ce_len, LOG_DUMP_CHAR, "\n");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
buflen_remain = buflen - (total_mac_pdu_header_len + sdu_length_total);
|
||||
buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total);
|
||||
|
||||
// Compute final offset for padding and fill remainder of ULSCH with 0
|
||||
if (buflen_remain > 0) {
|
||||
|
||||
LOG_D(NR_MAC, "In %s filling remainder %d bytes to the UL PDU \n", __FUNCTION__, buflen_remain);
|
||||
((NR_MAC_SUBHEADER_FIXED *) pdu)->R = 0;
|
||||
((NR_MAC_SUBHEADER_FIXED *) pdu)->LCID = UL_SCH_LCID_PADDING;
|
||||
|
||||
|
||||
@@ -261,6 +261,8 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
|
||||
else
|
||||
mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||
|
||||
int bwp_start = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
|
||||
uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value;
|
||||
// prach is scheduled according to configuration index and tables 6.3.3.2.2 to 6.3.3.2.4
|
||||
if ( get_nr_prach_info_from_index(config_index,
|
||||
@@ -387,7 +389,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
|
||||
const int16_t N_RA_RB = get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing.value, mu_pusch);
|
||||
uint16_t *vrb_map_UL = &cc->vrb_map_UL[slotP * MAX_BWP_SIZE];
|
||||
for (int i = 0; i < N_RA_RB * fdm; ++i)
|
||||
vrb_map_UL[rach_ConfigGeneric->msg1_FrequencyStart + i] = 0xff; // all symbols
|
||||
vrb_map_UL[bwp_start + rach_ConfigGeneric->msg1_FrequencyStart + i] = 0xff; // all symbols
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -772,7 +774,6 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t
|
||||
|
||||
// generation of DCI 0_0 to schedule msg3 retransmission
|
||||
NR_SearchSpace_t *ss = ra->ra_ss;
|
||||
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = *ss->controlResourceSetId==0 ? &nr_mac->type0_PDCCH_CSS_config[ra->beam_id] : NULL;
|
||||
NR_ControlResourceSet_t *coreset = get_coreset(module_idP, scc, NULL, ss, NR_SearchSpace__searchSpaceType_PR_common);
|
||||
AssertFatal(coreset!=NULL,"Coreset cannot be null for RA-Msg3 retransmission\n");
|
||||
|
||||
@@ -787,7 +788,7 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t
|
||||
ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
|
||||
pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15;
|
||||
ul_dci_req->numPdus += 1;
|
||||
nr_configure_pdcch(pdcch_pdu_rel15, ss, coreset, scc, genericParameters, type0_PDCCH_CSS_config);
|
||||
nr_configure_pdcch(nr_mac, pdcch_pdu_rel15, ss, coreset, scc, genericParameters, NULL);
|
||||
nr_mac->pdcch_pdu_idx[CC_id][ra->bwp_id][coresetid] = pdcch_pdu_rel15;
|
||||
}
|
||||
|
||||
@@ -917,10 +918,19 @@ void nr_get_Msg3alloc(module_id_t module_id,
|
||||
LOG_D(NR_MAC, "[RAPROC] Msg3 slot %d: current slot %u Msg3 frame %u k2 %u Msg3_tda_id %u start symbol index %u\n", ra->Msg3_slot, current_slot, ra->Msg3_frame, k2,ra->Msg3_tda_id, StartSymbolIndex);
|
||||
uint16_t *vrb_map_UL =
|
||||
&RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[ra->Msg3_slot * MAX_BWP_SIZE];
|
||||
const uint16_t bwpSize = NRRIV2BW(ubwp ?
|
||||
ubwp->bwp_Common->genericParameters.locationAndBandwidth :
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,
|
||||
MAX_BWP_SIZE);
|
||||
|
||||
int bwpSize = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
int bwpStart = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
|
||||
if (ra->CellGroup) {
|
||||
AssertFatal(ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
|
||||
"downlinkBWP_ToAddModList has %d BWP!\n", ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
|
||||
NR_BWP_Uplink_t *ubwp = ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id - 1];
|
||||
int act_bwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
int act_bwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
if (!((bwpStart >= act_bwp_start) && ((bwpStart+bwpSize) <= (act_bwp_start+act_bwp_size))))
|
||||
bwpStart = act_bwp_start;
|
||||
}
|
||||
|
||||
/* search msg3_nb_rb free RBs */
|
||||
int rbSize = 0;
|
||||
@@ -928,16 +938,17 @@ void nr_get_Msg3alloc(module_id_t module_id,
|
||||
while (rbSize < msg3_nb_rb) {
|
||||
rbStart += rbSize; /* last iteration rbSize was not enough, skip it */
|
||||
rbSize = 0;
|
||||
while (rbStart < bwpSize && vrb_map_UL[rbStart])
|
||||
while (rbStart < bwpSize && vrb_map_UL[rbStart + bwpStart])
|
||||
rbStart++;
|
||||
AssertFatal(rbStart < bwpSize - msg3_nb_rb, "no space to allocate Msg 3 for RA!\n");
|
||||
while (rbStart + rbSize < bwpSize
|
||||
&& !vrb_map_UL[rbStart + rbSize]
|
||||
&& !vrb_map_UL[rbStart + bwpStart + rbSize]
|
||||
&& rbSize < msg3_nb_rb)
|
||||
rbSize++;
|
||||
}
|
||||
ra->msg3_nb_rb = msg3_nb_rb;
|
||||
ra->msg3_first_rb = rbStart;
|
||||
ra->msg3_bwp_start = bwpStart;
|
||||
}
|
||||
|
||||
|
||||
@@ -1023,12 +1034,12 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
|
||||
uint16_t *vrb_map_UL =
|
||||
&RC.nrmac[module_idP]->common_channels[CC_id].vrb_map_UL[ra->Msg3_slot * MAX_BWP_SIZE];
|
||||
for (int i = 0; i < ra->msg3_nb_rb; ++i) {
|
||||
AssertFatal(!vrb_map_UL[i + ra->msg3_first_rb],
|
||||
AssertFatal(!vrb_map_UL[i + ra->msg3_first_rb + ra->msg3_bwp_start],
|
||||
"RB %d in %4d.%2d is already taken, cannot allocate Msg3!\n",
|
||||
i + ra->msg3_first_rb,
|
||||
ra->Msg3_frame,
|
||||
ra->Msg3_slot);
|
||||
vrb_map_UL[i + ra->msg3_first_rb] = 1;
|
||||
vrb_map_UL[i + ra->msg3_first_rb + ra->msg3_bwp_start] = 1;
|
||||
}
|
||||
|
||||
LOG_D(NR_MAC, "[gNB %d][RAPROC] Frame %d, Slot %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot);
|
||||
@@ -1047,9 +1058,6 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
|
||||
memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t));
|
||||
|
||||
int ibwp_size = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
int ibwp_start = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
int abwp_size = ibwp_size;
|
||||
int abwp_start = ibwp_start;
|
||||
int scs = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
|
||||
int fh = 0;
|
||||
int startSymbolAndLength = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength;
|
||||
@@ -1062,8 +1070,6 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
|
||||
|
||||
startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength;
|
||||
mappingtype = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->mappingType;
|
||||
abwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
abwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
scs = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
|
||||
fh = ubwp->bwp_Dedicated->pusch_Config->choice.setup->frequencyHopping ? 1 : 0;
|
||||
}
|
||||
@@ -1078,17 +1084,11 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
|
||||
ra->msg3_round,
|
||||
ra->rnti);
|
||||
|
||||
int bwp_start;
|
||||
if ((ibwp_start < abwp_start) || (ibwp_size > abwp_size))
|
||||
bwp_start = abwp_start;
|
||||
else
|
||||
bwp_start = ibwp_start;
|
||||
|
||||
fill_msg3_pusch_pdu(pusch_pdu,scc,
|
||||
ra->msg3_round,
|
||||
startSymbolAndLength,
|
||||
ra->rnti, scs,
|
||||
ibwp_size, bwp_start,
|
||||
ibwp_size, ra->msg3_bwp_start,
|
||||
mappingtype, fh,
|
||||
ra->msg3_first_rb, ra->msg3_nb_rb);
|
||||
future_ul_tti_req->n_pdus += 1;
|
||||
@@ -1150,7 +1150,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
|
||||
uint16_t *vrb_map = cc[CC_id].vrb_map;
|
||||
for (int i = 0; (i < rbSize) && (rbStart <= (BWPSize - rbSize)); i++) {
|
||||
if (vrb_map[rbStart + i]) {
|
||||
if (vrb_map[BWPStart + rbStart + i]) {
|
||||
rbStart += i;
|
||||
i = 0;
|
||||
}
|
||||
@@ -1204,7 +1204,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdcch_pdu));
|
||||
dl_req->nPDUs += 1;
|
||||
pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
|
||||
nr_configure_pdcch(pdcch_pdu_rel15, ss, coreset, scc, genericParameters, type0_PDCCH_CSS_config);
|
||||
nr_configure_pdcch(nr_mac, pdcch_pdu_rel15, ss, coreset, scc, genericParameters, NULL);
|
||||
nr_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid] = pdcch_pdu_rel15;
|
||||
}
|
||||
|
||||
@@ -1364,7 +1364,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
|
||||
// Mark the corresponding RBs as used
|
||||
for (int rb = 0; rb < rbSize; rb++) {
|
||||
vrb_map[rb + rbStart] = 1;
|
||||
vrb_map[BWPStart + rb + rbStart] = 1;
|
||||
}
|
||||
|
||||
ra->state = WAIT_Msg3;
|
||||
@@ -1547,7 +1547,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
|
||||
int i = 0;
|
||||
while ((i < rbSize) && (rbStart + rbSize <= BWPSize)) {
|
||||
if (vrb_map[rbStart + i]) {
|
||||
if (vrb_map[BWPStart + rbStart + i]) {
|
||||
rbStart += i+1;
|
||||
i = 0;
|
||||
} else {
|
||||
@@ -1580,7 +1580,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdcch_pdu));
|
||||
dl_req->nPDUs += 1;
|
||||
pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
|
||||
nr_configure_pdcch(pdcch_pdu_rel15, ss, coreset, scc, genericParameters, type0_PDCCH_CSS_config);
|
||||
nr_configure_pdcch(nr_mac, pdcch_pdu_rel15, ss, coreset, scc, genericParameters, NULL);
|
||||
nr_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid] = pdcch_pdu_rel15;
|
||||
}
|
||||
|
||||
@@ -1723,7 +1723,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
|
||||
// Mark the corresponding RBs as used
|
||||
for (int rb = 0; rb < pdsch_pdu_rel15->rbSize; rb++) {
|
||||
vrb_map[rb + pdsch_pdu_rel15->rbStart] = 1;
|
||||
vrb_map[BWPStart + rb + pdsch_pdu_rel15->rbStart] = 1;
|
||||
}
|
||||
|
||||
LOG_D(NR_MAC,"BWPSize: %i\n", pdcch_pdu_rel15->BWPSize);
|
||||
|
||||
@@ -339,6 +339,8 @@ uint32_t schedule_control_sib1(module_id_t module_id,
|
||||
gNB_mac->sched_ctrlCommon->coreset = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->coreset));
|
||||
fill_searchSpaceZero(gNB_mac->sched_ctrlCommon->search_space,type0_PDCCH_CSS_config);
|
||||
fill_coresetZero(gNB_mac->sched_ctrlCommon->coreset,type0_PDCCH_CSS_config);
|
||||
gNB_mac->cset0_bwp_start = type0_PDCCH_CSS_config->cset_start_rb;
|
||||
gNB_mac->cset0_bwp_size = type0_PDCCH_CSS_config->num_rbs;
|
||||
}
|
||||
|
||||
gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation = time_domain_allocation;
|
||||
@@ -436,7 +438,8 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
|
||||
dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
|
||||
dl_req->nPDUs += 1;
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
|
||||
nr_configure_pdcch(pdcch_pdu_rel15,
|
||||
nr_configure_pdcch(NULL,
|
||||
pdcch_pdu_rel15,
|
||||
gNB_mac->sched_ctrlCommon->search_space,
|
||||
gNB_mac->sched_ctrlCommon->coreset,
|
||||
scc,
|
||||
|
||||
@@ -481,7 +481,7 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
&RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
|
||||
|
||||
const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
int rbStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
int rbStart = 0; // start wrt BWPstart
|
||||
|
||||
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
||||
const long f = (sched_ctrl->active_bwp ||bwpd) ? sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats : 0;
|
||||
@@ -671,7 +671,7 @@ void pf_dl(module_id_t module_id,
|
||||
&scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
|
||||
|
||||
const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
|
||||
int rbStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
int rbStart = 0; // start wrt BWPstart
|
||||
|
||||
/* Find a free CCE */
|
||||
bool freeCCE = find_free_CCE(module_id, slot, UE_id);
|
||||
@@ -760,6 +760,10 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth:
|
||||
scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,
|
||||
MAX_BWP_SIZE);
|
||||
const uint16_t BWPStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp ?
|
||||
sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth:
|
||||
scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,
|
||||
MAX_BWP_SIZE);
|
||||
|
||||
uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
|
||||
uint8_t rballoc_mask[bwpSize];
|
||||
@@ -767,7 +771,7 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
for (int i = 0; i < bwpSize; i++) {
|
||||
// calculate mask: init with "NOT" vrb_map:
|
||||
// if any RB in vrb_map is blocked (1), the current RBG will be 0
|
||||
rballoc_mask[i] = !vrb_map[i];
|
||||
rballoc_mask[i] = !vrb_map[i+BWPStart];
|
||||
n_rb_sched += rballoc_mask[i];
|
||||
}
|
||||
|
||||
@@ -934,7 +938,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
LOG_D(NR_MAC,"Trying to configure DL pdcch for UE %d, bwp %d, cs %d\n",UE_id,bwpid,coresetid);
|
||||
NR_SearchSpace_t *ss = (bwp||bwpd) ? sched_ctrl->search_space:gNB_mac->sched_ctrlCommon->search_space;
|
||||
NR_ControlResourceSet_t *coreset = (bwp||bwpd)? sched_ctrl->coreset:gNB_mac->sched_ctrlCommon->coreset;
|
||||
nr_configure_pdcch(pdcch_pdu, ss, coreset, scc, genericParameters, NULL);
|
||||
nr_configure_pdcch(gNB_mac, pdcch_pdu, ss, coreset, scc, genericParameters, NULL);
|
||||
gNB_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid] = pdcch_pdu;
|
||||
}
|
||||
|
||||
|
||||
@@ -280,8 +280,8 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
/* find largest unallocated chunk */
|
||||
const int bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
|
||||
target_dl_bw = (bwpSize < target_dl_bw) ?bwpSize : target_dl_bw;
|
||||
const int BWPStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
|
||||
int rbStart = 0;
|
||||
int rbSize = 0;
|
||||
if (target_dl_bw>bwpSize)
|
||||
@@ -290,11 +290,11 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
||||
/* loop ensures that we allocate exactly target_dl_bw, or return */
|
||||
while (true) {
|
||||
/* advance to first free RB */
|
||||
while (rbStart < bwpSize && vrb_map[rbStart])
|
||||
while (rbStart < bwpSize && vrb_map[rbStart + BWPStart])
|
||||
rbStart++;
|
||||
rbSize = 1;
|
||||
/* iterate until we are at target_dl_bw or no available RBs */
|
||||
while (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize] && rbSize < target_dl_bw)
|
||||
while (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize + BWPStart] && rbSize < target_dl_bw)
|
||||
rbSize++;
|
||||
/* found target_dl_bw? */
|
||||
if (rbStart+ rbSize == target_dl_bw)
|
||||
@@ -399,7 +399,7 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
||||
|
||||
/* mark the corresponding RBs as used */
|
||||
for (int rb = 0; rb < sched_pdsch->rbSize; rb++)
|
||||
vrb_map[rb + sched_pdsch->rbStart] = 1;
|
||||
vrb_map[rb + sched_pdsch->rbStart + BWPStart] = 1;
|
||||
|
||||
if ((frame&127) == 0) LOG_D(MAC,"phytest: %d.%d DL mcs %d, DL rbStart %d, DL rbSize %d\n", frame, slot, sched_pdsch->mcs, rbStart,rbSize);
|
||||
}
|
||||
@@ -461,8 +461,11 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
|
||||
uint16_t rbSize;
|
||||
|
||||
const int bw = NRRIV2BW(sched_ctrl->active_ubwp ?
|
||||
sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth :
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth :
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
const int BWPStart = NRRIV2PRBOFFSET(sched_ctrl->active_ubwp ?
|
||||
sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth :
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
|
||||
if (target_ul_bw>bw)
|
||||
rbSize = bw;
|
||||
@@ -473,7 +476,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
|
||||
&RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[sched_slot * MAX_BWP_SIZE];
|
||||
const uint16_t symb = ((1 << ps->nrOfSymbols) - 1) << ps->startSymbolIndex;
|
||||
for (int i = rbStart; i < rbStart + rbSize; ++i) {
|
||||
if ((vrb_map_UL[i] & symb) != 0) {
|
||||
if ((vrb_map_UL[i+BWPStart] & symb) != 0) {
|
||||
LOG_E(MAC,
|
||||
"%s(): %4d.%2d RB %d is already reserved, cannot schedule UE\n",
|
||||
__func__,
|
||||
@@ -542,6 +545,6 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
|
||||
|
||||
/* mark the corresponding RBs as used */
|
||||
for (int rb = rbStart; rb < rbStart + rbSize; rb++)
|
||||
vrb_map_UL[rb] = 1;
|
||||
vrb_map_UL[rb+BWPStart] = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -723,7 +723,8 @@ int nr_get_default_pucch_res(int pucch_ResourceCommon) {
|
||||
return(default_pucch_csset[pucch_ResourceCommon]);
|
||||
}
|
||||
|
||||
void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
|
||||
void nr_configure_pdcch(gNB_MAC_INST *gNB_mac,
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
|
||||
NR_SearchSpace_t *ss,
|
||||
NR_ControlResourceSet_t *coreset,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
@@ -731,9 +732,19 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
|
||||
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config) {
|
||||
|
||||
int sps;
|
||||
if (bwp && *ss->controlResourceSetId!=0) { // This is not for coreset0
|
||||
pdcch_pdu->BWPSize = NRRIV2BW(bwp->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
pdcch_pdu->BWPStart = NRRIV2PRBOFFSET(bwp->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
AssertFatal(*ss->controlResourceSetId == coreset->controlResourceSetId,
|
||||
"coreset id in SS %ld does not correspond to the one in coreset %ld",
|
||||
*ss->controlResourceSetId, coreset->controlResourceSetId);
|
||||
|
||||
if (bwp) { // This is not for SIB1
|
||||
if(coreset->controlResourceSetId == 0){
|
||||
pdcch_pdu->BWPSize = gNB_mac->cset0_bwp_size;
|
||||
pdcch_pdu->BWPStart = gNB_mac->cset0_bwp_start;
|
||||
}
|
||||
else {
|
||||
pdcch_pdu->BWPSize = NRRIV2BW(bwp->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
pdcch_pdu->BWPStart = NRRIV2PRBOFFSET(bwp->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
}
|
||||
pdcch_pdu->SubcarrierSpacing = bwp->subcarrierSpacing;
|
||||
pdcch_pdu->CyclicPrefix = (bwp->cyclicPrefix==NULL) ? 0 : *bwp->cyclicPrefix;
|
||||
|
||||
@@ -2261,20 +2272,20 @@ void nr_csirs_scheduling(int Mod_idP,
|
||||
csirs_pdu_rel15->row = 1;
|
||||
csirs_pdu_rel15->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.row1.buf[0])>>4)&0x0f;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row2:
|
||||
csirs_pdu_rel15->row = 2;
|
||||
csirs_pdu_rel15->freq_domain = (((resourceMapping.frequencyDomainAllocation.choice.row2.buf[1]>>4)&0x0f) |
|
||||
((resourceMapping.frequencyDomainAllocation.choice.row2.buf[0]<<8)&0xff0));
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row4:
|
||||
csirs_pdu_rel15->row = 4;
|
||||
csirs_pdu_rel15->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.row4.buf[0])>>5)&0x07;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other:
|
||||
csirs_pdu_rel15->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.other.buf[0])>>2)&0x3f;
|
||||
@@ -2285,18 +2296,18 @@ void nr_csirs_scheduling(int Mod_idP,
|
||||
case NR_CSI_RS_ResourceMapping__nrofPorts_p2:
|
||||
csirs_pdu_rel15->row = 3;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__nrofPorts_p4:
|
||||
csirs_pdu_rel15->row = 5;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__nrofPorts_p8:
|
||||
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
|
||||
csirs_pdu_rel15->row = 8;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
|
||||
}
|
||||
else{
|
||||
int num_k = 0;
|
||||
@@ -2305,12 +2316,12 @@ void nr_csirs_scheduling(int Mod_idP,
|
||||
if(num_k==4) {
|
||||
csirs_pdu_rel15->row = 6;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
}
|
||||
else {
|
||||
csirs_pdu_rel15->row = 7;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -2318,12 +2329,12 @@ void nr_csirs_scheduling(int Mod_idP,
|
||||
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
|
||||
csirs_pdu_rel15->row = 10;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
|
||||
}
|
||||
else {
|
||||
csirs_pdu_rel15->row = 9;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
}
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__nrofPorts_p16:
|
||||
@@ -2332,24 +2343,24 @@ void nr_csirs_scheduling(int Mod_idP,
|
||||
else
|
||||
csirs_pdu_rel15->row = 11;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__nrofPorts_p24:
|
||||
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
|
||||
csirs_pdu_rel15->row = 14;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1));
|
||||
}
|
||||
else{
|
||||
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4) {
|
||||
csirs_pdu_rel15->row = 15;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= (7 << csirs_pdu_rel15->symb_l0);
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (7 << csirs_pdu_rel15->symb_l0);
|
||||
}
|
||||
else {
|
||||
csirs_pdu_rel15->row = 13;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -2357,18 +2368,18 @@ void nr_csirs_scheduling(int Mod_idP,
|
||||
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
|
||||
csirs_pdu_rel15->row = 17;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1));
|
||||
}
|
||||
else{
|
||||
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4) {
|
||||
csirs_pdu_rel15->row = 18;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= (7 << csirs_pdu_rel15->symb_l0);
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (7 << csirs_pdu_rel15->symb_l0);
|
||||
}
|
||||
else {
|
||||
csirs_pdu_rel15->row = 16;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -294,6 +294,7 @@ uint8_t compute_ri_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
}
|
||||
else
|
||||
AssertFatal(1==0,"Other configurations not yet implemented\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void compute_li_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
@@ -520,6 +521,11 @@ void nr_csi_meas_reporting(int Mod_idP,
|
||||
curr_pucch->csi_bits +=
|
||||
nr_get_csi_bitlen(Mod_idP,UE_id,csi_report_id);
|
||||
|
||||
NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ?
|
||||
&sched_ctrl->active_ubwp->bwp_Common->genericParameters:
|
||||
&scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
int bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
|
||||
|
||||
// going through the list of PUCCH resources to find the one indexed by resource_id
|
||||
uint16_t *vrb_map_UL = &RC.nrmac[Mod_idP]->common_channels[0].vrb_map_UL[sched_slot * MAX_BWP_SIZE];
|
||||
const int m = pucch_Config->resourceToAddModList->list.count;
|
||||
@@ -550,7 +556,7 @@ void nr_csi_meas_reporting(int Mod_idP,
|
||||
}
|
||||
// verify resources are free
|
||||
for (int i = start; i < start + len; ++i) {
|
||||
vrb_map_UL[i] |= mask;
|
||||
vrb_map_UL[i+bwp_start] |= mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1390,18 +1396,32 @@ int nr_acknack_scheduling(int mod_id,
|
||||
pucch_Config = RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup;
|
||||
}
|
||||
|
||||
NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ?
|
||||
&sched_ctrl->active_ubwp->bwp_Common->genericParameters:
|
||||
&scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
int bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
|
||||
|
||||
/* verify that at that slot and symbol, resources are free. We only do this
|
||||
* for initialCyclicShift 0 (we assume it always has that one), so other
|
||||
* initialCyclicShifts can overlap with ICS 0!*/
|
||||
if (pucch_Config) {
|
||||
const NR_PUCCH_Resource_t *resource = pucch_Config->resourceToAddModList->list.array[pucch->resource_indicator];
|
||||
DevAssert(resource->format.present == NR_PUCCH_Resource__format_PR_format0);
|
||||
int second_hop_prb = resource->secondHopPRB!= NULL ? *resource->secondHopPRB : 0;
|
||||
int nr_of_symbols = resource->format.choice.format0->nrofSymbols;
|
||||
if (resource->format.choice.format0->initialCyclicShift == 0) {
|
||||
uint16_t *vrb_map_UL = &RC.nrmac[mod_id]->common_channels[CC_id].vrb_map_UL[pucch->ul_slot * MAX_BWP_SIZE];
|
||||
const uint16_t symb = 1 << resource->format.choice.format0->startingSymbolIndex;
|
||||
if ((vrb_map_UL[resource->startingPRB] & symb) != 0)
|
||||
LOG_W(NR_MAC, "symbol 0x%x is not free for PUCCH alloc in vrb_map_UL at RB %ld and slot %d.%d\n", symb, resource->startingPRB, pucch->frame, pucch->ul_slot);
|
||||
vrb_map_UL[resource->startingPRB] |= symb;
|
||||
for (int l=0; l<nr_of_symbols; l++) {
|
||||
uint16_t symb = 1 << (resource->format.choice.format0->startingSymbolIndex + l);
|
||||
int prb;
|
||||
if (l==1 && second_hop_prb != 0)
|
||||
prb = second_hop_prb;
|
||||
else
|
||||
prb = resource->startingPRB;
|
||||
if ((vrb_map_UL[bwp_start+prb] & symb) != 0)
|
||||
LOG_W(MAC, "symbol 0x%x is not free for PUCCH alloc in vrb_map_UL at RB %ld and slot %d.%d\n", symb, resource->startingPRB, pucch->frame, pucch->ul_slot);
|
||||
vrb_map_UL[bwp_start+prb] |= symb;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -34,34 +34,7 @@
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include <openair2/UTIL/OPT/opt.h>
|
||||
|
||||
|
||||
//38.321 Table 6.1.3.1-1
|
||||
const uint32_t NR_SHORT_BSR_TABLE[32] = {
|
||||
0, 10, 14, 20, 28, 38, 53, 74,
|
||||
102, 142, 198, 276, 384, 535, 745, 1038,
|
||||
1446, 2014, 2806, 3909, 5446, 7587, 10570, 14726,
|
||||
20516, 28581, 39818, 55474, 77284, 107669, 150000, 300000
|
||||
};
|
||||
|
||||
//38.321 Table 6.1.3.1-2
|
||||
const uint32_t NR_LONG_BSR_TABLE[256] ={
|
||||
0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 23, 25, 26,
|
||||
28, 30, 32, 34, 36, 38, 40, 43, 46, 49, 52, 55, 59, 62, 66, 71,
|
||||
75, 80, 85, 91, 97, 103, 110, 117, 124, 132, 141, 150, 160, 170, 181, 193,
|
||||
205, 218, 233, 248, 264, 281, 299, 318, 339, 361, 384, 409, 436, 464, 494, 526,
|
||||
560, 597, 635, 677, 720, 767, 817, 870, 926, 987, 1051, 1119, 1191, 1269, 1351, 1439,
|
||||
1532, 1631, 1737, 1850, 1970, 2098, 2234, 2379, 2533, 2698, 2873, 3059, 3258, 3469, 3694, 3934,
|
||||
4189, 4461, 4751, 5059, 5387, 5737, 6109, 6506, 6928, 7378, 7857, 8367, 8910, 9488, 10104, 10760,
|
||||
11458, 12202, 12994, 13838, 14736, 15692, 16711, 17795, 18951, 20181, 21491, 22885, 24371, 25953, 27638, 29431,
|
||||
31342, 33376, 35543, 37850, 40307, 42923, 45709, 48676, 51836, 55200, 58784, 62599, 66663, 70990, 75598, 80505,
|
||||
85730, 91295, 97221, 103532, 110252, 117409, 125030, 133146, 141789, 150992, 160793, 171231, 182345, 194182, 206786, 220209,
|
||||
234503, 249725, 265935, 283197, 301579, 321155, 342002, 364202, 387842, 413018, 439827, 468377, 498780, 531156, 565634, 602350,
|
||||
641449, 683087, 727427, 774645, 824928, 878475, 935498, 996222, 1060888, 1129752, 1203085, 1281179, 1364342, 1452903, 1547213, 1647644,
|
||||
1754595, 1868488, 1989774, 2118933, 2256475, 2402946, 2558924, 2725027, 2901912, 3090279, 3290873, 3504487, 3731968, 3974215, 4232186, 4506902,
|
||||
4799451, 5110989, 5442750, 5796046, 6172275, 6572925, 6999582, 7453933, 7937777, 8453028, 9001725, 9586039, 10208280, 10870913, 11576557, 12328006,
|
||||
13128233, 13980403, 14887889, 15854280, 16883401, 17979324, 19146385, 20389201, 21712690, 23122088, 24622972, 26221280, 27923336, 29735875, 31666069, 33721553,
|
||||
35910462, 38241455, 40723756, 43367187, 46182206, 49179951, 52372284, 55771835, 59392055, 63247269, 67352729, 71724679, 76380419, 81338368, 162676736, 4294967295
|
||||
};
|
||||
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
|
||||
|
||||
int get_dci_format(NR_UE_sched_ctrl_t *sched_ctrl) {
|
||||
|
||||
@@ -896,7 +869,7 @@ bool nr_UE_is_to_be_scheduled(module_id_t mod_id, int CC_id, int UE_id, frame_t
|
||||
* (2) there is a scheduling request
|
||||
* (3) or we did not schedule it in more than 10 frames */
|
||||
const bool has_data = sched_ctrl->estimated_ul_buffer > sched_ctrl->sched_ul_bytes;
|
||||
const bool high_inactivity = diff >= nrmac->ulsch_max_slots_inactivity;
|
||||
const bool high_inactivity = diff >= nrmac->ulsch_max_frame_inactivity * n;
|
||||
LOG_D(NR_MAC,
|
||||
"%4d.%2d UL inactivity %d slots has_data %d SR %d\n",
|
||||
frame,
|
||||
@@ -930,7 +903,7 @@ bool allocate_ul_retransmission(module_id_t module_id,
|
||||
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
||||
NR_BWP_UplinkDedicated_t *ubwpd= cg ? cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP:NULL;
|
||||
NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? &sched_ctrl->active_ubwp->bwp_Common->genericParameters : &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
int rbStart = sched_ctrl->active_ubwp ? NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE) : 0;
|
||||
int rbStart = 0; // wrt BWP start
|
||||
const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
|
||||
const uint8_t num_dmrs_cdm_grps_no_data = (sched_ctrl->active_bwp || ubwpd) ? 1 : 2;
|
||||
@@ -1066,10 +1039,10 @@ void pf_ul(module_id_t module_id,
|
||||
LOG_D(NR_MAC,"pf_ul: preparing UL scheduling for UE %d\n",UE_id);
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? &sched_ctrl->active_ubwp->bwp_Common->genericParameters : &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
int rbStart = 0; // wrt BWP start
|
||||
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
||||
NR_BWP_UplinkDedicated_t *ubwpd= cg ? cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
|
||||
|
||||
int rbStart = sched_ctrl->active_ubwp ? NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE) : 0;
|
||||
const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
|
||||
NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static;
|
||||
@@ -1320,6 +1293,10 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth:
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,
|
||||
MAX_BWP_SIZE);
|
||||
const uint16_t bwpStart = NRRIV2PRBOFFSET(sched_ctrl->active_ubwp ?
|
||||
sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth:
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,
|
||||
MAX_BWP_SIZE);
|
||||
const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList = sched_ctrl->active_ubwp ?
|
||||
sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList:
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
|
||||
@@ -1333,10 +1310,10 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
if (RC.nrmac[module_id]->ulprbbl[i] == 1) vrb_map_UL[i]=symb;
|
||||
|
||||
for (int i = 0; i < bwpSize; i++) {
|
||||
while ((vrb_map_UL[i] & symb) != 0 && i < bwpSize)
|
||||
while ((vrb_map_UL[bwpStart + i] & symb) != 0 && i < bwpSize)
|
||||
i++;
|
||||
st = i;
|
||||
while ((vrb_map_UL[i] & symb) == 0 && i < bwpSize)
|
||||
while ((vrb_map_UL[bwpStart + i] & symb) == 0 && i < bwpSize)
|
||||
i++;
|
||||
if (i - st > len) {
|
||||
len = i - st;
|
||||
@@ -1659,7 +1636,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
|
||||
pdcch_pdu = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15;
|
||||
ul_dci_req->numPdus += 1;
|
||||
nr_configure_pdcch(pdcch_pdu, ss, coreset, scc, genericParameters, NULL);
|
||||
nr_configure_pdcch(nr_mac, pdcch_pdu, ss, coreset, scc, genericParameters, NULL);
|
||||
pdcch_pdu_bwp_coreset[bwpid][coresetid] = pdcch_pdu;
|
||||
}
|
||||
|
||||
|
||||
@@ -248,7 +248,8 @@ void find_search_space(int ss_type,
|
||||
NR_BWP_Downlink_t *bwp,
|
||||
NR_SearchSpace_t *ss);
|
||||
|
||||
void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
|
||||
void nr_configure_pdcch(gNB_MAC_INST *gNB_mac,
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
|
||||
NR_SearchSpace_t *ss,
|
||||
NR_ControlResourceSet_t *coreset,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
|
||||
@@ -145,6 +145,8 @@ typedef struct {
|
||||
uint8_t msg3_first_rb;
|
||||
/// Msg3 number of RB
|
||||
uint8_t msg3_nb_rb;
|
||||
/// Msg3 BWP start
|
||||
uint8_t msg3_bwp_start;
|
||||
/// Msg3 TPC command
|
||||
uint8_t msg3_TPC;
|
||||
/// Msg3 ULdelay command
|
||||
@@ -748,7 +750,7 @@ typedef struct gNB_MAC_INST_s {
|
||||
int *preferred_ul_tda[MAX_NUM_BWP];
|
||||
|
||||
/// maximum number of slots before a UE will be scheduled ULSCH automatically
|
||||
uint32_t ulsch_max_slots_inactivity;
|
||||
uint32_t ulsch_max_frame_inactivity;
|
||||
|
||||
/// DL preprocessor for differentiated scheduling
|
||||
nr_pp_impl_dl pre_processor_dl;
|
||||
@@ -756,6 +758,8 @@ typedef struct gNB_MAC_INST_s {
|
||||
nr_pp_impl_ul pre_processor_ul;
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrlCommon;
|
||||
uint16_t cset0_bwp_start;
|
||||
uint16_t cset0_bwp_size;
|
||||
NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config[64];
|
||||
|
||||
bool first_MIB;
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "pdcp.h"
|
||||
#include "LAYER2/nr_rlc/nr_rlc_oai_api.h"
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
#include "openair2/SDAP/nr_sdap/nr_sdap_gnb.h"
|
||||
|
||||
#define TODO do { \
|
||||
printf("%s:%d:%s: todo\n", __FILE__, __LINE__, __FUNCTION__); \
|
||||
@@ -447,10 +448,18 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
|
||||
|
||||
if(IS_SOFTMODEM_NOS1 || UE_NAS_USE_TUN){
|
||||
LOG_D(PDCP, "IP packet received, to be sent to TUN interface");
|
||||
len = write(nas_sock_fd[0], buf, size);
|
||||
|
||||
if(entity->has_sdapDLheader){
|
||||
size -= SDAP_HDR_LENGTH;
|
||||
len = write(nas_sock_fd[0], &buf[SDAP_HDR_LENGTH], size);
|
||||
} else {
|
||||
len = write(nas_sock_fd[0], buf, size);
|
||||
}
|
||||
|
||||
if (len != size) {
|
||||
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
}
|
||||
|
||||
}
|
||||
else{
|
||||
for (i = 0; i < 5; i++) {
|
||||
@@ -480,7 +489,10 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
|
||||
GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).offset = GTPU_HEADER_OVERHEAD_MAX;
|
||||
GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).rnti = ue->rnti;
|
||||
GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).pdusession_id = entity->pdusession_id;
|
||||
if (offset==1) LOG_D(PDCP, "%s() (drb %d) SDAP header %2x\n",__func__, rb_id, buf[0]);
|
||||
if (offset==1) {
|
||||
LOG_I(PDCP, "%s() (drb %d) SDAP header %2x\n",__func__, rb_id, buf[0]);
|
||||
sdap_gnb_ul_header_handler(buf[0]); // Handler for the UL gNB SDAP Header
|
||||
}
|
||||
LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n", __func__, rb_id, size-offset);
|
||||
itti_send_msg_to_task(TASK_VARIABLE, INSTANCE_DEFAULT, message_p);
|
||||
}
|
||||
@@ -828,10 +840,6 @@ static void add_drb_am(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s,
|
||||
has_sdap = 1;
|
||||
has_sdapULheader = s->cnAssociation->choice.sdap_Config->sdap_HeaderUL == NR_SDAP_Config__sdap_HeaderUL_present ? 1 : 0;
|
||||
has_sdapDLheader = s->cnAssociation->choice.sdap_Config->sdap_HeaderDL == NR_SDAP_Config__sdap_HeaderDL_present ? 1 : 0;
|
||||
if (has_sdapDLheader==1) {
|
||||
LOG_E(PDCP,"%s:%d:%s: fatal, no support for SDAP DL yet\n",__FILE__,__LINE__,__FUNCTION__);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
/* TODO(?): accept different UL and DL SN sizes? */
|
||||
if (sn_size_ul != sn_size_dl) {
|
||||
@@ -903,9 +911,7 @@ boolean_t nr_rrc_pdcp_config_asn1_req(
|
||||
uint8_t *const kRRCint,
|
||||
uint8_t *const kUPenc,
|
||||
uint8_t *const kUPint
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
|
||||
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
|
||||
#endif
|
||||
,rb_id_t *const defaultDRB,
|
||||
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list)
|
||||
//struct NR_RLC_Config *rlc_Config)
|
||||
@@ -975,9 +981,7 @@ boolean_t rrc_pdcp_config_asn1_req(
|
||||
uint8_t *const kRRCenc,
|
||||
uint8_t *const kRRCint,
|
||||
uint8_t *const kUPenc
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
|
||||
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
|
||||
#endif
|
||||
,rb_id_t *const defaultDRB)
|
||||
{
|
||||
return 0;
|
||||
@@ -1240,10 +1244,8 @@ boolean_t pdcp_data_req(
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
unsigned char *const sdu_buffer,
|
||||
const pdcp_transmission_mode_t mode
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
,const uint32_t *const sourceL2Id
|
||||
,const uint32_t *const destinationL2Id
|
||||
#endif
|
||||
)
|
||||
{
|
||||
if (srb_flagP) {
|
||||
|
||||
@@ -270,7 +270,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind(
|
||||
+ buf_stat.retx_size
|
||||
+ buf_stat.tx_size;
|
||||
} else {
|
||||
if (!(frameP%128)) //to supress this warning message
|
||||
if (!(frameP%128)) //to suppress this warning message
|
||||
LOG_W(RLC, "[%s] Radio Bearer (channel ID %d) is NULL for UE with rntiP %x\n", __FUNCTION__, channel_idP, rntiP);
|
||||
ret.bytes_in_buffer = 0;
|
||||
}
|
||||
@@ -334,6 +334,8 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(
|
||||
+ buf_stat.retx_size
|
||||
+ buf_stat.tx_size;
|
||||
} else {
|
||||
if (!(frameP%128)) //to suppress this warning message
|
||||
LOG_W(RLC, "[%s] Radio Bearer (channel ID %d) is NULL for UE with rntiP %x\n", __FUNCTION__, channel_idP, rntiP);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
@@ -953,16 +955,16 @@ rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt
|
||||
if ((drb2add_listP != NULL) && (rlc_bearer2add_list != NULL)) {
|
||||
for (i = 0; i < drb2add_listP->list.count; i++) {
|
||||
if (rlc_bearer2add_list != NULL) {
|
||||
for(j = 0; j < rlc_bearer2add_list->list.count; j++){
|
||||
if(rlc_bearer2add_list->list.array[j]->servedRadioBearer != NULL){
|
||||
if(rlc_bearer2add_list->list.array[j]->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity){
|
||||
if(drb2add_listP->list.array[i]->drb_Identity == rlc_bearer2add_list->list.array[j]->servedRadioBearer->choice.drb_Identity){
|
||||
add_drb(rnti, drb2add_listP->list.array[i], rlc_bearer2add_list->list.array[j]);
|
||||
for(j = 0; j < rlc_bearer2add_list->list.count; j++){
|
||||
if(rlc_bearer2add_list->list.array[j]->servedRadioBearer != NULL){
|
||||
if(rlc_bearer2add_list->list.array[j]->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity){
|
||||
if(drb2add_listP->list.array[i]->drb_Identity == rlc_bearer2add_list->list.array[j]->servedRadioBearer->choice.drb_Identity){
|
||||
add_drb(rnti, drb2add_listP->list.array[i], rlc_bearer2add_list->list.array[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3618,9 +3618,7 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
|
||||
, (LTE_PMCH_InfoList_r9_t *) NULL
|
||||
#endif
|
||||
, NULL);
|
||||
|
||||
/* Refresh SRBs/DRBs */
|
||||
@@ -3629,11 +3627,9 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t
|
||||
*SRB_configList2, // NULL,
|
||||
*DRB_configList,
|
||||
NULL
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
|
||||
, (LTE_PMCH_InfoList_r9_t *) NULL,
|
||||
0,
|
||||
0
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6331,9 +6327,7 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
|
||||
, (LTE_PMCH_InfoList_r9_t *) NULL
|
||||
#endif
|
||||
, NULL);
|
||||
|
||||
/* Refresh SRBs/DRBs */
|
||||
@@ -6342,11 +6336,9 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct
|
||||
*SRB_configList2, // NULL,
|
||||
*DRB_configList,
|
||||
NULL
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
|
||||
, (LTE_PMCH_InfoList_r9_t *) NULL,
|
||||
0,
|
||||
0
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1182,9 +1182,9 @@ void fill_initial_SpCellConfig(rnti_t rnti,
|
||||
AssertFatal(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing==NR_SubcarrierSpacing_kHz30,
|
||||
"SCS != 30kHz\n");
|
||||
AssertFatal(scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity==NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms5,
|
||||
"TDD period != 5ms : %ld\n",scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity);
|
||||
|
||||
schedulingRequestResourceConfig->periodicityAndOffset->choice.sl40 = 8+(10*((rnti>>1)&3)) + (rnti&1);
|
||||
"TDD period != 5ms : %ld\n",scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity);
|
||||
|
||||
schedulingRequestResourceConfig->periodicityAndOffset->choice.sl40 = 8 + 10*((rnti>>1)&3) + (rnti&1);
|
||||
schedulingRequestResourceConfig->resource = calloc(1,sizeof(*schedulingRequestResourceConfig->resource));
|
||||
*schedulingRequestResourceConfig->resource = 0;
|
||||
ASN_SEQUENCE_ADD(&pucch_Config->schedulingRequestResourceToAddModList->list,schedulingRequestResourceConfig);
|
||||
|
||||
@@ -106,9 +106,7 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req(
|
||||
uint8_t *const kRRCint,
|
||||
uint8_t *const kUPenc,
|
||||
uint8_t *const kUPint
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
|
||||
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
|
||||
#endif
|
||||
,rb_id_t *const defaultDRB,
|
||||
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
|
||||
|
||||
@@ -1010,7 +1008,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
|
||||
sdap_config = CALLOC(1, sizeof(NR_SDAP_Config_t));
|
||||
memset(sdap_config, 0, sizeof(NR_SDAP_Config_t));
|
||||
sdap_config->pdu_Session = ue_context_pP->ue_context.pduSession[i].param.pdusession_id;
|
||||
sdap_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent;
|
||||
sdap_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_present;
|
||||
sdap_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_absent;
|
||||
sdap_config->defaultDRB = TRUE;
|
||||
sdap_config->mappedQoS_FlowsToAdd = calloc(1, sizeof(struct NR_SDAP_Config__mappedQoS_FlowsToAdd));
|
||||
@@ -1043,7 +1041,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
|
||||
DRB_config->pdcp_Config->moreThanOneRLC = NULL;
|
||||
|
||||
DRB_config->pdcp_Config->t_Reordering = calloc(1, sizeof(*DRB_config->pdcp_Config->t_Reordering));
|
||||
*DRB_config->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms750;
|
||||
*DRB_config->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms0;
|
||||
DRB_config->pdcp_Config->ext1 = NULL;
|
||||
|
||||
if (rrc->security.do_drb_integrity) {
|
||||
@@ -1305,51 +1303,22 @@ rrc_gNB_process_RRCReconfigurationComplete(
|
||||
|
||||
ue_context_pP->ue_context.ue_reestablishment_timer = 0;
|
||||
|
||||
#ifndef PHYSIM
|
||||
uint8_t *k_kdf = NULL;
|
||||
/* Derive the keys from kgnb */
|
||||
if (DRB_configList != NULL) {
|
||||
k_kdf = NULL;
|
||||
nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm,
|
||||
ue_context_pP->ue_context.kgnb,
|
||||
&k_kdf);
|
||||
/* kUPenc: last 128 bits of key derivation function which returns 256 bits */
|
||||
kUPenc = malloc(16);
|
||||
if (kUPenc == NULL) exit(1);
|
||||
memcpy(kUPenc, k_kdf+16, 16);
|
||||
free(k_kdf);
|
||||
|
||||
k_kdf = NULL;
|
||||
&kUPenc);
|
||||
nr_derive_key_up_int(ue_context_pP->ue_context.integrity_algorithm,
|
||||
ue_context_pP->ue_context.kgnb,
|
||||
&k_kdf);
|
||||
/* kUPint: last 128 bits of key derivation function which returns 256 bits */
|
||||
kUPint = malloc(16);
|
||||
if (kUPint == NULL) exit(1);
|
||||
memcpy(kUPint, k_kdf+16, 16);
|
||||
free(k_kdf);
|
||||
&kUPint);
|
||||
}
|
||||
|
||||
k_kdf = NULL;
|
||||
nr_derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm,
|
||||
ue_context_pP->ue_context.kgnb,
|
||||
&k_kdf);
|
||||
/* kRRCenc: last 128 bits of key derivation function which returns 256 bits */
|
||||
kRRCenc = malloc(16);
|
||||
if (kRRCenc == NULL) exit(1);
|
||||
memcpy(kRRCenc, k_kdf+16, 16);
|
||||
free(k_kdf);
|
||||
|
||||
k_kdf = NULL;
|
||||
&kRRCenc);
|
||||
nr_derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm,
|
||||
ue_context_pP->ue_context.kgnb,
|
||||
&k_kdf);
|
||||
/* kRRCint: last 128 bits of key derivation function which returns 256 bits */
|
||||
kRRCint = malloc(16);
|
||||
if (kRRCint == NULL) exit(1);
|
||||
memcpy(kRRCint, k_kdf+16, 16);
|
||||
free(k_kdf);
|
||||
#endif
|
||||
&kRRCint);
|
||||
/* Refresh SRBs/DRBs */
|
||||
MSC_LOG_TX_MESSAGE(MSC_RRC_GNB, MSC_PDCP_ENB, NULL, 0, MSC_AS_TIME_FMT" CONFIG_REQ UE %x DRB (security unchanged)",
|
||||
MSC_AS_TIME_ARGS(ctxt_pP),
|
||||
|
||||
@@ -308,43 +308,19 @@ nr_rrc_pdcp_config_security(
|
||||
uint8_t *kUPenc = NULL;
|
||||
static int print_keys= 1;
|
||||
|
||||
#ifndef PHYSIM
|
||||
|
||||
uint8_t *k_kdf = NULL;
|
||||
|
||||
/* Derive the keys from kgnb */
|
||||
if (SRB_configList != NULL) {
|
||||
k_kdf = NULL;
|
||||
nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm,
|
||||
ue_context_pP->ue_context.kgnb,
|
||||
&k_kdf);
|
||||
/* kUPenc: last 128 bits of key derivation function which returns 256 bits */
|
||||
kUPenc = malloc(16);
|
||||
if (kUPenc == NULL) exit(1);
|
||||
memcpy(kUPenc, k_kdf+16, 16);
|
||||
free(k_kdf);
|
||||
&kUPenc);
|
||||
}
|
||||
|
||||
k_kdf = NULL;
|
||||
nr_derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm,
|
||||
ue_context_pP->ue_context.kgnb,
|
||||
&k_kdf);
|
||||
/* kRRCenc: last 128 bits of key derivation function which returns 256 bits */
|
||||
kRRCenc = malloc(16);
|
||||
if (kRRCenc == NULL) exit(1);
|
||||
memcpy(kRRCenc, k_kdf+16, 16);
|
||||
free(k_kdf);
|
||||
|
||||
k_kdf = NULL;
|
||||
&kRRCenc);
|
||||
nr_derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm,
|
||||
ue_context_pP->ue_context.kgnb,
|
||||
&k_kdf);
|
||||
/* kRRCint: last 128 bits of key derivation function which returns 256 bits */
|
||||
kRRCint = malloc(16);
|
||||
if (kRRCint == NULL) exit(1);
|
||||
memcpy(kRRCint, k_kdf+16, 16);
|
||||
free(k_kdf);
|
||||
#endif
|
||||
&kRRCint);
|
||||
if (!IS_SOFTMODEM_IQPLAYER) {
|
||||
SET_LOG_DUMP(DEBUG_SECURITY) ;
|
||||
}
|
||||
|
||||
@@ -52,9 +52,7 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req(
|
||||
uint8_t *const kRRCint,
|
||||
uint8_t *const kUPenc,
|
||||
uint8_t *const kUPint
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
|
||||
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
|
||||
#endif
|
||||
,rb_id_t *const defaultDRB,
|
||||
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
|
||||
|
||||
@@ -215,25 +213,12 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
LOG_I(RRC, "selecting integrity algorithm %d\n", ue_context_p->ue_context.integrity_algorithm);
|
||||
|
||||
/* derive UP security key */
|
||||
unsigned char *kUPenc_kdf;
|
||||
nr_derive_key_up_enc(ue_context_p->ue_context.ciphering_algorithm,
|
||||
ue_context_p->ue_context.kgnb,
|
||||
&kUPenc_kdf);
|
||||
/* kUPenc: last 128 bits of key derivation function which returns 256 bits */
|
||||
kUPenc = malloc(16);
|
||||
if (kUPenc == NULL) exit(1);
|
||||
memcpy(kUPenc, kUPenc_kdf+16, 16);
|
||||
free(kUPenc_kdf);
|
||||
|
||||
unsigned char *kUPint_kdf;
|
||||
&kUPenc);
|
||||
nr_derive_key_up_int(ue_context_p->ue_context.integrity_algorithm,
|
||||
ue_context_p->ue_context.kgnb,
|
||||
&kUPint_kdf);
|
||||
/* kUPint: last 128 bits of key derivation function which returns 256 bits */
|
||||
kUPint = malloc(16);
|
||||
if (kUPint == NULL) exit(1);
|
||||
memcpy(kUPint, kUPint_kdf+16, 16);
|
||||
free(kUPint_kdf);
|
||||
&kUPint);
|
||||
|
||||
e_NR_CipheringAlgorithm cipher_algo;
|
||||
switch (ue_context_p->ue_context.ciphering_algorithm) {
|
||||
|
||||
+85
-63
@@ -187,9 +187,7 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req(
|
||||
uint8_t *const kRRCint,
|
||||
uint8_t *const kUPenc,
|
||||
uint8_t *const kUPint
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
|
||||
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
|
||||
#endif
|
||||
,rb_id_t *const defaultDRB,
|
||||
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
|
||||
|
||||
@@ -1661,45 +1659,40 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB
|
||||
uint8_t *kRRCenc = NULL;
|
||||
uint8_t *kUPenc = NULL;
|
||||
uint8_t *kRRCint = NULL;
|
||||
pdcp_t *pdcp_p = NULL;
|
||||
hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE;
|
||||
hashtable_rc_t h_rc;
|
||||
key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, DCCH, SRB_FLAG_YES);
|
||||
h_rc = hashtable_get(pdcp_coll_p, key, (void **) &pdcp_p);
|
||||
nr_derive_key_up_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb,
|
||||
&kUPenc);
|
||||
nr_derive_key_rrc_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb,
|
||||
&kRRCenc);
|
||||
nr_derive_key_rrc_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb,
|
||||
&kRRCint);
|
||||
LOG_I(NR_RRC, "driving kRRCenc, kRRCint and kUPenc from KgNB="
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x\n",
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[0], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[1], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[2], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[3],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[4], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[5], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[6], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[7],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[8], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[9], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[10], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[11],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[12], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[13], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[14], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[15],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[16], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[17], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[18], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[19],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[20], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[21], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[22], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[23],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[24], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[25], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[26], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[27],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[28], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[29], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[30], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[31]);
|
||||
|
||||
if (h_rc == HASH_TABLE_OK) {
|
||||
LOG_D(NR_RRC, "PDCP_COLL_KEY_VALUE() returns valid key = %ld\n", key);
|
||||
LOG_D(NR_RRC, "driving kRRCenc, kRRCint and kUPenc from KgNB="
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x\n",
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[0], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[1], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[2], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[3],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[4], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[5], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[6], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[7],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[8], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[9], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[10], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[11],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[12], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[13], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[14], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[15],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[16], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[17], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[18], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[19],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[20], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[21], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[22], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[23],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[24], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[25], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[26], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[27],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[28], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[29], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[30], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[31]);
|
||||
derive_key_rrc_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCenc);
|
||||
derive_key_rrc_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCint);
|
||||
derive_key_up_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kUPenc);
|
||||
|
||||
if (securityMode != 0xff) {
|
||||
pdcp_config_set_security(ctxt_pP, pdcp_p, 0, 0,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm
|
||||
| (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4),
|
||||
kRRCenc, kRRCint, kUPenc);
|
||||
} else {
|
||||
LOG_I(NR_RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x", securityMode);
|
||||
}
|
||||
if (securityMode != 0xff) {
|
||||
pdcp_config_set_security(ctxt_pP, NULL, DCCH, DCCH+2,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm
|
||||
| (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4),
|
||||
kRRCenc, kRRCint, kUPenc);
|
||||
} else {
|
||||
LOG_I(NR_RRC, "Could not get PDCP instance where key=0x%ld\n", key);
|
||||
LOG_I(NR_RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x", securityMode);
|
||||
}
|
||||
|
||||
if (securityModeCommand->criticalExtensions.present == NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand) {
|
||||
@@ -2044,21 +2037,12 @@ nr_rrc_ue_establish_srb2(
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t *k_kdf = NULL;
|
||||
uint8_t *kRRCenc = NULL;
|
||||
uint8_t *kRRCint = NULL;
|
||||
nr_derive_key_rrc_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &k_kdf);
|
||||
kRRCenc = malloc(16);
|
||||
if (kRRCenc == NULL) exit(1);
|
||||
memcpy(kRRCenc, k_kdf + 16, 16);
|
||||
free(k_kdf);
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCenc);
|
||||
nr_derive_key_rrc_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &k_kdf);
|
||||
kRRCint = malloc(16);
|
||||
if (kRRCint == NULL) exit(1);
|
||||
memcpy(kRRCint, k_kdf + 16, 16);
|
||||
free(k_kdf);
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCint);
|
||||
|
||||
// Refresh SRBs
|
||||
nr_rrc_pdcp_config_asn1_req(ctxt_pP,
|
||||
@@ -2100,6 +2084,7 @@ nr_rrc_ue_establish_srb2(
|
||||
|
||||
LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SRB1 gNB %d) --->][MAC_UE][MOD %02d][]\n",
|
||||
ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id);
|
||||
nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,gNB_index,1,true); //todo handle mac_LogicalChannelConfig
|
||||
// rrc_mac_config_req_ue
|
||||
}
|
||||
} else {
|
||||
@@ -2115,6 +2100,7 @@ nr_rrc_ue_establish_srb2(
|
||||
|
||||
LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SRB2 gNB %d) --->][MAC_UE][MOD %02d][]\n",
|
||||
ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id);
|
||||
nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,gNB_index,2,true); //todo handle mac_LogicalChannelConfig
|
||||
// rrc_mac_config_req_ue
|
||||
}
|
||||
} // srb2
|
||||
@@ -2135,28 +2121,33 @@ nr_rrc_ue_establish_srb2(
|
||||
memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1],
|
||||
radioBearerConfig->drb_ToAddModList->list.array[cnt], sizeof(NR_DRB_ToAddMod_t));
|
||||
} else {
|
||||
LOG_D(NR_RRC, "Adding DRB %ld %p\n", DRB_id-1, radioBearerConfig->drb_ToAddModList->list.array[cnt]);
|
||||
//LOG_D(NR_RRC, "Adding DRB %ld %p\n", DRB_id-1, radioBearerConfig->drb_ToAddModList->list.array[cnt]);
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1] = radioBearerConfig->drb_ToAddModList->list.array[cnt];
|
||||
int j;
|
||||
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list = NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList;
|
||||
if (rlc_bearer2add_list != NULL) {
|
||||
for(j = 0; j < rlc_bearer2add_list->list.count; j++){
|
||||
if(rlc_bearer2add_list->list.array[j]->servedRadioBearer != NULL){
|
||||
if(rlc_bearer2add_list->list.array[j]->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity){
|
||||
if(DRB_id == rlc_bearer2add_list->list.array[j]->servedRadioBearer->choice.drb_Identity){
|
||||
LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (DRB lcid %ld gNB %d) --->][MAC_UE][MOD %02d][]\n",
|
||||
ctxt_pP->frame, ctxt_pP->module_id, rlc_bearer2add_list->list.array[j]->logicalChannelIdentity, 0, ctxt_pP->module_id);
|
||||
nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,0,rlc_bearer2add_list->list.array[j]->logicalChannelIdentity,true); //todo handle mac_LogicalChannelConfig
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t *k_kdf = NULL;
|
||||
uint8_t *kUPenc = NULL;
|
||||
uint8_t *kUPint = NULL;
|
||||
|
||||
nr_derive_key_up_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &k_kdf);
|
||||
kUPenc = malloc(16);
|
||||
if (kUPenc == NULL) exit(1);
|
||||
memcpy(kUPenc, k_kdf + 16, 16);
|
||||
free(k_kdf);
|
||||
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kUPenc);
|
||||
nr_derive_key_up_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &k_kdf);
|
||||
kUPint = malloc(16);
|
||||
if (kUPint == NULL) exit(1);
|
||||
memcpy(kUPint, k_kdf + 16, 16);
|
||||
free(k_kdf);
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kUPint);
|
||||
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
MSC_RRC_UE,
|
||||
@@ -2199,6 +2190,15 @@ nr_rrc_ue_establish_srb2(
|
||||
}
|
||||
}
|
||||
|
||||
if (NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToReleaseList != NULL) {
|
||||
for (i = 0; i < NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToReleaseList->list.count; i++) {
|
||||
NR_LogicalChannelIdentity_t lcid = *NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToReleaseList->list.array[i];
|
||||
LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (RB lcid %ld gNB %d release) --->][MAC_UE][MOD %02d][]\n",
|
||||
ctxt_pP->frame, ctxt_pP->module_id, lcid, 0, ctxt_pP->module_id);
|
||||
nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,0,lcid,false); //todo handle mac_LogicalChannelConfig
|
||||
}
|
||||
}
|
||||
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State = NR_RRC_CONNECTED;
|
||||
LOG_I(NR_RRC,"[UE %d] State = NR_RRC_CONNECTED (gNB %d)\n", ctxt_pP->module_id, gNB_index);
|
||||
}
|
||||
@@ -2511,6 +2511,28 @@ nr_rrc_ue_establish_srb2(
|
||||
NR_RRC_DCCH_DATA_IND (msg_p).gNB_index);
|
||||
break;
|
||||
|
||||
case NAS_KENB_REFRESH_REQ:
|
||||
memcpy((void *)NR_UE_rrc_inst[ue_mod_id].kgnb, (void *)NAS_KENB_REFRESH_REQ(msg_p).kenb, sizeof(NR_UE_rrc_inst[ue_mod_id].kgnb));
|
||||
LOG_D(RRC, "[UE %d] Received %s: refreshed RRC::KgNB = "
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x\n",
|
||||
ue_mod_id, ITTI_MSG_NAME (msg_p),
|
||||
NR_UE_rrc_inst[ue_mod_id].kgnb[0], NR_UE_rrc_inst[ue_mod_id].kgnb[1], NR_UE_rrc_inst[ue_mod_id].kgnb[2], NR_UE_rrc_inst[ue_mod_id].kgnb[3],
|
||||
NR_UE_rrc_inst[ue_mod_id].kgnb[4], NR_UE_rrc_inst[ue_mod_id].kgnb[5], NR_UE_rrc_inst[ue_mod_id].kgnb[6], NR_UE_rrc_inst[ue_mod_id].kgnb[7],
|
||||
NR_UE_rrc_inst[ue_mod_id].kgnb[8], NR_UE_rrc_inst[ue_mod_id].kgnb[9], NR_UE_rrc_inst[ue_mod_id].kgnb[10], NR_UE_rrc_inst[ue_mod_id].kgnb[11],
|
||||
NR_UE_rrc_inst[ue_mod_id].kgnb[12], NR_UE_rrc_inst[ue_mod_id].kgnb[13], NR_UE_rrc_inst[ue_mod_id].kgnb[14], NR_UE_rrc_inst[ue_mod_id].kgnb[15],
|
||||
NR_UE_rrc_inst[ue_mod_id].kgnb[16], NR_UE_rrc_inst[ue_mod_id].kgnb[17], NR_UE_rrc_inst[ue_mod_id].kgnb[18], NR_UE_rrc_inst[ue_mod_id].kgnb[19],
|
||||
NR_UE_rrc_inst[ue_mod_id].kgnb[20], NR_UE_rrc_inst[ue_mod_id].kgnb[21], NR_UE_rrc_inst[ue_mod_id].kgnb[22], NR_UE_rrc_inst[ue_mod_id].kgnb[23],
|
||||
NR_UE_rrc_inst[ue_mod_id].kgnb[24], NR_UE_rrc_inst[ue_mod_id].kgnb[25], NR_UE_rrc_inst[ue_mod_id].kgnb[26], NR_UE_rrc_inst[ue_mod_id].kgnb[27],
|
||||
NR_UE_rrc_inst[ue_mod_id].kgnb[28], NR_UE_rrc_inst[ue_mod_id].kgnb[29], NR_UE_rrc_inst[ue_mod_id].kgnb[30], NR_UE_rrc_inst[ue_mod_id].kgnb[31]);
|
||||
break;
|
||||
|
||||
case NAS_UPLINK_DATA_REQ: {
|
||||
uint32_t length;
|
||||
uint8_t *buffer;
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "nr_sdap_gnb.h"
|
||||
#include <openair2/LAYER2/PDCP_v10.1.0/pdcp.h>
|
||||
|
||||
boolean_t sdap_gnb_data_req(protocol_ctxt_t *ctxt_p,
|
||||
const srb_flag_t srb_flag,
|
||||
const rb_id_t rb_id,
|
||||
const mui_t mui,
|
||||
const confirm_t confirm,
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
unsigned char *const sdu_buffer,
|
||||
const pdcp_transmission_mode_t pt_mode,
|
||||
const uint32_t *sourceL2Id,
|
||||
const uint32_t *destinationL2Id
|
||||
) {
|
||||
if(sdu_buffer == NULL) {
|
||||
LOG_E(PDCP, "%s:%d:%s: SDAP Layer gNB - NULL sdu_buffer \n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(sdu_buffer_size == 0) {
|
||||
LOG_E(PDCP, "%s:%d:%s: SDAP Layer gNB - NULL or 0 sdu_buffer_size \n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uint8_t *sdap_buf = (uint8_t *)malloc(sdu_buffer_size+SDAP_HDR_LENGTH);
|
||||
nr_sdap_dl_hdr_t sdap_hdr;
|
||||
sdap_hdr.RDI = 0; // SDAP_Hardcoded -
|
||||
sdap_hdr.RQI = 0; // SDAP_Hardcoded - Should get this info from DL_PDU_SESSION_INFORMATION
|
||||
sdap_hdr.QFI = 1; // SDAP_Hardcoded - Should get this info from DL_PDU_SESSION_INFORMATION
|
||||
memcpy(&sdap_buf[0], &sdap_hdr, 1);
|
||||
memcpy(&sdap_buf[1], sdu_buffer, sdu_buffer_size);
|
||||
rb_id_t sdap_drb_id = rb_id; // SDAP_Hardcoded - Should get this info from QFI to DRB mapping table
|
||||
boolean_t ret = pdcp_data_req(ctxt_p,
|
||||
srb_flag,
|
||||
sdap_drb_id,
|
||||
mui,
|
||||
confirm,
|
||||
sdu_buffer_size+1,
|
||||
sdap_buf,
|
||||
pt_mode,
|
||||
sourceL2Id,
|
||||
destinationL2Id);
|
||||
|
||||
if(!ret) {
|
||||
LOG_E(PDCP, "%s:%d:%s: SDAP Layer gNB - PDCP DL refused PDU\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
free(sdap_buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
free(sdap_buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void sdap_gnb_ul_header_handler(char sdap_gnb_ul_hdr) {
|
||||
nr_sdap_ul_hdr_t *sdap_hdr_ul = (nr_sdap_ul_hdr_t *)&sdap_gnb_ul_hdr;
|
||||
|
||||
switch (sdap_hdr_ul->DC) {
|
||||
case SDAP_HDR_UL_DATA_PDU:
|
||||
LOG_I(PDCP, "%s:%d:%s: SDAP Layer gNB - UL Received SDAP Data PDU\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
break;
|
||||
|
||||
case SDAP_HDR_UL_CTRL_PDU:
|
||||
LOG_I(PDCP, "%s:%d:%s: SDAP Layer gNB - Received SDAP Control PDU\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef _NR_SDAP_GNB_
|
||||
#define _NR_SDAP_GNB_
|
||||
|
||||
#include "openair2/COMMON/platform_types.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
|
||||
#define SDAP_BITMASK_DC (0x80)
|
||||
#define SDAP_BITMASK_R (0x40)
|
||||
#define SDAP_BITMASK_QFI (0x3F)
|
||||
#define SDAP_HDR_UL_DATA_PDU (1)
|
||||
#define SDAP_HDR_UL_CTRL_PDU (0)
|
||||
#define SDAP_HDR_LENGTH (1)
|
||||
|
||||
typedef struct nr_sdap_dl_hdr_s {
|
||||
uint8_t QFI:6;
|
||||
uint8_t RQI:1;
|
||||
uint8_t RDI:1;
|
||||
} __attribute__((packed)) nr_sdap_dl_hdr_t;
|
||||
|
||||
typedef struct nr_sdap_ul_hdr_s {
|
||||
uint8_t QFI:6;
|
||||
uint8_t R:1;
|
||||
uint8_t DC:1;
|
||||
} __attribute__((packed)) nr_sdap_ul_hdr_t;
|
||||
|
||||
boolean_t sdap_gnb_data_req(protocol_ctxt_t *ctxt_p,
|
||||
const srb_flag_t srb_flag,
|
||||
const rb_id_t rb_id,
|
||||
const mui_t mui,
|
||||
const confirm_t confirm,
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
unsigned char *const sdu_buffer,
|
||||
const pdcp_transmission_mode_t pt_mode,
|
||||
const uint32_t *sourceL2Id,
|
||||
const uint32_t *destinationL2Id
|
||||
);
|
||||
|
||||
void sdap_gnb_ul_header_handler(char sdap_gnb_ul_hdr);
|
||||
|
||||
#endif
|
||||
@@ -121,6 +121,8 @@ int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id,
|
||||
string[6] = 0x01;
|
||||
|
||||
kdf(string, 7, key, 32, out, 32);
|
||||
// in NR, we use the last 16 bytes, ignoring the first 16 ones
|
||||
memcpy(*out, *out+16, 16);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,8 @@
|
||||
uint8_t *registration_request_buf;
|
||||
uint32_t registration_request_len;
|
||||
extern char *baseNetAddress;
|
||||
extern uint16_t NB_UE_INST;
|
||||
static ue_sa_security_key_t ** ue_security_key;
|
||||
|
||||
static int nas_protected_security_header_encode(
|
||||
char *buffer,
|
||||
@@ -251,6 +253,108 @@ void derive_knas(algorithm_type_dist_t nas_alg_type, uint8_t nas_alg_id, uint8_t
|
||||
knas_int[i] = out[16 + i];
|
||||
}
|
||||
|
||||
void derive_kgnb(uint8_t kamf[32], uint32_t count, uint8_t *kgnb){
|
||||
/* Compute the KDF input parameter
|
||||
* S = FC(0x6E) || UL NAS Count || 0x00 0x04 || 0x01 || 0x00 0x01
|
||||
*/
|
||||
uint8_t input[32];
|
||||
// uint16_t length = 4;
|
||||
// int offset = 0;
|
||||
uint8_t out[32] = { 0 };
|
||||
|
||||
LOG_TRACE(INFO, "%s with count= %d", __FUNCTION__, count);
|
||||
memset(input, 0, 32);
|
||||
input[0] = 0x6E;
|
||||
// P0
|
||||
input[1] = count >> 24;
|
||||
input[2] = (uint8_t)(count >> 16);
|
||||
input[3] = (uint8_t)(count >> 8);
|
||||
input[4] = (uint8_t)count;
|
||||
// L0
|
||||
input[5] = 0;
|
||||
input[6] = 4;
|
||||
// P1
|
||||
input[7] = 0x01;
|
||||
// L1
|
||||
input[8] = 0;
|
||||
input[9] = 1;
|
||||
|
||||
kdf(kamf, 32, input, 10, out, 32);
|
||||
for (int i = 0; i < 32; i++)
|
||||
kgnb[i] = out[i];
|
||||
printf("kgnb : ");
|
||||
for(int pp=0;pp<32;pp++)
|
||||
printf("%02x ",kgnb[pp]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void derive_ue_keys(int Mod_id, uint8_t *buf, uicc_t *uicc) {
|
||||
uint8_t ak[6];
|
||||
uint8_t sqn[6];
|
||||
|
||||
AssertFatal (Mod_id < NB_UE_INST, "Failed, Mod_id %d is over NB_UE_INST!\n", Mod_id);
|
||||
if(ue_security_key[Mod_id]){
|
||||
// clear old key
|
||||
memset(ue_security_key[Mod_id],0,sizeof(ue_sa_security_key_t));
|
||||
}else{
|
||||
// Allocate new memory
|
||||
ue_security_key[Mod_id]=(ue_sa_security_key_t *)calloc(1,sizeof(ue_sa_security_key_t));
|
||||
}
|
||||
uint8_t *kausf = ue_security_key[Mod_id]->kausf;
|
||||
uint8_t *kseaf = ue_security_key[Mod_id]->kseaf;
|
||||
uint8_t *kamf = ue_security_key[Mod_id]->kamf;
|
||||
uint8_t *knas_int = ue_security_key[Mod_id]->knas_int;
|
||||
uint8_t *output = ue_security_key[Mod_id]->res;
|
||||
uint8_t *rand = ue_security_key[Mod_id]->rand;
|
||||
uint8_t *kgnb = ue_security_key[Mod_id]->kgnb;
|
||||
|
||||
// get RAND for authentication request
|
||||
for(int index = 0; index < 16;index++){
|
||||
rand[index] = buf[8+index];
|
||||
}
|
||||
|
||||
uint8_t resTemp[16];
|
||||
uint8_t ck[16], ik[16];
|
||||
f2345(uicc->key, rand, resTemp, ck, ik, ak, uicc->opc);
|
||||
|
||||
transferRES(ck, ik, resTemp, rand, output, uicc);
|
||||
|
||||
for(int index = 0; index < 6; index++){
|
||||
sqn[index] = buf[26+index];
|
||||
}
|
||||
|
||||
derive_kausf(ck, ik, sqn, kausf, uicc);
|
||||
derive_kseaf(kausf, kseaf, uicc);
|
||||
derive_kamf(kseaf, kamf, 0x0000, uicc);
|
||||
derive_knas(0x02, 2, kamf, knas_int);
|
||||
derive_kgnb(kamf,0,kgnb);
|
||||
|
||||
printf("kausf:");
|
||||
for(int i = 0; i < 32; i++){
|
||||
printf("%x ", kausf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("kseaf:");
|
||||
for(int i = 0; i < 32; i++){
|
||||
printf("%x ", kseaf[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
printf("kamf:");
|
||||
for(int i = 0; i < 32; i++){
|
||||
printf("%x ", kamf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("knas_int:\n");
|
||||
for(int i = 0; i < 16; i++){
|
||||
printf("%x ", knas_int[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void generateRegistrationRequest(as_nas_info_t *initialNasMsg, int Mod_id) {
|
||||
int size = sizeof(mm_msg_header_t);
|
||||
fgs_nas_message_t nas_msg={0};
|
||||
@@ -373,69 +477,13 @@ void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype
|
||||
|
||||
}
|
||||
|
||||
OctetString knas_int;
|
||||
static void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf, uicc_t *uicc){
|
||||
static void generateAuthenticationResp(int Mod_id,as_nas_info_t *initialNasMsg, uint8_t *buf, uicc_t *uicc){
|
||||
|
||||
uint8_t ak[6];
|
||||
|
||||
uint8_t kausf[32];
|
||||
uint8_t sqn[6];
|
||||
uint8_t kseaf[32];
|
||||
uint8_t kamf[32];
|
||||
derive_ue_keys(Mod_id,buf,uicc);
|
||||
OctetString res;
|
||||
|
||||
// get RAND for authentication request
|
||||
unsigned char rand[16];
|
||||
for(int index = 0; index < 16;index++){
|
||||
rand[index] = buf[8+index];
|
||||
}
|
||||
|
||||
uint8_t resTemp[16];
|
||||
uint8_t ck[16], ik[16], output[16];
|
||||
f2345(uicc->key, rand, resTemp, ck, ik, ak, uicc->opc);
|
||||
|
||||
transferRES(ck, ik, resTemp, rand, output, uicc);
|
||||
|
||||
// get knas_int
|
||||
knas_int.length = 16;
|
||||
knas_int.value = malloc(knas_int.length);
|
||||
for(int index = 0; index < 6; index++){
|
||||
sqn[index] = buf[26+index];
|
||||
}
|
||||
|
||||
derive_kausf(ck, ik, sqn, kausf, uicc);
|
||||
derive_kseaf(kausf, kseaf, uicc);
|
||||
derive_kamf(kseaf, kamf, 0x0000, uicc);
|
||||
derive_knas(0x02, 2, kamf, knas_int.value);
|
||||
|
||||
printf("kausf:");
|
||||
for(int i = 0; i < 32; i++){
|
||||
printf("%x ", kausf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("kseaf:");
|
||||
for(int i = 0; i < 32; i++){
|
||||
printf("%x ", kseaf[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
printf("kamf:");
|
||||
for(int i = 0; i < 32; i++){
|
||||
printf("%x ", kamf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("knas_int:\n");
|
||||
for(int i = 0; i < 16; i++){
|
||||
printf("%x ", knas_int.value[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// set res
|
||||
res.length = 16;
|
||||
res.value = output;
|
||||
res.value = calloc(1,16);
|
||||
memcpy(res.value,ue_security_key[Mod_id]->res,16);
|
||||
|
||||
int size = sizeof(mm_msg_header_t);
|
||||
fgs_nas_message_t nas_msg;
|
||||
@@ -465,7 +513,14 @@ static void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *bu
|
||||
initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size);
|
||||
}
|
||||
|
||||
static void generateSecurityModeComplete(as_nas_info_t *initialNasMsg)
|
||||
int nas_itti_kgnb_refresh_req(const uint8_t kgnb[32], int instance) {
|
||||
MessageDef *message_p;
|
||||
message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_KENB_REFRESH_REQ);
|
||||
memcpy(NAS_KENB_REFRESH_REQ(message_p).kenb, kgnb, sizeof(NAS_KENB_REFRESH_REQ(message_p).kenb));
|
||||
return itti_send_msg_to_task(TASK_RRC_NRUE, instance, message_p);
|
||||
}
|
||||
|
||||
static void generateSecurityModeComplete(int Mod_id,as_nas_info_t *initialNasMsg)
|
||||
{
|
||||
int size = sizeof(mm_msg_header_t);
|
||||
fgs_nas_message_t nas_msg;
|
||||
@@ -512,7 +567,7 @@ static void generateSecurityModeComplete(as_nas_info_t *initialNasMsg)
|
||||
|
||||
initialNasMsg->length = security_header_len + mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data+security_header_len), size-security_header_len);
|
||||
|
||||
stream_cipher.key = knas_int.value;
|
||||
stream_cipher.key = ue_security_key[Mod_id]->knas_int;
|
||||
stream_cipher.key_length = 16;
|
||||
stream_cipher.count = 0;
|
||||
stream_cipher.bearer = 1;
|
||||
@@ -532,7 +587,7 @@ static void generateSecurityModeComplete(as_nas_info_t *initialNasMsg)
|
||||
}
|
||||
}
|
||||
|
||||
static void generateRegistrationComplete(as_nas_info_t *initialNasMsg, SORTransparentContainer *sortransparentcontainer) {
|
||||
static void generateRegistrationComplete(int Mod_id, as_nas_info_t *initialNasMsg, SORTransparentContainer *sortransparentcontainer) {
|
||||
//wait send RRCReconfigurationComplete and InitialContextSetupResponse
|
||||
sleep(1);
|
||||
int length = 0;
|
||||
@@ -592,7 +647,7 @@ static void generateRegistrationComplete(as_nas_info_t *initialNasMsg, SORTransp
|
||||
}
|
||||
|
||||
initialNasMsg->length = length;
|
||||
stream_cipher.key = knas_int.value;
|
||||
stream_cipher.key = ue_security_key[Mod_id]->knas_int;
|
||||
stream_cipher.key_length = 16;
|
||||
stream_cipher.count = 1;
|
||||
stream_cipher.bearer = 1;
|
||||
@@ -625,7 +680,7 @@ void decodeDownlinkNASTransport(as_nas_info_t *initialNasMsg, uint8_t * pdu_buff
|
||||
}
|
||||
}
|
||||
|
||||
static void generatePduSessionEstablishRequest(uicc_t * uicc, as_nas_info_t *initialNasMsg){
|
||||
static void generatePduSessionEstablishRequest(int Mod_id, uicc_t * uicc, as_nas_info_t *initialNasMsg){
|
||||
//wait send RegistrationComplete
|
||||
usleep(100*150);
|
||||
int size = 0;
|
||||
@@ -699,7 +754,7 @@ static void generatePduSessionEstablishRequest(uicc_t * uicc, as_nas_info_t *ini
|
||||
|
||||
initialNasMsg->length = security_header_len + mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data+security_header_len), size-security_header_len);
|
||||
|
||||
stream_cipher.key = knas_int.value;
|
||||
stream_cipher.key = ue_security_key[Mod_id]->knas_int;
|
||||
stream_cipher.key_length = 16;
|
||||
stream_cipher.count = 0;
|
||||
stream_cipher.bearer = 1;
|
||||
@@ -729,6 +784,8 @@ void *nas_nrue_task(void *args_p)
|
||||
uint8_t msg_type = 0;
|
||||
uint8_t *pdu_buffer = NULL;
|
||||
|
||||
|
||||
ue_security_key=(ue_sa_security_key_t **)calloc(1,sizeof(ue_sa_security_key_t*)*NB_UE_INST);
|
||||
itti_mark_task_ready (TASK_NAS_NRUE);
|
||||
MSC_START_USE();
|
||||
|
||||
@@ -813,7 +870,7 @@ void *nas_nrue_task(void *args_p)
|
||||
|
||||
as_nas_info_t initialNasMsg;
|
||||
memset(&initialNasMsg, 0, sizeof(as_nas_info_t));
|
||||
generateRegistrationComplete(&initialNasMsg, NULL);
|
||||
generateRegistrationComplete(Mod_id,&initialNasMsg, NULL);
|
||||
if(initialNasMsg.length > 0){
|
||||
MessageDef *message_p;
|
||||
message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_UPLINK_DATA_REQ);
|
||||
@@ -826,7 +883,7 @@ void *nas_nrue_task(void *args_p)
|
||||
|
||||
as_nas_info_t pduEstablishMsg;
|
||||
memset(&pduEstablishMsg, 0, sizeof(as_nas_info_t));
|
||||
generatePduSessionEstablishRequest(uicc, &pduEstablishMsg);
|
||||
generatePduSessionEstablishRequest(Mod_id, uicc, &pduEstablishMsg);
|
||||
if(pduEstablishMsg.length > 0){
|
||||
MessageDef *message_p;
|
||||
message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_UPLINK_DATA_REQ);
|
||||
@@ -893,10 +950,11 @@ void *nas_nrue_task(void *args_p)
|
||||
generateIdentityResponse(&initialNasMsg,*(pdu_buffer+3), uicc);
|
||||
break;
|
||||
case FGS_AUTHENTICATION_REQUEST:
|
||||
generateAuthenticationResp(&initialNasMsg, pdu_buffer, uicc);
|
||||
generateAuthenticationResp(Mod_id,&initialNasMsg, pdu_buffer, uicc);
|
||||
break;
|
||||
case FGS_SECURITY_MODE_COMMAND:
|
||||
generateSecurityModeComplete(&initialNasMsg);
|
||||
nas_itti_kgnb_refresh_req(ue_security_key[Mod_id]->kgnb, instance);
|
||||
generateSecurityModeComplete(Mod_id,&initialNasMsg);
|
||||
break;
|
||||
case FGS_DOWNLINK_NAS_TRANSPORT:
|
||||
decodeDownlinkNASTransport(&initialNasMsg, pdu_buffer);
|
||||
|
||||
@@ -64,6 +64,16 @@
|
||||
|
||||
#define INITIAL_REGISTRATION 0b001
|
||||
|
||||
/* Security Key for SA UE */
|
||||
typedef struct {
|
||||
uint8_t kausf[32];
|
||||
uint8_t kseaf[32];
|
||||
uint8_t kamf[32];
|
||||
uint8_t knas_int[16];
|
||||
uint8_t res[16];
|
||||
uint8_t rand[16];
|
||||
uint8_t kgnb[32];
|
||||
} ue_sa_security_key_t;
|
||||
|
||||
typedef enum fgs_protocol_discriminator_e {
|
||||
/* Protocol discriminator identifier for 5GS Mobility Management */
|
||||
|
||||
@@ -17,6 +17,7 @@ extern "C" {
|
||||
#include <openair2/COMMON/gtpv1_u_messages_types.h>
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
#include <openair2/LAYER2/PDCP_v10.1.0/pdcp.h>
|
||||
#include "openair2/SDAP/nr_sdap/nr_sdap_gnb.h"
|
||||
//#include <openair1/PHY/phy_extern.h>
|
||||
|
||||
#pragma pack(1)
|
||||
@@ -539,8 +540,8 @@ int gtpv1u_create_ngu_tunnel( const instance_t instance,
|
||||
create_tunnel_req->incoming_rb_id[i],
|
||||
create_tunnel_req->pdusession_id[i],
|
||||
create_tunnel_req->upf_NGu_teid[i],
|
||||
create_tunnel_req->upf_addr[i], dstport,
|
||||
pdcp_data_req);
|
||||
create_tunnel_req->upf_addr[i], dstport,
|
||||
sdap_gnb_data_req);
|
||||
create_tunnel_resp->status=0;
|
||||
create_tunnel_resp->rnti=create_tunnel_req->rnti;
|
||||
create_tunnel_resp->num_tunnels=create_tunnel_req->num_tunnels;
|
||||
|
||||
@@ -230,7 +230,6 @@ MACRLCs = (
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
ulsch_max_slots_inactivity = 10;
|
||||
pusch_TargetSNRx10 = 150;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
}
|
||||
|
||||
@@ -230,7 +230,6 @@ MACRLCs = (
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
ulsch_max_slots_inactivity = 10;
|
||||
pusch_TargetSNRx10 = 150;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user