Commit e8801412 authored by Raphael Defosseux's avatar Raphael Defosseux

Merge branch 'develop_integration_2019_w36' into 'develop'

Develop Integration Branch: 2019 week 36

The following MR are included:

* MR 653 : Feature LTE-M PUSCH CE - 8 Repetitions
* MR 654 : Rfsimu config and CI scripting updates
parents 5ddad9bd ed2b7752
...@@ -57,6 +57,7 @@ pipeline { ...@@ -57,6 +57,7 @@ pipeline {
echo '\u2705 \u001B[32mVerify Parameters\u001B[0m' echo '\u2705 \u001B[32mVerify Parameters\u001B[0m'
def allParametersPresent = true def allParametersPresent = true
echo "Platform is ${TESTPLATFORM_OWNER}"
if (params.RedHatRemoteServer == null) { if (params.RedHatRemoteServer == null) {
allParametersPresent = false allParametersPresent = false
......
...@@ -44,7 +44,7 @@ function build_on_vm { ...@@ -44,7 +44,7 @@ function build_on_vm {
STATUS=1 STATUS=1
return return
fi fi
if [ ! -f /etc/apt/apt.conf.d/01proxy ] if [[ ! -f /etc/apt/apt.conf.d/01proxy ]] && [[ "$OPTIONAL_APTCACHER" != "true" ]]
then then
echo "Missing /etc/apt/apt.conf.d/01proxy file!" echo "Missing /etc/apt/apt.conf.d/01proxy file!"
echo "Is apt-cacher installed and configured?" echo "Is apt-cacher installed and configured?"
...@@ -96,12 +96,12 @@ function build_on_vm { ...@@ -96,12 +96,12 @@ function build_on_vm {
else else
scp -o StrictHostKeyChecking=no $JENKINS_WKSP/localZip.zip ubuntu@$VM_IP_ADDR:/home/ubuntu scp -o StrictHostKeyChecking=no $JENKINS_WKSP/localZip.zip ubuntu@$VM_IP_ADDR:/home/ubuntu
fi fi
scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$VM_IP_ADDR:/home/ubuntu [ -f /etc/apt/apt.conf.d/01proxy ] && scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$VM_IP_ADDR:/home/ubuntu
echo "############################################################" echo "############################################################"
echo "Running install and build script on VM ($VM_NAME)" echo "Running install and build script on VM ($VM_NAME)"
echo "############################################################" echo "############################################################"
echo "sudo cp 01proxy /etc/apt/apt.conf.d/" > $VM_CMDS echo "[ -f 01proxy ] && sudo cp 01proxy /etc/apt/apt.conf.d/" > $VM_CMDS
echo "touch /home/ubuntu/.hushlogin" >> $VM_CMDS echo "touch /home/ubuntu/.hushlogin" >> $VM_CMDS
if [[ "$VM_NAME" == *"-cppcheck"* ]] if [[ "$VM_NAME" == *"-cppcheck"* ]]
then then
......
...@@ -233,6 +233,7 @@ eNBs = ...@@ -233,6 +233,7 @@ eNBs =
#pdsch_maxNumRepetitionCEmodeB_r13 = "r384"; # NULL - 2 #pdsch_maxNumRepetitionCEmodeB_r13 = "r384"; # NULL - 2
pusch_maxNumRepetitionCEmodeA_r13 = "r8"; #0 pusch_maxNumRepetitionCEmodeA_r13 = "r8"; #0
pusch_repetitionLevelCEmodeA_r13 = "l1";
#pusch_maxNumRepetitionCEmodeB_r13 = "r768"; #4 #NULL #pusch_maxNumRepetitionCEmodeB_r13 = "r768"; #4 #NULL
#pusch_HoppingOffset_v1310 = 5; #NULL #pusch_HoppingOffset_v1310 = 5; #NULL
......
...@@ -521,6 +521,35 @@ class SSHConnection(): ...@@ -521,6 +521,35 @@ class SSHConnection():
# here add a check if git clone or git fetch went smoothly # here add a check if git clone or git fetch went smoothly
self.command('git config user.email "jenkins@openairinterface.org"', '\$', 5) self.command('git config user.email "jenkins@openairinterface.org"', '\$', 5)
self.command('git config user.name "OAI Jenkins"', '\$', 5) self.command('git config user.name "OAI Jenkins"', '\$', 5)
self.command('ls *.txt', '\$', 5)
result = re.search('LAST_BUILD_INFO', str(self.ssh.before))
if result is not None:
mismatch = False
self.command('grep SRC_COMMIT LAST_BUILD_INFO.txt', '\$', 2)
result = re.search(self.ranCommitID, str(self.ssh.before))
if result is None:
mismatch = True
self.command('grep MERGED_W_TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2)
if (self.ranAllowMerge):
result = re.search('YES', str(self.ssh.before))
if result is None:
mismatch = True
self.command('grep TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2)
if self.ranTargetBranch == '':
result = re.search('develop', str(self.ssh.before))
else:
result = re.search(self.ranTargetBranch, str(self.ssh.before))
if result is None:
mismatch = True
else:
result = re.search('NO', str(self.ssh.before))
if result is None:
mismatch = True
if not mismatch:
self.close()
self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK)
return
self.command('echo ' + self.UEPassword + ' | sudo -S git clean -x -d -ff', '\$', 30) self.command('echo ' + self.UEPassword + ' | sudo -S git clean -x -d -ff', '\$', 30)
# if the commit ID is provided use it to point to it # if the commit ID is provided use it to point to it
if self.ranCommitID != '': if self.ranCommitID != '':
...@@ -549,10 +578,22 @@ class SSHConnection(): ...@@ -549,10 +578,22 @@ class SSHConnection():
self.command('mkdir -p build_log_' + self.testCase_id, '\$', 5) self.command('mkdir -p build_log_' + self.testCase_id, '\$', 5)
self.command('mv log/* ' + 'build_log_' + self.testCase_id, '\$', 5) self.command('mv log/* ' + 'build_log_' + self.testCase_id, '\$', 5)
self.command('mv compile_oai_ue.log ' + 'build_log_' + self.testCase_id, '\$', 5) self.command('mv compile_oai_ue.log ' + 'build_log_' + self.testCase_id, '\$', 5)
self.close()
if buildStatus: if buildStatus:
# Generating a BUILD INFO file
self.command('echo "SRC_BRANCH: ' + self.ranBranch + '" > ../LAST_BUILD_INFO.txt', '\$', 2)
self.command('echo "SRC_COMMIT: ' + self.ranCommitID + '" >> ../LAST_BUILD_INFO.txt', '\$', 2)
if (self.ranAllowMerge):
self.command('echo "MERGED_W_TGT_BRANCH: YES" >> ../LAST_BUILD_INFO.txt', '\$', 2)
if self.ranTargetBranch == '':
self.command('echo "TGT_BRANCH: develop" >> ../LAST_BUILD_INFO.txt', '\$', 2)
else:
self.command('echo "TGT_BRANCH: ' + self.ranTargetBranch + '" >> ../LAST_BUILD_INFO.txt', '\$', 2)
else:
self.command('echo "MERGED_W_TGT_BRANCH: NO" >> ../LAST_BUILD_INFO.txt', '\$', 2)
self.close()
self.CreateHtmlTestRow(self.Build_OAI_UE_args, 'OK', ALL_PROCESSES_OK, 'OAI UE') self.CreateHtmlTestRow(self.Build_OAI_UE_args, 'OK', ALL_PROCESSES_OK, 'OAI UE')
else: else:
self.close()
logging.error('\u001B[1m Building OAI UE Failed\u001B[0m') logging.error('\u001B[1m Building OAI UE Failed\u001B[0m')
self.CreateHtmlTestRow(self.Build_OAI_UE_args, 'KO', ALL_PROCESSES_OK, 'OAI UE') self.CreateHtmlTestRow(self.Build_OAI_UE_args, 'KO', ALL_PROCESSES_OK, 'OAI UE')
self.CreateHtmlTabFooter(False) self.CreateHtmlTabFooter(False)
...@@ -1081,7 +1122,7 @@ class SSHConnection(): ...@@ -1081,7 +1122,7 @@ class SSHConnection():
html_queue = SimpleQueue() html_queue = SimpleQueue()
self.checkDevTTYisUnlocked() self.checkDevTTYisUnlocked()
if attach_status: if attach_status:
html_cell = '<pre style="background-color:white">CAT-M module\nAttachment Completed in ' + str(attach_cnt+4) + ' seconds' html_cell = '<pre style="background-color:white">CAT-M module Attachment Completed in ' + str(attach_cnt+4) + ' seconds'
if (nRSRQ is not None) and (nRSRP is not None): if (nRSRQ is not None) and (nRSRP is not None):
html_cell += '\n RSRQ = ' + str(-20+(nRSRQ/2)) + ' dB' html_cell += '\n RSRQ = ' + str(-20+(nRSRQ/2)) + ' dB'
html_cell += '\n RSRP = ' + str(-140+nRSRP) + ' dBm</pre>' html_cell += '\n RSRP = ' + str(-140+nRSRP) + ' dBm</pre>'
...@@ -1090,9 +1131,11 @@ class SSHConnection(): ...@@ -1090,9 +1131,11 @@ class SSHConnection():
html_queue.put(html_cell) html_queue.put(html_cell)
self.CreateHtmlTestRowQueue('N/A', 'OK', 1, html_queue) self.CreateHtmlTestRowQueue('N/A', 'OK', 1, html_queue)
else: else:
html_cell = '<pre style="background-color:white">CAT-M module\nAttachment Failed</pre>' logging.error('\u001B[1m CAT-M module Attachment Failed\u001B[0m')
html_cell = '<pre style="background-color:white">CAT-M module Attachment Failed</pre>'
html_queue.put(html_cell) html_queue.put(html_cell)
self.CreateHtmlTestRowQueue('N/A', 'KO', 1, html_queue) self.CreateHtmlTestRowQueue('N/A', 'KO', 1, html_queue)
self.AutoTerminateUEandeNB()
def PingCatM(self): def PingCatM(self):
if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '': if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '':
...@@ -1103,7 +1146,7 @@ class SSHConnection(): ...@@ -1103,7 +1146,7 @@ class SSHConnection():
pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE)
if (pStatus < 0): if (pStatus < 0):
self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
self.prematureExit = True self.AutoTerminateUEandeNB()
return return
try: try:
statusQueue = SimpleQueue() statusQueue = SimpleQueue()
...@@ -1122,6 +1165,8 @@ class SSHConnection(): ...@@ -1122,6 +1165,8 @@ class SSHConnection():
if result is not None: if result is not None:
moduleIPAddr = result.group('ipaddr') moduleIPAddr = result.group('ipaddr')
else: else:
self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
self.AutoTerminateUEandeNB()
return return
ping_time = re.findall("-c (\d+)",str(self.ping_args)) ping_time = re.findall("-c (\d+)",str(self.ping_args))
device_id = 'catm' device_id = 'catm'
...@@ -2353,15 +2398,16 @@ class SSHConnection(): ...@@ -2353,15 +2398,16 @@ class SSHConnection():
os.kill(os.getppid(),signal.SIGUSR1) os.kill(os.getppid(),signal.SIGUSR1)
def IperfNoS1(self): def IperfNoS1(self):
if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '':
Usage()
sys.exit('Insufficient Parameter')
check_eNB = True check_eNB = True
check_OAI_UE = True check_OAI_UE = True
pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE)
if (pStatus < 0): if (pStatus < 0):
self.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) self.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus)
self.AutoTerminateUEandeNB() self.AutoTerminateUEandeNB()
if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '': return
Usage()
sys.exit('Insufficient Parameter')
server_on_enb = re.search('-R', str(self.iperf_args)) server_on_enb = re.search('-R', str(self.iperf_args))
if server_on_enb is not None: if server_on_enb is not None:
iServerIPAddr = self.eNBIPAddress iServerIPAddr = self.eNBIPAddress
...@@ -3328,6 +3374,11 @@ class SSHConnection(): ...@@ -3328,6 +3374,11 @@ class SSHConnection():
self.ShowTestID() self.ShowTestID()
self.eNB_instance = '0' self.eNB_instance = '0'
self.TerminateeNB() self.TerminateeNB()
if self.flexranCtrlInstalled and self.flexranCtrlStarted:
self.testCase_id = 'AUTO-KILL-flexran-ctl'
self.desc = 'Automatic Termination of FlexRan CTL'
self.ShowTestID()
self.TerminateFlexranCtrl()
self.prematureExit = True self.prematureExit = True
def IdleSleep(self): def IdleSleep(self):
...@@ -4399,7 +4450,11 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re ...@@ -4399,7 +4450,11 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
while cnt < SSH.repeatCounts[0] and SSH.prematureExit: while cnt < SSH.repeatCounts[0] and SSH.prematureExit:
SSH.prematureExit = False SSH.prematureExit = False
for test_case_id in todo_tests: for test_case_id in todo_tests:
if SSH.prematureExit:
break
for test in all_tests: for test in all_tests:
if SSH.prematureExit:
break
id = test.get('id') id = test.get('id')
if test_case_id != id: if test_case_id != id:
continue continue
...@@ -4480,10 +4535,6 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re ...@@ -4480,10 +4535,6 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
SSH.Perform_X2_Handover() SSH.Perform_X2_Handover()
else: else:
sys.exit('Invalid action') sys.exit('Invalid action')
if SSH.prematureExit:
break
if SSH.prematureExit:
break
cnt += 1 cnt += 1
if cnt == SSH.repeatCounts[0] and SSH.prematureExit: if cnt == SSH.repeatCounts[0] and SSH.prematureExit:
logging.debug('Testsuite failed ' + str(cnt) + ' time(s)') logging.debug('Testsuite failed ' + str(cnt) + ' time(s)')
......
...@@ -140,10 +140,25 @@ function command_options_usage { ...@@ -140,10 +140,25 @@ function command_options_usage {
echo "" echo ""
} }
# function to set specific behavior depending on the TESTPLATFORM_OWNER variable
# which may be set by a jenkins server for exemple
function platform_set {
if [ "$TESTPLATFORM_OWNER" != "" ]
then
echo "Running on $TESTPLATFORM_OWNER platform"
if [ -x "/usr/local/bin/oai_${TESTPLATFORM_OWNER}_setenv.sh" ]
then
. /usr/local/bin/oai_${TESTPLATFORM_OWNER}_setenv.sh
fi
fi
}
function setvar_usage { function setvar_usage {
declare -A HELP_VAR declare -A HELP_VAR
HELP_VAR["VM_OSREL"]="OS release to use in virtual machines" HELP_VAR["VM_OSREL"]="OS release to use in virtual machines"
HELP_VAR["RUN_EXPERIMENTAL"]="Enforce execution of variants with EXPERIMENTAL variable set to \"true\"" HELP_VAR["RUN_EXPERIMENTAL"]="Enforce execution of variants with EXPERIMENTAL variable set to \"true\""
HELP_VAR["OPTIONAL_APTCACHER"]="build and Run tests will fail if apt-cacher not installed and this variable not set to \"true\""
HELP_VAR["TESTPLATFORM_OWNER"]="Allow pipeline customization via execution of an externel scripts residing on the jenkins server"
echo "--setvar_<varname> <value> where varname is one of:" echo "--setvar_<varname> <value> where varname is one of:"
for i in ${AUTHORIZED_VAR[@]}; do printf "%20s : %s\n" "$i" "${HELP_VAR[$i]}" ;done for i in ${AUTHORIZED_VAR[@]}; do printf "%20s : %s\n" "$i" "${HELP_VAR[$i]}" ;done
} }
...@@ -315,6 +330,7 @@ function check_setvar { ...@@ -315,6 +330,7 @@ function check_setvar {
exit 1 exit 1
} }
platform_set
MY_DIR=$(dirname $(readlink -f $0)) MY_DIR=$(dirname $(readlink -f $0))
. $MY_DIR/createVM.sh . $MY_DIR/createVM.sh
. $MY_DIR/buildOnVM.sh . $MY_DIR/buildOnVM.sh
...@@ -324,6 +340,7 @@ MY_DIR=$(dirname $(readlink -f $0)) ...@@ -324,6 +340,7 @@ MY_DIR=$(dirname $(readlink -f $0))
. $MY_DIR/reportBuildLocally.sh . $MY_DIR/reportBuildLocally.sh
. $MY_DIR/reportTestLocally.sh . $MY_DIR/reportTestLocally.sh
if [ $# -lt 1 ] if [ $# -lt 1 ]
then then
echo "Syntax Error: too few arguments" echo "Syntax Error: too few arguments"
...@@ -440,7 +457,7 @@ RUN_OPTIONS="none" ...@@ -440,7 +457,7 @@ RUN_OPTIONS="none"
# list of variables that can be set via the --setvar option # list of variables that can be set via the --setvar option
AUTHORIZED_VAR=("VM_OSREL RUN_EXPERIMENTAL") AUTHORIZED_VAR=("VM_OSREL RUN_EXPERIMENTAL OPTIONAL_APTCACHER TESTPLATFORM_OWNER")
#variables to set which OS VM should use #variables to set which OS VM should use
......
...@@ -476,7 +476,7 @@ function install_epc_on_vm { ...@@ -476,7 +476,7 @@ function install_epc_on_vm {
local LOC_EPC_VM_IP_ADDR=`uvt-kvm ip $LOC_EPC_VM_NAME` local LOC_EPC_VM_IP_ADDR=`uvt-kvm ip $LOC_EPC_VM_NAME`
echo "$LOC_EPC_VM_NAME has for IP addr = $LOC_EPC_VM_IP_ADDR" echo "$LOC_EPC_VM_NAME has for IP addr = $LOC_EPC_VM_IP_ADDR"
scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu [ -f /etc/apt/apt.conf.d/01proxy ] && scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu
# ltebox specific actions (install and start) # ltebox specific actions (install and start)
LTE_BOX_TO_INSTALL=1 LTE_BOX_TO_INSTALL=1
...@@ -500,7 +500,7 @@ function install_epc_on_vm { ...@@ -500,7 +500,7 @@ function install_epc_on_vm {
echo "############################################################" echo "############################################################"
echo "Install EPC on EPC VM ($LOC_EPC_VM_NAME)" echo "Install EPC on EPC VM ($LOC_EPC_VM_NAME)"
echo "############################################################" echo "############################################################"
echo "sudo cp 01proxy /etc/apt/apt.conf.d/" > $LOC_EPC_VM_CMDS echo "sudo [ -f 01proxy ] && cp 01proxy /etc/apt/apt.conf.d/" > $LOC_EPC_VM_CMDS
echo "touch /home/ubuntu/.hushlogin" >> $LOC_EPC_VM_CMDS echo "touch /home/ubuntu/.hushlogin" >> $LOC_EPC_VM_CMDS
echo "echo \"sudo apt-get --yes --quiet install zip openjdk-8-jre libconfuse-dev libreadline-dev liblog4c-dev libgcrypt-dev libsctp-dev python2.7 python2.7-dev daemon iperf\"" >> $LOC_EPC_VM_CMDS echo "echo \"sudo apt-get --yes --quiet install zip openjdk-8-jre libconfuse-dev libreadline-dev liblog4c-dev libgcrypt-dev libsctp-dev python2.7 python2.7-dev daemon iperf\"" >> $LOC_EPC_VM_CMDS
echo "sudo apt-get update > zip-install.txt 2>&1" >> $LOC_EPC_VM_CMDS echo "sudo apt-get update > zip-install.txt 2>&1" >> $LOC_EPC_VM_CMDS
......
...@@ -25,10 +25,23 @@ ...@@ -25,10 +25,23 @@
<htmlTabName>EPC-Start</htmlTabName> <htmlTabName>EPC-Start</htmlTabName>
<htmlTabIcon>log-in</htmlTabIcon> <htmlTabIcon>log-in</htmlTabIcon>
<TestCaseRequestedList> <TestCaseRequestedList>
010101 090101
050101 060101 070101 050101 060101 070101
</TestCaseRequestedList> </TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList> <TestCaseExclusionList></TestCaseExclusionList>
<testCase id="010101">
<class>Build_eNB</class>
<desc>Build eNB (USRP)</desc>
<Build_eNB_args>-w USRP -c --eNB</Build_eNB_args>
</testCase>
<testCase id="090101">
<class>Build_OAI_UE</class>
<desc>Build OAI UE</desc>
<Build_OAI_UE_args>-w USRP --UE</Build_OAI_UE_args>
</testCase>
<testCase id="050101"> <testCase id="050101">
<class>Initialize_HSS</class> <class>Initialize_HSS</class>
<desc>Initialize HSS</desc> <desc>Initialize HSS</desc>
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
<htmlTabRef>test-05-tm1-nos1-tunnel</htmlTabRef> <htmlTabRef>test-05-tm1-nos1-tunnel</htmlTabRef>
<htmlTabName>Test-05MHz-TM1-noS1-tunnel</htmlTabName> <htmlTabName>Test-05MHz-TM1-noS1-tunnel</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon> <htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>2</repeatCount> <repeatCount>4</repeatCount>
<TestCaseRequestedList> <TestCaseRequestedList>
030201 090109 030201 090109
030101 000001 090101 000002 040501 040502 000001 040601 040602 040641 040642 000001 090109 030201 030101 000001 090101 000002 040501 040502 000001 040601 040602 040641 040642 000001 090109 030201
......
...@@ -25,10 +25,16 @@ ...@@ -25,10 +25,16 @@
<htmlTabName>EPC-Closure</htmlTabName> <htmlTabName>EPC-Closure</htmlTabName>
<htmlTabIcon>log-out</htmlTabIcon> <htmlTabIcon>log-out</htmlTabIcon>
<TestCaseRequestedList> <TestCaseRequestedList>
040202
050201 060201 070201 050201 060201 070201
</TestCaseRequestedList> </TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList> <TestCaseExclusionList></TestCaseExclusionList>
<testCase id="040202">
<class>Terminate_CatM_module</class>
<desc>Terminate CAT-M Module</desc>
</testCase>
<testCase id="050201"> <testCase id="050201">
<class>Terminate_HSS</class> <class>Terminate_HSS</class>
<desc>Terminate HSS</desc> <desc>Terminate HSS</desc>
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
<htmlTabIcon>tasks</htmlTabIcon> <htmlTabIcon>tasks</htmlTabIcon>
<TestCaseRequestedList> <TestCaseRequestedList>
030201 030202 030201 030202
050202
</TestCaseRequestedList> </TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList> <TestCaseExclusionList></TestCaseExclusionList>
...@@ -43,4 +44,9 @@ ...@@ -43,4 +44,9 @@
<eNB_serverId>1</eNB_serverId> <eNB_serverId>1</eNB_serverId>
</testCase> </testCase>
<testCase id="050202">
<class>Terminate_FlexranCtrl</class>
<desc>Stopping Flexran Controller</desc>
</testCase>
</testCaseList> </testCaseList>
...@@ -1822,7 +1822,7 @@ add_library(LFDS7 ...@@ -1822,7 +1822,7 @@ add_library(LFDS7
# Simulation library # Simulation library
########################## ##########################
add_library(SIMU set (SIMUSRC
${OPENAIR1_DIR}/SIMULATION/TOOLS/random_channel.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/random_channel.c
${OPENAIR1_DIR}/SIMULATION/TOOLS/rangen_double.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/rangen_double.c
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
...@@ -1833,9 +1833,13 @@ ${OPENAIR1_DIR}/SIMULATION/TOOLS/channel_sim.c ...@@ -1833,9 +1833,13 @@ ${OPENAIR1_DIR}/SIMULATION/TOOLS/channel_sim.c
${OPENAIR1_DIR}/SIMULATION/RF/rf.c ${OPENAIR1_DIR}/SIMULATION/RF/rf.c
${OPENAIR1_DIR}/SIMULATION/RF/dac.c ${OPENAIR1_DIR}/SIMULATION/RF/dac.c
${OPENAIR1_DIR}/SIMULATION/RF/adc.c ${OPENAIR1_DIR}/SIMULATION/RF/adc.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR_DIR}/targets/ARCH/rfsimulator/apply_channelmod.c
#${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
) )
# Simulation library
##########################
add_library( SIMU SHARED ${SIMUSRC} )
add_library(SIMU_ETH add_library(SIMU_ETH
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
...@@ -2134,7 +2138,6 @@ add_executable(lte-uesoftmodem ...@@ -2134,7 +2138,6 @@ add_executable(lte-uesoftmodem
${OPENAIR_TARGETS}/RT/USER/lte-ru.c ${OPENAIR_TARGETS}/RT/USER/lte-ru.c
${OPENAIR_TARGETS}/RT/USER/ru_control.c ${OPENAIR_TARGETS}/RT/USER/ru_control.c
${OPENAIR_TARGETS}/RT/USER/rfsim.c ${OPENAIR_TARGETS}/RT/USER/rfsim.c
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c ${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c
......
...@@ -150,7 +150,7 @@ Options ...@@ -150,7 +150,7 @@ Options
--build-eclipse --build-eclipse
Build eclipse project files. Paths are auto corrected by fixprj.sh Build eclipse project files. Paths are auto corrected by fixprj.sh
--build-lib <libraries> --build-lib <libraries>
Build optional shared library, <libraries> can be one or several of $OPTIONAL_LIBRARIES Build optional shared library, <libraries> can be one or several of $OPTIONAL_LIBRARIES or \"all\"
--usrp-recplay --usrp-recplay
Build for I/Q record-playback modes Build for I/Q record-playback modes
...@@ -324,16 +324,21 @@ function main() { ...@@ -324,16 +324,21 @@ function main() {
shift 1;; shift 1;;
--build-lib) --build-lib)
BUILD_OPTLIB="" BUILD_OPTLIB=""
for alib in $2 ; do if [ "$2" == "all" ] ; then
BUILD_OPTLIB="$OPTIONAL_LIBRARIES"
echo_info "Enabling build of all optional shared libraries ($OPTIONAL_LIBRARIES)"
else
for alib in $2 ; do
for oklib in $OPTIONAL_LIBRARIES ; do for oklib in $OPTIONAL_LIBRARIES ; do
if [ "$alib" = "$oklib" ] ; then if [ "$alib" = "$oklib" ] ; then
BUILD_OPTLIB="$BUILD_OPTLIB $alib" BUILD_OPTLIB="$BUILD_OPTLIB $alib"
echo_info "Enabling build of lib${alib}.so" echo_info "Enabling build of lib${alib}.so"
fi fi
done
done done
done if [ "${BUILD_OPTLIB## }" != "$2" ] ; then
if [ "${BUILD_OPTLIB## }" != "$2" ] ; then echo_fatal "Unknown optional library in $2, valid libraries are $OPTIONAL_LIBRARIES"
echo_fatal "Unknown optional library in $2, valid libraries are $OPTIONAL_LIBRARIES" fi
fi fi
shift 2;; shift 2;;
--usrp-recplay) --usrp-recplay)
...@@ -515,21 +520,7 @@ function main() { ...@@ -515,21 +520,7 @@ function main() {
$lte_build_dir $lte_exec \ $lte_build_dir $lte_exec \
$lte_exec $dbin/$lte_exec.$REL $lte_exec $dbin/$lte_exec.$REL
# mandatory shared lib
compilations \
$lte_build_dir $config_libconfig_shlib \
lib$config_libconfig_shlib.so $dbin/lib$config_libconfig_shlib.so
compilations \
$lte_build_dir coding \
libcoding.so $dbin/libcoding.so
# optional libs (used when noS1 with kernel modules
compilations \
$lte_build_dir nasmesh \
CMakeFiles/nasmesh/nasmesh.ko $dbin/nasmesh.ko
compilations \
$lte_build_dir rb_tool \
rb_tool $dbin/rb_tool
cp $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 $dbin
fi fi
if [ "$UE" = 1 ] ; then if [ "$UE" = 1 ] ; then
...@@ -538,21 +529,6 @@ function main() { ...@@ -538,21 +529,6 @@ function main() {
$lte_build_dir $lte_exec \ $lte_build_dir $lte_exec \
$lte_exec $dbin/$lte_exec.$REL $lte_exec $dbin/$lte_exec.$REL
# mandatory shared lib
compilations \
$lte_build_dir $config_libconfig_shlib \
lib$config_libconfig_shlib.so $dbin/lib$config_libconfig_shlib.so
compilations \
$lte_build_dir coding \
libcoding.so $dbin/libcoding.so
# optional libs (used when noS1 with kernel modules
compilations \
$lte_build_dir nasmesh \
CMakeFiles/nasmesh/nasmesh.ko $dbin/nasmesh.ko
compilations \
$lte_build_dir rb_tool \
rb_tool $dbin/rb_tool
cp $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 $dbin
# ue_ip driver compilation # ue_ip driver compilation
compilations \ compilations \
$lte_build_dir ue_ip \ $lte_build_dir ue_ip \
...@@ -665,10 +641,25 @@ function main() { ...@@ -665,10 +641,25 @@ function main() {
fi fi
# build RF device and transport protocol libraries # build RF device, transport protocol libraries and all
# shared libraries common to UE and eNB
##################################### #####################################
if [ "$eNB" = "1" -o "$UE" = "1" ] ; then if [ "$eNB" = "1" -o "$UE" = "1" ] ; then
# mandatory shared lib
compilations \
$lte_build_dir $config_libconfig_shlib \
lib$config_libconfig_shlib.so $dbin/lib$config_libconfig_shlib.so
compilations \
$lte_build_dir coding \
libcoding.so $dbin/libcoding.so
# optional libs (used when noS1 with kernel modules
compilations \
$lte_build_dir nasmesh \
CMakeFiles/nasmesh/nasmesh.ko $dbin/nasmesh.ko
compilations \
$lte_build_dir rb_tool \
rb_tool $dbin/rb_tool
cp $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 $dbin
# build RF device libraries # build RF device libraries
if [ "$HW" != "None" ] ; then if [ "$HW" != "None" ] ; then
rm -f liboai_device.so rm -f liboai_device.so
...@@ -737,7 +728,7 @@ function main() { ...@@ -737,7 +728,7 @@ function main() {
echo_info "liboai_transpro.so is linked to ETHERNET transport" echo_info "liboai_transpro.so is linked to ETHERNET transport"
fi fi
if [ "$RFSIMULATOR" == "true" -o "$HW" == "OAI_SIMU" ] ; then if [ "$HW" == "OAI_SIMU" ] ; then
echo_info "Compiling rfsimulator" echo_info "Compiling rfsimulator"
compilations \ compilations \
$lte_build_dir rfsimulator \ $lte_build_dir rfsimulator \
......
## config module management
```c ```c
configmodule_interface_t *load_configmodule(int argc, char **argv, uint32_t initflags) configmodule_interface_t *load_configmodule(int argc, char **argv, uint32_t initflags)
``` ```
...@@ -14,23 +16,17 @@ void End_configmodule(void) ...@@ -14,23 +16,17 @@ void End_configmodule(void)
* Free memory which has been allocated by the configuration module since its initialization. * Free memory which has been allocated by the configuration module since its initialization.
* Possibly calls the `config_<config source>_end` function * Possibly calls the `config_<config source>_end` function
## Retrieving parameter's values
```c ```c
int config_get(paramdef_t *params,int numparams, char *prefix) int config_get(paramdef_t *params,int numparams, char *prefix)
``` ```
* Reads as many parameters as described in params, they must all be in the same configuration file section * Reads as many parameters as described in params, they must all be in the same configuration file section
* Calls the `config_<config source>_get` function * Calls the `config_<config source>_get` function
* Calls the `config_process_cmdline` function * Calls the `config_process_cmdline` function
* `params` points to an array of `paramdef_t` structures which describes the parameters to be read, possibly including a pointer to a checking function. The following bits can possibly be set in the `paramflags` mask before calling * `params` points to an array of `paramdef_t` structures which describes the parameters to be read, possibly including a pointer to a checking function.The `paramflags` bit mask can be used to modify how a specific parameter is processed and the same mask is also used by the configuration module to return information about how the parameter has been processed. Bits definitions are described in the [`paramdef_t` structure description](./struct.md)
- `PARAMFLAG_MANDATORY`: -1 is returned if the parameter is not explicitly defined in the config source.
- `PARAMFLAG_DISABLECMDLINE`: parameter cannot be modified via the command line
- `PARAMFLAG_DONOTREAD`: ignore the parameter, can be used at run-time, to alter a pre-defined `paramdef_t` array which is used in several `config_get` or/and `config_getlist` calls.
- `PARAMFLAG_NOFREE`: do not free the memory possibly allocated by the config module to store the value of the parameter. Default behavior is for the config module to free the memory it has allocated when the `config_end` function is called.
- `PARAMFLAG_BOOL`: Only relevant for integer types. tell the config module that when processing the command line, the corresponding option can be specified without any arggument and that in this case it must set the value to 1.
* `params` is also used as an output parameter, `< XXX >ptr >` field is used by the config module to store the value it has read. The following bits can possibly be set in the `paramflags` mask after the call:
- `PARAMFLAG_MALLOCINCONFIG`: memory has been allocated for the ` < XXX >ptr > ` field
- `PARAMFLAG_PARAMSET`: parameter has been found in the config source, it is not set to default value.
- `PARAMFLAG_PARAMSET`: parameter has been set to its default value
* `numparams` is the number of entries in the params array * `numparams` is the number of entries in the params array
* `prefix` is a character string to be appended to the parameters name, it defines the parameters position in the configuration file hierarchy (the section name in libconfig terminology). * `prefix` is a character string to be appended to the parameters name, it defines the parameters position in the configuration file hierarchy (the section name in libconfig terminology).
* The returned value is the number of parameters which have been assigned a value or -1 if a severe error occured * The returned value is the number of parameters which have been assigned a value or -1 if a severe error occured
...@@ -44,6 +40,9 @@ int config_libconfig_getlist(paramlist_def_t *ParamList, paramdef_t *params, int ...@@ -44,6 +40,9 @@ int config_libconfig_getlist(paramlist_def_t *ParamList, paramdef_t *params, int
* `ParamList` points to a structure, where `paramarray` field points to an array of `paramdef_t` structure, allocated by the function. It is used to return the values of the parameters. * `ParamList` points to a structure, where `paramarray` field points to an array of `paramdef_t` structure, allocated by the function. It is used to return the values of the parameters.
* The returned value is the number of occurrences in the list or -1 in case of severe error * The returned value is the number of occurrences in the list or -1 in case of severe error
## utility functions and macros
The configuration module also defines APIs to access the `paramdef_t` and `configmodule_interface_t` fields. They are listed in the configuration module [include file `common/config/config_userapi.h`](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_userapi.h)
[Configuration module developer main page](../../config/devusage.md) [Configuration module developer main page](../../config/devusage.md)
[Configuration module home](../../config.md) [Configuration module home](../../config.md)
...@@ -5,6 +5,7 @@ It is defined in include file [ common/config/config_paramdesc.h ](https://gitla ...@@ -5,6 +5,7 @@ It is defined in include file [ common/config/config_paramdesc.h ](https://gitla
|:-----------|:------------------------------------------------------------------|----:| |:-----------|:------------------------------------------------------------------|----:|
| `optname` | parameter name, as used when looking for it in the config source, 63 bytes max (64 with trailing \0) | I | | `optname` | parameter name, as used when looking for it in the config source, 63 bytes max (64 with trailing \0) | I |
| `helstr` | pointer to a C string printed when using --help on the command line | I | | `helstr` | pointer to a C string printed when using --help on the command line | I |
| `paramflags` | bit mask, used to modify how the parameter is processed, or to return to the API caller how the parameter has been set, see list in the next table | IO |
| `strptr` `strlistptr` `u8ptr` `i8ptr` `u16ptr` `i16ptr` `uptr` `iptr` `u64ptr` `i64ptr` `dblptr` `voidptr` | a pointer to a variable where the parameter value(s) will be returned. This field is an anonymous union, the supported pointer types have been built to avoid type mismatch warnings at compile time. | O | | `strptr` `strlistptr` `u8ptr` `i8ptr` `u16ptr` `i16ptr` `uptr` `iptr` `u64ptr` `i64ptr` `dblptr` `voidptr` | a pointer to a variable where the parameter value(s) will be returned. This field is an anonymous union, the supported pointer types have been built to avoid type mismatch warnings at compile time. | O |
| `defstrval` `defstrlistval` `defuintval` `defintval` `defint64val` `defintarrayval` `defdblval` | this field is an anonymous union, it can be used to define the default value for the parameter. It is ignored if `PARAMFLAG_MANDATORY` is set in the `paramflags` field.| I | | `defstrval` `defstrlistval` `defuintval` `defintval` `defint64val` `defintarrayval` `defdblval` | this field is an anonymous union, it can be used to define the default value for the parameter. It is ignored if `PARAMFLAG_MANDATORY` is set in the `paramflags` field.| I |
| `type` | Supported parameter types are defined as integer macros. Supported simple types are `TYPE_STRING`, parameter value is returned in `strptr` field, `TYPE_INT8` `TYPE_UINT8` `TYPE_INT16` `TYPE_UINT16` `TYPE_INT32` `TYPE_UINT32` `TYPE_INT64` `TYPE_UINT64`, parameter value is returned in the corresponding uXptr or iXptr, `TYPE_MASK`, value is returned in `u32ptr`, `TYPE_DOUBLE` value is returned in `dblptr`, `TYPE_IPV4ADDR` value is returned in binary, network bytes order in `u32ptr` field. `TYPE_STRINGLIST`, `TYPE_INTARRAY` and `TYPE_UINTARRAY` are multiple values types. Multiple values are returned in respectively, `strlistptr`, `iptr` and `uptr` fields which then point to arrays. The `numelt` field gives the number of item in the array. | I | | `type` | Supported parameter types are defined as integer macros. Supported simple types are `TYPE_STRING`, parameter value is returned in `strptr` field, `TYPE_INT8` `TYPE_UINT8` `TYPE_INT16` `TYPE_UINT16` `TYPE_INT32` `TYPE_UINT32` `TYPE_INT64` `TYPE_UINT64`, parameter value is returned in the corresponding uXptr or iXptr, `TYPE_MASK`, value is returned in `u32ptr`, `TYPE_DOUBLE` value is returned in `dblptr`, `TYPE_IPV4ADDR` value is returned in binary, network bytes order in `u32ptr` field. `TYPE_STRINGLIST`, `TYPE_INTARRAY` and `TYPE_UINTARRAY` are multiple values types. Multiple values are returned in respectively, `strlistptr`, `iptr` and `uptr` fields which then point to arrays. The `numelt` field gives the number of item in the array. | I |
...@@ -12,6 +13,22 @@ It is defined in include file [ common/config/config_paramdesc.h ](https://gitla ...@@ -12,6 +13,22 @@ It is defined in include file [ common/config/config_paramdesc.h ](https://gitla
| `chkPptr` | possible pointer to the structure containing the info used to check parameter values | I | | `chkPptr` | possible pointer to the structure containing the info used to check parameter values | I |
| `processedvalue` | When `chkPptr` is not `ǸULL`, is used to return a value, computed from the original parameter, as read from the configuration source. | O | | `processedvalue` | When `chkPptr` is not `ǸULL`, is used to return a value, computed from the original parameter, as read from the configuration source. | O |
## `paramflags` bits definition
| C macro bit definition | usage | I/O |
|:-------------------------------------|:---------------------------------------------------------------------------------------------------------------------|----:|
| `PARAMFLAG_MANDATORY` | parameter is mandatory, comfiguration module will stop the process if it is not specified. Default value is ignored | I |
| `PARAMFLAG_DISABLECMDLINE` | parameter cannot be specified on the command line | I |
| `PARAMFLAG_DONOTREAD` | ignore the parameter, usefull when a parameter group is used in different context | I |
| `PARAMFLAG_NOFREE` | The end_configmodule API won't free the memory which has been possibly allocated to store the value of the parameter.| I |
| `PARAMFLAG_BOOL` | Parameter is a boolean, it can be specified without a value to set it to true | I |
| `PARAMFLAG_CMDLINE_NOPREFIXENABLED` | parameter can be specified without the prefix on the command line. Must be used with care, carefuly checking unicity, especially for short parameter names | I |
| `PARAMFLAG_MALLOCINCONFIG` | Memory for the parameter value has been allocated by the configuration module |O |
| `PARAMFLAG_PARAMSET` | Parameter value has been explicitely set, as the parameter was specified either on the command line or the config source | O |
| `PARAMFLAG_PARAMSETDEF` | Parameter value has been set to it's default | O |
# `paramlist_def_t`structure # `paramlist_def_t`structure
It is defined in include file [ common/config/config_paramdesc.h ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_paramdesc.h#L160). It is defined in include file [ common/config/config_paramdesc.h ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_paramdesc.h#L160).
It is used as an argument to `config_getlist` calls, to get values of multiple occurrences of group of parameters. It is used as an argument to `config_getlist` calls, to get values of multiple occurrences of group of parameters.
......
...@@ -167,8 +167,8 @@ int config_check_unknown_cmdlineopt(char *prefix) { ...@@ -167,8 +167,8 @@ int config_check_unknown_cmdlineopt(char *prefix) {
char testprefix[CONFIG_MAXOPTLENGTH]; char testprefix[CONFIG_MAXOPTLENGTH];
int finalcheck = 0; int finalcheck = 0;
memset(testprefix,0,sizeof(testprefix)); memset(testprefix,0,sizeof(testprefix));
memset(testprefix,0,sizeof(testprefix)); memset(testprefix,0,sizeof(testprefix));
if (prefix != NULL) { if (prefix != NULL) {
if (strcmp(prefix,CONFIG_CHECKALLSECTIONS) == 0) if (strcmp(prefix,CONFIG_CHECKALLSECTIONS) == 0)
finalcheck = 1; finalcheck = 1;
...@@ -253,7 +253,9 @@ int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix) ...@@ -253,7 +253,9 @@ int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix)
} }
if ( ((strlen(oneargv) == 2) && (strcmp(oneargv + 1,cfgpath) == 0)) || /* short option, one "-" */ if ( ((strlen(oneargv) == 2) && (strcmp(oneargv + 1,cfgpath) == 0)) || /* short option, one "-" */
((strlen(oneargv) > 2) && (strcmp(oneargv + 2,cfgpath ) == 0 )) ) { ((strlen(oneargv) > 2) && (strcmp(oneargv + 2,cfgpath ) == 0 )) || /* long option beginning with "--" */
((strlen(oneargv) == 2) && (strcmp(oneargv + 1,cfgoptions[n].optname) == 0) && (cfgoptions[n].paramflags & PARAMFLAG_CMDLINE_NOPREFIXENABLED )) ||
((strlen(oneargv) > 2) && (strcmp(oneargv + 2,cfgpath ) == 0 ) && (cfgoptions[n].paramflags & PARAMFLAG_CMDLINE_NOPREFIXENABLED )) ) {
char *valptr=NULL; char *valptr=NULL;
int ret; int ret;
config_get_if()->argv_info[i] |= CONFIG_CMDLINEOPT_PROCESSED; config_get_if()->argv_info[i] |= CONFIG_CMDLINEOPT_PROCESSED;
......
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
#define PARAMFLAG_DONOTREAD (1 << 2) // parameter must be ignored in get function #define PARAMFLAG_DONOTREAD (1 << 2) // parameter must be ignored in get function
#define PARAMFLAG_NOFREE (1 << 3) // don't free parameter in end function #define PARAMFLAG_NOFREE (1 << 3) // don't free parameter in end function
#define PARAMFLAG_BOOL (1 << 4) // integer param can be 0 or 1 #define PARAMFLAG_BOOL (1 << 4) // integer param can be 0 or 1
#define PARAMFLAG_CMDLINE_NOPREFIXENABLED (1 << 5) // on the command line, allow a parameter to be specified without the prefix
/* Flags used by config modules to return info to calling modules and/or to for internal usage*/ /* Flags used by config modules to return info to calling modules and/or to for internal usage*/
#define PARAMFLAG_MALLOCINCONFIG (1 << 15) // parameter allocated in config module #define PARAMFLAG_MALLOCINCONFIG (1 << 15) // parameter allocated in config module
......
...@@ -172,7 +172,7 @@ int config_get_processedint(paramdef_t *cfgoption) { ...@@ -172,7 +172,7 @@ int config_get_processedint(paramdef_t *cfgoption) {
return ret; return ret;
} }
void config_printhelp(paramdef_t *params,int numparams, char *prefix) { void config_printhelp(paramdef_t *params,int numparams, char *prefix) {
printf("\n-----Help for section %-26s: %03i entries------\n",(prefix==NULL)?"(root section)":prefix ,numparams); printf("\n-----Help for section %-26s: %03i entries------\n",(prefix==NULL)?"(root section)":prefix,numparams);
for (int i=0 ; i<numparams ; i++) { for (int i=0 ; i<numparams ; i++) {
printf(" %s%s: %s", printf(" %s%s: %s",
...@@ -204,6 +204,16 @@ int config_execcheck(paramdef_t *params,int numparams, char *prefix) { ...@@ -204,6 +204,16 @@ int config_execcheck(paramdef_t *params,int numparams, char *prefix) {
return st; return st;
} }
int config_paramidx_fromname(paramdef_t *params,int numparams, char *name) {
for (int i=0; i<numparams ; i++) {
if (strcmp(name,params[i].optname) == 0)
return i;
}
fprintf(stderr,"[CONFIG]config_paramidx_fromname , %s is not a valid parameter name\n",name);
return -1;
}
int config_get(paramdef_t *params,int numparams, char *prefix) { int config_get(paramdef_t *params,int numparams, char *prefix) {
int ret= -1; int ret= -1;
...@@ -438,7 +448,7 @@ int config_setdefault_intlist(paramdef_t *cfgoptions, char *prefix) { ...@@ -438,7 +448,7 @@ int config_setdefault_intlist(paramdef_t *cfgoptions, char *prefix) {
status=1; status=1;
for (int j=0; j<cfgoptions->numelt ; j++) { for (int j=0; j<cfgoptions->numelt ; j++) {
printf_params("[CONFIG] %s[%i] set to default value %i\n",cfgoptions->optname ,j,(int)cfgoptions->iptr[j]); printf_params("[CONFIG] %s[%i] set to default value %i\n",cfgoptions->optname,j,(int)cfgoptions->iptr[j]);
} }
} }
...@@ -452,7 +462,7 @@ int config_setdefault_double(paramdef_t *cfgoptions, char *prefix) { ...@@ -452,7 +462,7 @@ int config_setdefault_double(paramdef_t *cfgoptions, char *prefix) {
if( ((cfgoptions->paramflags & PARAMFLAG_MANDATORY) == 0)) { if( ((cfgoptions->paramflags & PARAMFLAG_MANDATORY) == 0)) {
*(cfgoptions->dblptr)=cfgoptions->defdblval; *(cfgoptions->dblptr)=cfgoptions->defdblval;
status=1; status=1;
printf_params("[CONFIG] %s set to default value %lf\n",cfgoptions->optname , *(cfgoptions->dblptr)); printf_params("[CONFIG] %s set to default value %lf\n",cfgoptions->optname, *(cfgoptions->dblptr));
} }
return status; return status;
...@@ -460,7 +470,7 @@ int config_setdefault_double(paramdef_t *cfgoptions, char *prefix) { ...@@ -460,7 +470,7 @@ int config_setdefault_double(paramdef_t *cfgoptions, char *prefix) {
int config_assign_ipv4addr(paramdef_t *cfgoptions, char *ipv4addr) { int config_assign_ipv4addr(paramdef_t *cfgoptions, char *ipv4addr) {
config_check_valptr(cfgoptions,(char **)&(cfgoptions->uptr), sizeof(int)); config_check_valptr(cfgoptions,(char **)&(cfgoptions->uptr), sizeof(int));
int rst=inet_pton(AF_INET, ipv4addr ,cfgoptions->uptr ); int rst=inet_pton(AF_INET, ipv4addr,cfgoptions->uptr );
if (rst == 1 && *(cfgoptions->uptr) > 0) { if (rst == 1 && *(cfgoptions->uptr) > 0) {
printf_params("[CONFIG] %s: %s\n",cfgoptions->optname, ipv4addr); printf_params("[CONFIG] %s: %s\n",cfgoptions->optname, ipv4addr);
......
...@@ -39,6 +39,7 @@ extern "C" ...@@ -39,6 +39,7 @@ extern "C"
{ {
#endif #endif
/* utility functions to ease usage of config module structures */
#define CONFIG_GETSOURCE ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgmode ) #define CONFIG_GETSOURCE ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgmode )
#define CONFIG_GETNUMP ( (config_get_if()==NULL) ? 0 : config_get_if()->num_cfgP ) #define CONFIG_GETNUMP ( (config_get_if()==NULL) ? 0 : config_get_if()->num_cfgP )
#define CONFIG_GETP(P) ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgP[P] ) #define CONFIG_GETP(P) ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgP[P] )
...@@ -46,6 +47,8 @@ extern "C" ...@@ -46,6 +47,8 @@ extern "C"
#define CONFIG_SETRTFLAG(P) if (config_get_if()) { config_get_if()->rtflags |= P; } #define CONFIG_SETRTFLAG(P) if (config_get_if()) { config_get_if()->rtflags |= P; }
#define CONFIG_CLEARRTFLAG(P) if (config_get_if()) { config_get_if()->rtflags &= (~P); } #define CONFIG_CLEARRTFLAG(P) if (config_get_if()) { config_get_if()->rtflags &= (~P); }
#define CONFIG_ISPARAMFLAGSET(P,F) ( !!(P.paramflags & F)) #define CONFIG_ISPARAMFLAGSET(P,F) ( !!(P.paramflags & F))
extern int config_paramidx_fromname(paramdef_t *params,int numparams, char *name);
/* utility functions, to be used by configuration module and/or configuration libraries */ /* utility functions, to be used by configuration module and/or configuration libraries */
extern configmodule_interface_t *config_get_if(void); extern configmodule_interface_t *config_get_if(void);
extern char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) ; extern char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) ;
......
...@@ -123,7 +123,7 @@ void client_printf(const char *message, ...) { ...@@ -123,7 +123,7 @@ void client_printf(const char *message, ...) {
if (telnetparams.new_socket > 0) { if (telnetparams.new_socket > 0) {
vsnprintf(telnetparams.msgbuff,sizeof(telnetparams.msgbuff)-1,message, va_args); vsnprintf(telnetparams.msgbuff,sizeof(telnetparams.msgbuff)-1,message, va_args);
send(telnetparams.new_socket,telnetparams.msgbuff , strlen(telnetparams.msgbuff), MSG_NOSIGNAL); send(telnetparams.new_socket,telnetparams.msgbuff, strlen(telnetparams.msgbuff), MSG_NOSIGNAL);
} else { } else {
vprintf(message, va_args); vprintf(message, va_args);
} }
...@@ -475,7 +475,7 @@ int process_command(char *buf) { ...@@ -475,7 +475,7 @@ int process_command(char *buf) {
memset(cmdb,0,sizeof(cmdb)); memset(cmdb,0,sizeof(cmdb));
bufbck=strdup(buf); bufbck=strdup(buf);
rt=CMDSTATUS_NOTFOUND; rt=CMDSTATUS_NOTFOUND;
j = sscanf(buf,"%9s %9s %9[^\t\n]",modulename,cmd,cmdb); j = sscanf(buf,"%19s %19s %19[^\t\n]",modulename,cmd,cmdb);
if (telnetparams.telnetdbg > 0) if (telnetparams.telnetdbg > 0)
printf("process_command: %i words, module=%s cmd=%s, parameters= %s\n",j,modulename,cmd,cmdb); printf("process_command: %i words, module=%s cmd=%s, parameters= %s\n",j,modulename,cmd,cmdb);
...@@ -543,7 +543,7 @@ void run_telnetsrv(void) { ...@@ -543,7 +543,7 @@ void run_telnetsrv(void) {
char buf[TELNET_MAX_MSGLENGTH]; char buf[TELNET_MAX_MSGLENGTH];
struct sockaddr cli_addr; struct sockaddr cli_addr;
unsigned int cli_len = sizeof(cli_addr); unsigned int cli_len = sizeof(cli_addr);
int readc , filled; int readc, filled;
int status; int status;
int optval = 1; int optval = 1;
pthread_setname_np(pthread_self(), "telnet"); pthread_setname_np(pthread_self(), "telnet");
...@@ -604,7 +604,7 @@ void run_telnetsrv(void) { ...@@ -604,7 +604,7 @@ void run_telnetsrv(void) {
} }
if (telnetparams.telnetdbg > 0) if (telnetparams.telnetdbg > 0)
printf("[TELNETSRV] Command received: readc %i filled %i \"%s\"\n", readc, filled ,buf); printf("[TELNETSRV] Command received: readc %i filled %i \"%s\"\n", readc, filled,buf);
if (buf[0] == '!') { if (buf[0] == '!') {
if (buf[1] == '!') { if (buf[1] == '!') {
......
...@@ -54,7 +54,7 @@ cd cmake_targets/ ...@@ -54,7 +54,7 @@ cd cmake_targets/
``` ```
- The `-I` option is to install pre-requisites, you only need it the first time you build the softmodem or when some oai dependencies have changed. - The `-I` option is to install pre-requisites, you only need it the first time you build the softmodem or when some oai dependencies have changed.
- The `-w` option is to select the radio head support you want to include in your build. Radio head support is provided via a shared library, which is called the "oai device" The build script creates a soft link from `liboai_device.so` to the true device which will be used at run-time (here the USRP one,`liboai_usrpdevif.so` . USRP is the only hardware tested today in the Continuous Integration process. - The `-w` option is to select the radio head support you want to include in your build. Radio head support is provided via a shared library, which is called the "oai device" The build script creates a soft link from `liboai_device.so` to the true device which will be used at run-time (here the USRP one,`liboai_usrpdevif.so` . USRP is the only hardware tested today in the Continuous Integration process. The RF simulator[RF simulator](../targets/ARCH/rfsimulator/README.md) is implemented as a specific device replacing RF hardware, it can be build using `-w SIMU` option.
- `--eNB` is to build the `lte-softmodem` executable and all required shared libraries - `--eNB` is to build the `lte-softmodem` executable and all required shared libraries
- `--UE` is to build the `lte-uesoftmodem` executable and all required shared libraries - `--UE` is to build the `lte-uesoftmodem` executable and all required shared libraries
......
...@@ -2022,6 +2022,11 @@ void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu ...@@ -2022,6 +2022,11 @@ void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu
ulsch->ue_type = 0; ulsch->ue_type = 0;
#endif #endif
if(ulsch_pdu->ulsch_pdu_rel13.repetition_number >1) // Fill the Harq process parameters in the first Rep only
{
return;
}
//AssertFatal(ulsch->harq_processes[harq_pid]->nb_rb>0,"nb_rb = 0\n"); //AssertFatal(ulsch->harq_processes[harq_pid]->nb_rb>0,"nb_rb = 0\n");
if(ulsch->harq_processes[harq_pid]->nb_rb == 0){ if(ulsch->harq_processes[harq_pid]->nb_rb == 0){
LOG_E(PHY, "fill_ulsch UE_id %d nb_rb = 0\n", UE_id); LOG_E(PHY, "fill_ulsch UE_id %d nb_rb = 0\n", UE_id);
...@@ -2031,6 +2036,9 @@ void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu ...@@ -2031,6 +2036,9 @@ void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu
ulsch->harq_processes[harq_pid]->subframe = subframe; ulsch->harq_processes[harq_pid]->subframe = subframe;
ulsch->harq_processes[harq_pid]->handled = 0; ulsch->harq_processes[harq_pid]->handled = 0;
ulsch->harq_processes[harq_pid]->repetition_number = ulsch_pdu->ulsch_pdu_rel13.repetition_number ;
ulsch->harq_processes[harq_pid]->total_number_of_repetitions = ulsch_pdu->ulsch_pdu_rel13.total_number_of_repetitions ;
ulsch->harq_processes[harq_pid]->first_rb = ulsch_pdu->ulsch_pdu_rel8.resource_block_start; ulsch->harq_processes[harq_pid]->first_rb = ulsch_pdu->ulsch_pdu_rel8.resource_block_start;
ulsch->harq_processes[harq_pid]->nb_rb = ulsch_pdu->ulsch_pdu_rel8.number_of_resource_blocks; ulsch->harq_processes[harq_pid]->nb_rb = ulsch_pdu->ulsch_pdu_rel8.number_of_resource_blocks;
......
...@@ -319,6 +319,12 @@ typedef struct { ...@@ -319,6 +319,12 @@ typedef struct {
// int calibration_flag; // int calibration_flag;
/// delta_TF for power control /// delta_TF for power control
int32_t delta_TF; int32_t delta_TF;
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
// PUSCH Repetition Number for the current SF
uint32_t repetition_number ;
// PUSCH Total number of repetitions
uint32_t total_number_of_repetitions;
#endif
} LTE_UL_eNB_HARQ_t; } LTE_UL_eNB_HARQ_t;
typedef struct { typedef struct {
......
...@@ -555,12 +555,18 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) ...@@ -555,12 +555,18 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag)
int G = ulsch_harq->G; int G = ulsch_harq->G;
unsigned int E; unsigned int E;
decoder_if_t *tc; decoder_if_t *tc;
static int32_t pusch_rep_buffer[3*(6144+64)];
int max_Ncb;
if (llr8_flag == 0) if (llr8_flag == 0)
tc = *decoder16; tc = *decoder16;
else else
tc = *decoder8; tc = *decoder8;
if(ulsch_harq->repetition_number == 1){
memset(pusch_rep_buffer,0,(sizeof(int32_t)*3*(6144+64))) ; // reset the buffer every new repetitions
}
for (r=0; r<ulsch_harq->C; r++) { for (r=0; r<ulsch_harq->C; r++) {
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]); // printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
// Get Turbo interleaver parameters // Get Turbo interleaver parameters
...@@ -594,7 +600,7 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) ...@@ -594,7 +600,7 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag)
0, //Uplink 0, //Uplink
1, 1,
ulsch_harq->rvidx, ulsch_harq->rvidx,
(ulsch_harq->round==0)?1:0, // clear (ulsch_harq->rvidx==0)?1:0, // clear
ulsch_harq->Qm, ulsch_harq->Qm,
1, 1,
r, r,
...@@ -604,6 +610,27 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) ...@@ -604,6 +610,27 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag)
} }
stop_meas(&eNB->ulsch_rate_unmatching_stats); stop_meas(&eNB->ulsch_rate_unmatching_stats);
max_Ncb = 3*ulsch_harq->RTC[r]*32 ;
if(ulsch_harq->total_number_of_repetitions > 1)
{
if (ulsch_harq->rvidx==1)
{ // Store the result of HARQ combining in the last emtc repetitions of sequence 0,2,3,1
for (int nn=0;nn<max_Ncb;nn++)
{
pusch_rep_buffer[nn] += ulsch_harq->w[r][nn] ;
}
}
if (ulsch_harq->repetition_number == ulsch_harq->total_number_of_repetitions)
{
for (int nn=0;nn<max_Ncb;nn++)
{
ulsch_harq->w[r][nn] = pusch_rep_buffer[nn] ;
}
}
}
r_offset += E; r_offset += E;
start_meas(&eNB->ulsch_deinterleaving_stats); start_meas(&eNB->ulsch_deinterleaving_stats);
sub_block_deinterleaving_turbo(4+Kr, sub_block_deinterleaving_turbo(4+Kr,
......
...@@ -122,7 +122,6 @@ void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxt ...@@ -122,7 +122,6 @@ void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxt
phich->config[phich->num_hi].n_DMRS = hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms; phich->config[phich->num_hi].n_DMRS = hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms;
phich->num_hi++; phich->num_hi++;
AssertFatal(phich->num_hi<32,"Maximum number of phich reached in subframe\n"); AssertFatal(phich->num_hi<32,"Maximum number of phich reached in subframe\n");
} }
void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,
...@@ -186,6 +185,7 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_pro ...@@ -186,6 +185,7 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_pro
#endif #endif
harq_pid = dlsch0->harq_ids[proc->frame_tx%2][proc->subframe_tx]; harq_pid = dlsch0->harq_ids[proc->frame_tx%2][proc->subframe_tx];
if((harq_pid < 0) || (harq_pid >= dlsch0->Mdlharq)) { if((harq_pid < 0) || (harq_pid >= dlsch0->Mdlharq)) {
LOG_E(PHY,"illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__); LOG_E(PHY,"illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__);
return; return;
...@@ -260,9 +260,7 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_pro ...@@ -260,9 +260,7 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_pro
dlsch0->harq_mask = 1; dlsch0->harq_mask = 1;
dlsch0_harq = dlsch0->harq_processes[0]; dlsch0_harq = dlsch0->harq_processes[0];
dlsch0_harq->pdu = sdu; dlsch0_harq->pdu = sdu;
LOG_D(PHY,"NFAPI: frame %d, subframe %d (TX %d.%d): Programming SI-BR (%d) => %d\n",frame,subframe,proc->frame_tx,proc->subframe_tx,rel13->pdsch_payload_type,UE_id); LOG_D(PHY,"NFAPI: frame %d, subframe %d (TX %d.%d): Programming SI-BR (%d) => %d\n",frame,subframe,proc->frame_tx,proc->subframe_tx,rel13->pdsch_payload_type,UE_id);
dlsch0->rnti = 0xFFFF; dlsch0->rnti = 0xFFFF;
dlsch0->Kmimo = 1; dlsch0->Kmimo = 1;
dlsch0->Mdlharq = 4; dlsch0->Mdlharq = 4;
...@@ -569,8 +567,7 @@ void handle_uci_sr_pdu(PHY_VARS_eNB *eNB, ...@@ -569,8 +567,7 @@ void handle_uci_sr_pdu(PHY_VARS_eNB *eNB,
nfapi_ul_config_request_pdu_t *ul_config_pdu, nfapi_ul_config_request_pdu_t *ul_config_pdu,
uint16_t frame, uint16_t frame,
uint8_t subframe, uint8_t subframe,
uint8_t srs_active) uint8_t srs_active) {
{
LTE_eNB_UCI *uci = &eNB->uci_vars[UE_id]; LTE_eNB_UCI *uci = &eNB->uci_vars[UE_id];
if (NFAPI_MODE==NFAPI_MODE_VNF) return; if (NFAPI_MODE==NFAPI_MODE_VNF) return;
...@@ -803,13 +800,13 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { ...@@ -803,13 +800,13 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
// clear DCI allocation maps for new subframe // clear DCI allocation maps for new subframe
if (NFAPI_MODE!=NFAPI_MODE_VNF) if (NFAPI_MODE!=NFAPI_MODE_VNF)
for (i=0; i<NUMBER_OF_UE_MAX; i++) { for (i=0; i<NUMBER_OF_UE_MAX; i++) {
if (eNB->ulsch[i]) { if (eNB->ulsch[i]) {
ulsch_harq = eNB->ulsch[i]->harq_processes[harq_pid]; ulsch_harq = eNB->ulsch[i]->harq_processes[harq_pid];
ulsch_harq->dci_alloc=0; ulsch_harq->dci_alloc=0;
ulsch_harq->rar_alloc=0; ulsch_harq->rar_alloc=0;
}
} }
}
} }
for (i=0; i<number_dl_pdu; i++) { for (i=0; i<number_dl_pdu; i++) {
...@@ -820,6 +817,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { ...@@ -820,6 +817,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE: case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE:
if (NFAPI_MODE!=NFAPI_MODE_VNF) if (NFAPI_MODE!=NFAPI_MODE_VNF)
handle_nfapi_dci_dl_pdu(eNB,NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),proc,dl_config_pdu); handle_nfapi_dci_dl_pdu(eNB,NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),proc,dl_config_pdu);
eNB->pdcch_vars[NFAPI_SFNSF2SF(DL_req->sfn_sf)&1].num_dci++; eNB->pdcch_vars[NFAPI_SFNSF2SF(DL_req->sfn_sf)&1].num_dci++;
//LOG_E(PHY,"Incremented num_dci:%d but already set??? dl_config:num_dci:%d\n", eNB->pdcch_vars[subframe&1].num_dci, number_dci); //LOG_E(PHY,"Incremented num_dci:%d but already set??? dl_config:num_dci:%d\n", eNB->pdcch_vars[subframe&1].num_dci, number_dci);
do_oai=1; do_oai=1;
...@@ -832,11 +830,13 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { ...@@ -832,11 +830,13 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
TX_req->tx_request_body.number_of_pdus); TX_req->tx_request_body.number_of_pdus);
eNB->pbch_configured=1; eNB->pbch_configured=1;
do_oai=1; do_oai=1;
//LOG_D(PHY,"%s() NFAPI_DL_CONFIG_BCH_PDU_TYPE TX:%d/%d RX:%d/%d TXREQ:%d/%d\n", //LOG_D(PHY,"%s() NFAPI_DL_CONFIG_BCH_PDU_TYPE TX:%d/%d RX:%d/%d TXREQ:%d/%d\n",
//__FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->frame_rx, proc->subframe_rx, NFAPI_SFNSF2SFN(TX_req->sfn_sf), NFAPI_SFNSF2SF(TX_req->sfn_sf)); //__FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->frame_rx, proc->subframe_rx, NFAPI_SFNSF2SFN(TX_req->sfn_sf), NFAPI_SFNSF2SF(TX_req->sfn_sf));
if (NFAPI_MODE!=NFAPI_MODE_VNF) if (NFAPI_MODE!=NFAPI_MODE_VNF)
handle_nfapi_bch_pdu(eNB,proc,dl_config_pdu, handle_nfapi_bch_pdu(eNB,proc,dl_config_pdu,
TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index].segments[0].segment_data); TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index].segments[0].segment_data);
break; break;
case NFAPI_DL_CONFIG_MCH_PDU_TYPE: case NFAPI_DL_CONFIG_MCH_PDU_TYPE:
...@@ -867,8 +867,8 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { ...@@ -867,8 +867,8 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
dlsch_pdu_rel8->transport_blocks); dlsch_pdu_rel8->transport_blocks);
if (1) { //sdu != NULL) if (1) { //sdu != NULL)
if (NFAPI_MODE!=NFAPI_MODE_VNF) if (NFAPI_MODE!=NFAPI_MODE_VNF)
handle_nfapi_dlsch_pdu(eNB,NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),proc,dl_config_pdu, dlsch_pdu_rel8->transport_blocks-1, sdu); handle_nfapi_dlsch_pdu(eNB,NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),proc,dl_config_pdu, dlsch_pdu_rel8->transport_blocks-1, sdu);
} else { } else {
dont_send=1; dont_send=1;
LOG_E(MAC,"%s() NFAPI_DL_CONFIG_DLSCH_PDU_TYPE sdu is NULL DL_CFG:SFN/SF:%d:pdu_index:%d TX_REQ:SFN/SF:%d:pdus:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(DL_req->sfn_sf), pdu_index, LOG_E(MAC,"%s() NFAPI_DL_CONFIG_DLSCH_PDU_TYPE sdu is NULL DL_CFG:SFN/SF:%d:pdu_index:%d TX_REQ:SFN/SF:%d:pdus:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(DL_req->sfn_sf), pdu_index,
...@@ -911,6 +911,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { ...@@ -911,6 +911,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE: case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE:
if (NFAPI_MODE!=NFAPI_MODE_VNF) if (NFAPI_MODE!=NFAPI_MODE_VNF)
handle_nfapi_mpdcch_pdu(eNB,proc,dl_config_pdu); handle_nfapi_mpdcch_pdu(eNB,proc,dl_config_pdu);
eNB->mpdcch_vars[subframe&1].num_dci++; eNB->mpdcch_vars[subframe&1].num_dci++;
break; break;
#endif #endif
...@@ -918,10 +919,11 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { ...@@ -918,10 +919,11 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
} }
if ((NFAPI_MODE!=NFAPI_MONOLITHIC) && do_oai && !dont_send) { if ((NFAPI_MODE!=NFAPI_MONOLITHIC) && do_oai && !dont_send) {
if(Sched_INFO->TX_req->tx_request_body.number_of_pdus > 0){ if(Sched_INFO->TX_req->tx_request_body.number_of_pdus > 0) {
Sched_INFO->TX_req->sfn_sf = frame << 4 | subframe; Sched_INFO->TX_req->sfn_sf = frame << 4 | subframe;
oai_nfapi_tx_req(Sched_INFO->TX_req); oai_nfapi_tx_req(Sched_INFO->TX_req);
} }
Sched_INFO->DL_req->sfn_sf = frame << 4 | subframe; Sched_INFO->DL_req->sfn_sf = frame << 4 | subframe;
oai_nfapi_dl_config_req(Sched_INFO->DL_req); // DJP - .dl_config_request_body.dl_config_pdu_list[0]); // DJP - FIXME TODO - yuk - only copes with 1 pdu oai_nfapi_dl_config_req(Sched_INFO->DL_req); // DJP - .dl_config_request_body.dl_config_pdu_list[0]); // DJP - FIXME TODO - yuk - only copes with 1 pdu
Sched_INFO->UE_release_req->sfn_sf = frame << 4 | subframe; Sched_INFO->UE_release_req->sfn_sf = frame << 4 | subframe;
...@@ -935,27 +937,27 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { ...@@ -935,27 +937,27 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
eNB->pdcch_vars[NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf)&1].num_pdcch_symbols=0; eNB->pdcch_vars[NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf)&1].num_pdcch_symbols=0;
} }
if (NFAPI_MODE!=NFAPI_MODE_VNF) if (NFAPI_MODE!=NFAPI_MODE_VNF)
for (i=0; i<number_hi_dci0_pdu; i++) { for (i=0; i<number_hi_dci0_pdu; i++) {
hi_dci0_req_pdu = &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[i]; hi_dci0_req_pdu = &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[i];
LOG_D(PHY,"NFAPI: hi_dci0_pdu %d : type %d\n",i,hi_dci0_req_pdu->pdu_type); LOG_D(PHY,"NFAPI: hi_dci0_pdu %d : type %d\n",i,hi_dci0_req_pdu->pdu_type);
switch (hi_dci0_req_pdu->pdu_type) { switch (hi_dci0_req_pdu->pdu_type) {
case NFAPI_HI_DCI0_DCI_PDU_TYPE: case NFAPI_HI_DCI0_DCI_PDU_TYPE:
handle_nfapi_hi_dci0_dci_pdu(eNB,NFAPI_SFNSF2SFN(HI_DCI0_req->sfn_sf),NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf),proc,hi_dci0_req_pdu); handle_nfapi_hi_dci0_dci_pdu(eNB,NFAPI_SFNSF2SFN(HI_DCI0_req->sfn_sf),NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf),proc,hi_dci0_req_pdu);
eNB->pdcch_vars[NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf)&1].num_dci++; eNB->pdcch_vars[NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf)&1].num_dci++;
break; break;
case NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE: case NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE:
handle_nfapi_hi_dci0_mpdcch_dci_pdu(eNB,proc,hi_dci0_req_pdu); handle_nfapi_hi_dci0_mpdcch_dci_pdu(eNB,proc,hi_dci0_req_pdu);
eNB->mpdcch_vars[subframe&1].num_dci++; eNB->mpdcch_vars[subframe&1].num_dci++;
break; break;
case NFAPI_HI_DCI0_HI_PDU_TYPE: case NFAPI_HI_DCI0_HI_PDU_TYPE:
handle_nfapi_hi_dci0_hi_pdu(eNB,NFAPI_SFNSF2SFN(HI_DCI0_req->sfn_sf),NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf),proc,hi_dci0_req_pdu); handle_nfapi_hi_dci0_hi_pdu(eNB,NFAPI_SFNSF2SFN(HI_DCI0_req->sfn_sf),NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf),proc,hi_dci0_req_pdu);
break; break;
}
} }
}
if (NFAPI_MODE!=NFAPI_MONOLITHIC) { if (NFAPI_MODE!=NFAPI_MONOLITHIC) {
if (number_ul_pdu>0) { if (number_ul_pdu>0) {
......
...@@ -1158,6 +1158,7 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { ...@@ -1158,6 +1158,7 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
const int subframe = proc->subframe_rx; const int subframe = proc->subframe_rx;
const int frame = proc->frame_rx; const int frame = proc->frame_rx;
uint32_t harq_pid0 = subframe2harq_pid(&eNB->frame_parms,frame,subframe); uint32_t harq_pid0 = subframe2harq_pid(&eNB->frame_parms,frame,subframe);
int rvidx_tab[4] = {0,2,3,1};
for (i = 0; i < NUMBER_OF_UE_MAX; i++) { for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
ulsch = eNB->ulsch[i]; ulsch = eNB->ulsch[i];
...@@ -1174,8 +1175,8 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { ...@@ -1174,8 +1175,8 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
if ((ulsch) && if ((ulsch) &&
(ulsch->rnti>0) && (ulsch->rnti>0) &&
(ulsch_harq->status == ACTIVE) && (ulsch_harq->status == ACTIVE) &&
(ulsch_harq->frame == frame) && ((ulsch_harq->frame == frame) || (ulsch_harq->repetition_number >1) ) &&
(ulsch_harq->subframe == subframe) && ((ulsch_harq->subframe == subframe) || (ulsch_harq->repetition_number >1) ) &&
(ulsch_harq->handled == 0)) { (ulsch_harq->handled == 0)) {
// UE has ULSCH scheduling // UE has ULSCH scheduling
for (int rb=0; for (int rb=0;
...@@ -1232,6 +1233,10 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { ...@@ -1232,6 +1233,10 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
ulsch_harq->cqi_crc_status, ulsch_harq->cqi_crc_status,
ulsch_harq->O_ACK, ulsch_harq->O_ACK,
eNB->ulsch_decoding_stats.p_time, eNB->ulsch_decoding_stats.max); eNB->ulsch_decoding_stats.p_time, eNB->ulsch_decoding_stats.max);
if (ulsch_harq->repetition_number < ulsch_harq->total_number_of_repetitions){
ulsch_harq->rvidx = rvidx_tab[(ulsch_harq->repetition_number%4)] ; // Set the correct rvidx for the next emtc repetitions
ulsch_harq->repetition_number +=1 ; // Increment repetition_number for the next ULSCH allocation
}
//compute the expected ULSCH RX power (for the stats) //compute the expected ULSCH RX power (for the stats)
ulsch_harq->delta_TF = get_hundred_times_delta_IF_eNB(eNB,i,harq_pid, 0); // 0 means bw_factor is not considered ulsch_harq->delta_TF = get_hundred_times_delta_IF_eNB(eNB,i,harq_pid, 0); // 0 means bw_factor is not considered
...@@ -1287,7 +1292,7 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { ...@@ -1287,7 +1292,7 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
*/ */
ulsch_harq->handled = 1; ulsch_harq->handled = 1;
} // ulsch in error } // ulsch in error
else { else if(ulsch_harq->repetition_number == ulsch_harq->total_number_of_repetitions){
fill_crc_indication(eNB,i,frame,subframe,0); // indicate ACK to MAC fill_crc_indication(eNB,i,frame,subframe,0); // indicate ACK to MAC
fill_rx_indication(eNB,i,frame,subframe); // indicate SDU to MAC fill_rx_indication(eNB,i,frame,subframe); // indicate SDU to MAC
ulsch_harq->status = SCH_IDLE; ulsch_harq->status = SCH_IDLE;
......
This diff is collapsed.
...@@ -147,7 +147,7 @@ typedef struct { ...@@ -147,7 +147,7 @@ typedef struct {
/// Rice factor??? /// Rice factor???
/// Walls (penetration loss) /// Walls (penetration loss)
/// Nodes in the scenario /// Nodes in the scenario
node_desc_t* nodes; node_desc_t *nodes;
} scenario_desc_t; } scenario_desc_t;
typedef enum { typedef enum {
...@@ -180,29 +180,66 @@ typedef enum { ...@@ -180,29 +180,66 @@ typedef enum {
EPA_medium, EPA_medium,
EPA_high, EPA_high,
} SCM_t; } SCM_t;
#define CHANNELMOD_MAP_INIT \
{"custom",custom},\
{"SCM_A",SCM_A},\
{"SCM_B",SCM_B},\
{"SCM_C",SCM_C},\
{"SCM_D",SCM_D},\
{"EPA",EPA},\
{"EVA",EVA},\
{"ETU",ETU},\
{"MBSFN",MBSFN},\
{"Rayleigh8",Rayleigh8},\
{"Rayleigh1",Rayleigh1},\
{"Rayleigh1_800",Rayleigh1_800},\
{"Rayleigh1_corr",Rayleigh1_corr},\
{"Rayleigh1_anticorr",Rayleigh1_anticorr},\
{"Rice8",Rice8},\
{"Rice1",Rice1},\
{"Rice1_corr",Rice1_corr},\
{"Rice1_anticorr",Rice1_anticorr},\
{"AWGN",AWGN},\
{"Rayleigh1_orthogonal",Rayleigh1_orthogonal},\
{"Rayleigh1_orth_eff_ch_TM4_prec_real",Rayleigh1_orth_eff_ch_TM4_prec_real},\
{"Rayleigh1_orth_eff_ch_TM4_prec_imag",Rayleigh1_orth_eff_ch_TM4_prec_imag},\
{"Rayleigh8_orth_eff_ch_TM4_prec_real",Rayleigh8_orth_eff_ch_TM4_prec_real},\
{"Rayleigh8_orth_eff_ch_TM4_prec_imag",Rayleigh8_orth_eff_ch_TM4_prec_imag},\
{"TS_SHIFT",TS_SHIFT},\
{"EPA_low",EPA_low},\
{"EPA_medium",EPA_medium},\
{"EPA_high",EPA_high},\
{NULL, -1}
#define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\n"
#define CHANNELMOD_SECTION "channelmod"
#define CHANNELMOD_PARAMS_DESC { \
{"s" ,CONFIG_HLP_SNR, PARAMFLAG_CMDLINE_NOPREFIXENABLED , dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0},\
{"sinr_dB" ,NULL, 0 , dblptr:&sinr_dB, defdblval:0, TYPE_DOUBLE, 0},\
}
#include "platform_constants.h" #include "platform_constants.h"
typedef struct { typedef struct {
channel_desc_t *RU2UE[NUMBER_OF_RU_MAX][NUMBER_OF_UE_MAX][MAX_NUM_CCs]; channel_desc_t *RU2UE[NUMBER_OF_RU_MAX][NUMBER_OF_UE_MAX][MAX_NUM_CCs];
channel_desc_t *UE2RU[NUMBER_OF_UE_MAX][NUMBER_OF_RU_MAX][MAX_NUM_CCs]; channel_desc_t *UE2RU[NUMBER_OF_UE_MAX][NUMBER_OF_RU_MAX][MAX_NUM_CCs];
double r_re_DL[NUMBER_OF_UE_MAX][2][30720]; double r_re_DL[NUMBER_OF_UE_MAX][2][30720];
double r_im_DL[NUMBER_OF_UE_MAX][2][30720]; double r_im_DL[NUMBER_OF_UE_MAX][2][30720];
double r_re_UL[NUMBER_OF_eNB_MAX][2][30720]; double r_re_UL[NUMBER_OF_eNB_MAX][2][30720];
double r_im_UL[NUMBER_OF_eNB_MAX][2][30720]; double r_im_UL[NUMBER_OF_eNB_MAX][2][30720];
int RU_output_mask[NUMBER_OF_UE_MAX]; int RU_output_mask[NUMBER_OF_UE_MAX];
int UE_output_mask[NUMBER_OF_RU_MAX]; int UE_output_mask[NUMBER_OF_RU_MAX];
pthread_mutex_t RU_output_mutex[NUMBER_OF_UE_MAX]; pthread_mutex_t RU_output_mutex[NUMBER_OF_UE_MAX];
pthread_mutex_t UE_output_mutex[NUMBER_OF_RU_MAX]; pthread_mutex_t UE_output_mutex[NUMBER_OF_RU_MAX];
pthread_mutex_t subframe_mutex; pthread_mutex_t subframe_mutex;
int subframe_ru_mask; int subframe_ru_mask;
int subframe_UE_mask; int subframe_UE_mask;
openair0_timestamp current_ru_rx_timestamp[NUMBER_OF_RU_MAX][MAX_NUM_CCs]; openair0_timestamp current_ru_rx_timestamp[NUMBER_OF_RU_MAX][MAX_NUM_CCs];
openair0_timestamp current_UE_rx_timestamp[MAX_MOBILES_PER_ENB][MAX_NUM_CCs]; openair0_timestamp current_UE_rx_timestamp[MAX_MOBILES_PER_ENB][MAX_NUM_CCs];
openair0_timestamp last_ru_rx_timestamp[NUMBER_OF_RU_MAX][MAX_NUM_CCs]; openair0_timestamp last_ru_rx_timestamp[NUMBER_OF_RU_MAX][MAX_NUM_CCs];
openair0_timestamp last_UE_rx_timestamp[MAX_MOBILES_PER_ENB][MAX_NUM_CCs]; openair0_timestamp last_UE_rx_timestamp[MAX_MOBILES_PER_ENB][MAX_NUM_CCs];
double ru_amp[NUMBER_OF_RU_MAX]; double ru_amp[NUMBER_OF_RU_MAX];
pthread_t rfsim_thread; pthread_t rfsim_thread;
} sim_t; } sim_t;
...@@ -231,7 +268,7 @@ typedef struct { ...@@ -231,7 +268,7 @@ typedef struct {
channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
uint8_t nb_rx, uint8_t nb_rx,
SCM_t channel_model, SCM_t channel_model,
double sampling_rate, double sampling_rate,
double channel_bandwidth, double channel_bandwidth,
double forgetting_factor, double forgetting_factor,
int32_t channel_offset, int32_t channel_offset,
...@@ -395,9 +432,23 @@ void multipath_tv_channel(channel_desc_t *desc, ...@@ -395,9 +432,23 @@ void multipath_tv_channel(channel_desc_t *desc,
/**@} */ /**@} */
/**@} */ /**@} */
void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_sig,
int rxAnt,
channel_desc_t *channelDesc,
int nbSamples,
uint64_t TS,
uint32_t CirSize
);
int modelid_fromname(char *modelname);
double channelmod_get_snr_dB(void);
double channelmod_get_sinr_dB(void);
void init_channelmod(void) ;
double N_RB2sampling_rate(uint16_t N_RB); double N_RB2sampling_rate(uint16_t N_RB);
double N_RB2channel_bandwidth(uint16_t N_RB); double N_RB2channel_bandwidth(uint16_t N_RB);
#include "targets/RT/USER/rfsim.h" #include "targets/RT/USER/rfsim.h"
void do_DL_sig(sim_t *sim, void do_DL_sig(sim_t *sim,
...@@ -409,9 +460,10 @@ void do_DL_sig(sim_t *sim, ...@@ -409,9 +460,10 @@ void do_DL_sig(sim_t *sim,
int CC_id); int CC_id);
void do_UL_sig(sim_t *sim, void do_UL_sig(sim_t *sim,
uint16_t subframe,uint8_t abstraction_flag,LTE_DL_FRAME_PARMS *frame_parms, uint16_t subframe,uint8_t abstraction_flag,LTE_DL_FRAME_PARMS *frame_parms,
uint32_t frame,int ru_id,uint8_t CC_id); uint32_t frame,int ru_id,uint8_t CC_id);
#endif #endif
...@@ -280,6 +280,7 @@ typedef struct RrcConfigurationReq_s { ...@@ -280,6 +280,7 @@ typedef struct RrcConfigurationReq_s {
long *pdsch_maxNumRepetitionCEmodeB_r13 [MAX_NUM_CCs]; long *pdsch_maxNumRepetitionCEmodeB_r13 [MAX_NUM_CCs];
long *pusch_maxNumRepetitionCEmodeA_r13 [MAX_NUM_CCs]; long *pusch_maxNumRepetitionCEmodeA_r13 [MAX_NUM_CCs];
long *pusch_maxNumRepetitionCEmodeB_r13 [MAX_NUM_CCs]; long *pusch_maxNumRepetitionCEmodeB_r13 [MAX_NUM_CCs];
long *pusch_repetitionLevelCEmodeA_r13 [MAX_NUM_CCs];
long *pusch_HoppingOffset_v1310 [MAX_NUM_CCs]; long *pusch_HoppingOffset_v1310 [MAX_NUM_CCs];
#endif #endif
//SIB18 //SIB18
......
...@@ -859,6 +859,21 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in ...@@ -859,6 +859,21 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in
config_fname); config_fname);
} }
RRC_CONFIGURATION_REQ(msg_p).pusch_repetitionLevelCEmodeA_r13[cc_idx] = CALLOC(1, sizeof(long));
if (!strcmp(eMTCconfig->pusch_repetitionLevelCEmodeA_r13, "l1")) {
*RRC_CONFIGURATION_REQ(msg_p).pusch_repetitionLevelCEmodeA_r13[cc_idx] = 0;
} else if (!strcmp(eMTCconfig->pusch_repetitionLevelCEmodeA_r13, "l2")) {
*RRC_CONFIGURATION_REQ(msg_p).pusch_repetitionLevelCEmodeA_r13[cc_idx] = 1;
} else if (!strcmp(eMTCconfig->pusch_repetitionLevelCEmodeA_r13, "l3")) {
*RRC_CONFIGURATION_REQ(msg_p).pusch_repetitionLevelCEmodeA_r13[cc_idx] = 2;
} else if (!strcmp(eMTCconfig->pusch_repetitionLevelCEmodeA_r13, "l4")) {
*RRC_CONFIGURATION_REQ(msg_p).pusch_repetitionLevelCEmodeA_r13[cc_idx] = 3;
} else {
AssertFatal (0,
"Failed to parse eNB configuration file %s, pusch_repetitionLevelCEmodeA_r13 unknown value!\n",
config_fname);
}
char rachCELevelInfoListPath[MAX_OPTNAME_SIZE * 2]; char rachCELevelInfoListPath[MAX_OPTNAME_SIZE * 2];
config_getlist(&rachcelevellist, NULL, 0, brparamspath); config_getlist(&rachcelevellist, NULL, 0, brparamspath);
RRC_CONFIGURATION_REQ (msg_p).rach_CE_LevelInfoList_r13_size[cc_idx] = rachcelevellist.numelt; RRC_CONFIGURATION_REQ (msg_p).rach_CE_LevelInfoList_r13_size[cc_idx] = rachcelevellist.numelt;
......
...@@ -407,6 +407,7 @@ typedef enum { ...@@ -407,6 +407,7 @@ typedef enum {
#define ENB_CONFIG_STRING_PUSCH_MAX_NUM_REPETITION_CE_MODE_A_R13 "pusch_maxNumRepetitionCEmodeA_r13" #define ENB_CONFIG_STRING_PUSCH_MAX_NUM_REPETITION_CE_MODE_A_R13 "pusch_maxNumRepetitionCEmodeA_r13"
#define ENB_CONFIG_STRING_PUSCH_MAX_NUM_REPETITION_CE_MODE_B_R13 "pusch_maxNumRepetitionCEmodeB_r13" #define ENB_CONFIG_STRING_PUSCH_MAX_NUM_REPETITION_CE_MODE_B_R13 "pusch_maxNumRepetitionCEmodeB_r13"
#define ENB_CONFIG_STRING_PUSCH_REPETITION_LEVEL_CE_MODE_A_R13 "pusch_repetitionLevelCEmodeA_r13"
#define ENB_CONFIG_STRING_PUSCH_HOPPING_OFFSET_V1310 "pusch_HoppingOffset_v1310" #define ENB_CONFIG_STRING_PUSCH_HOPPING_OFFSET_V1310 "pusch_HoppingOffset_v1310"
......
...@@ -64,6 +64,7 @@ ...@@ -64,6 +64,7 @@
#define ENB_CONFIG_STRING_PDSCH_MAX_NUM_REPETITION_CE_MODE_B_R13 "pdsch_maxNumRepetitionCEmodeB_r13" #define ENB_CONFIG_STRING_PDSCH_MAX_NUM_REPETITION_CE_MODE_B_R13 "pdsch_maxNumRepetitionCEmodeB_r13"
#define ENB_CONFIG_STRING_PUSCH_MAX_NUM_REPETITION_CE_MODE_A_R13 "pusch_maxNumRepetitionCEmodeA_r13" #define ENB_CONFIG_STRING_PUSCH_MAX_NUM_REPETITION_CE_MODE_A_R13 "pusch_maxNumRepetitionCEmodeA_r13"
#define ENB_CONFIG_STRING_PUSCH_MAX_NUM_REPETITION_CE_MODE_B_R13 "pusch_maxNumRepetitionCEmodeB_r13" #define ENB_CONFIG_STRING_PUSCH_MAX_NUM_REPETITION_CE_MODE_B_R13 "pusch_maxNumRepetitionCEmodeB_r13"
#define ENB_CONFIG_STRING_PUSCH_REPETITION_LEVEL_CE_MODE_A_R13 "pusch_repetitionLevelCEmodeA_r13"
#define ENB_CONFIG_STRING_PUSCH_HOPPING_OFFSET_V1310 "pusch_HoppingOffset_v1310" #define ENB_CONFIG_STRING_PUSCH_HOPPING_OFFSET_V1310 "pusch_HoppingOffset_v1310"
#define ENB_CONFIG_STRING_SYSTEM_INFO_VALUE_TAG_LIST "system_info_value_tag_SI" #define ENB_CONFIG_STRING_SYSTEM_INFO_VALUE_TAG_LIST "system_info_value_tag_SI"
#define ENB_CONFIG_STRING_FIRST_PREAMBLE_R13 "firstPreamble_r13" #define ENB_CONFIG_STRING_FIRST_PREAMBLE_R13 "firstPreamble_r13"
...@@ -161,6 +162,7 @@ typedef struct ccparams_eMTC_s { ...@@ -161,6 +162,7 @@ typedef struct ccparams_eMTC_s {
char *pdsch_maxNumRepetitionCEmodeB_r13; char *pdsch_maxNumRepetitionCEmodeB_r13;
char *pusch_maxNumRepetitionCEmodeA_r13; char *pusch_maxNumRepetitionCEmodeA_r13;
char *pusch_maxNumRepetitionCEmodeB_r13; char *pusch_maxNumRepetitionCEmodeB_r13;
char *pusch_repetitionLevelCEmodeA_r13;
} ccparams_eMTC_t; } ccparams_eMTC_t;
...@@ -230,6 +232,7 @@ typedef struct ccparams_eMTC_s { ...@@ -230,6 +232,7 @@ typedef struct ccparams_eMTC_s {
{ENB_CONFIG_STRING_PRACH_HOPPING_OFFSET_R13, NULL, 0, iptr:&eMTCconfig->prach_HoppingOffset_r13, defintval:0, TYPE_INT, 0}, \ {ENB_CONFIG_STRING_PRACH_HOPPING_OFFSET_R13, NULL, 0, iptr:&eMTCconfig->prach_HoppingOffset_r13, defintval:0, TYPE_INT, 0}, \
{ENB_CONFIG_STRING_PDSCH_MAX_NUM_REPETITION_CE_MODE_A_R13, NULL, 0, strptr:&eMTCconfig->pdsch_maxNumRepetitionCEmodeA_r13, defstrval:"r16", TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_PDSCH_MAX_NUM_REPETITION_CE_MODE_A_R13, NULL, 0, strptr:&eMTCconfig->pdsch_maxNumRepetitionCEmodeA_r13, defstrval:"r16", TYPE_STRING, 0}, \
{ENB_CONFIG_STRING_PUSCH_MAX_NUM_REPETITION_CE_MODE_A_R13, NULL, 0, strptr:&eMTCconfig->pusch_maxNumRepetitionCEmodeA_r13, defstrval:"r8", TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_PUSCH_MAX_NUM_REPETITION_CE_MODE_A_R13, NULL, 0, strptr:&eMTCconfig->pusch_maxNumRepetitionCEmodeA_r13, defstrval:"r8", TYPE_STRING, 0}, \
{ENB_CONFIG_STRING_PUSCH_REPETITION_LEVEL_CE_MODE_A_R13, NULL, 0, strptr:&eMTCconfig->pusch_repetitionLevelCEmodeA_r13, defstrval:"l1", TYPE_STRING, 0}, \
{ENB_CONFIG_STRING_CELL_SELECTION_INFO_CE_R13, NULL, 0, strptr:&eMTCconfig->cellSelectionInfoCE_r13, defstrval:"ENABLE", TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_CELL_SELECTION_INFO_CE_R13, NULL, 0, strptr:&eMTCconfig->cellSelectionInfoCE_r13, defstrval:"ENABLE", TYPE_STRING, 0}, \
{ENB_CONFIG_STRING_Q_RX_LEV_MIN_CE_R13, NULL, 0, iptr:&eMTCconfig->q_RxLevMinCE_r13, defintval:-70, TYPE_INT, 0}, \ {ENB_CONFIG_STRING_Q_RX_LEV_MIN_CE_R13, NULL, 0, iptr:&eMTCconfig->q_RxLevMinCE_r13, defintval:-70, TYPE_INT, 0}, \
{ENB_CONFIG_STRING_BANDWIDTH_REDUCED_ACCESS_RELATED_INFO_R13, NULL, 0, strptr:&eMTCconfig->bandwidthReducedAccessRelatedInfo_r13, defstrval:"ENABLE", TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_BANDWIDTH_REDUCED_ACCESS_RELATED_INFO_R13, NULL, 0, strptr:&eMTCconfig->bandwidthReducedAccessRelatedInfo_r13, defstrval:"ENABLE", TYPE_STRING, 0}, \
......
...@@ -68,6 +68,7 @@ ...@@ -68,6 +68,7 @@
extern RAN_CONTEXT_t RC; extern RAN_CONTEXT_t RC;
extern const uint8_t pusch_repetition_Table8_2_36213[3][4];
extern int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req); extern int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req);
...@@ -98,6 +99,7 @@ void ...@@ -98,6 +99,7 @@ void
add_msg3(module_id_t module_idP, int CC_id, RA_t *ra, frame_t frameP, add_msg3(module_id_t module_idP, int CC_id, RA_t *ra, frame_t frameP,
sub_frame_t subframeP) { sub_frame_t subframeP) {
eNB_MAC_INST *mac = RC.mac[module_idP]; eNB_MAC_INST *mac = RC.mac[module_idP];
eNB_RRC_INST *rrc = RC.rrc[module_idP];
COMMON_channels_t *cc = &mac->common_channels[CC_id]; COMMON_channels_t *cc = &mac->common_channels[CC_id];
uint8_t j; uint8_t j;
nfapi_ul_config_request_t *ul_req; nfapi_ul_config_request_t *ul_req;
...@@ -108,6 +110,7 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t *ra, frame_t frameP, ...@@ -108,6 +110,7 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t *ra, frame_t frameP,
nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu; nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu;
uint8_t sf_ahead_dl; uint8_t sf_ahead_dl;
uint8_t rvseq[4] = {0, 2, 3, 1}; uint8_t rvseq[4] = {0, 2, 3, 1};
uint8_t pusch_maxNumRepetitionCEmodeA_r13;
ul_req = &mac->UL_req_tmp[CC_id][ra->Msg3_subframe]; ul_req = &mac->UL_req_tmp[CC_id][ra->Msg3_subframe];
ul_req_body = &ul_req->ul_config_request_body; ul_req_body = &ul_req->ul_config_request_body;
AssertFatal(ra->state != IDLE, "RA is not active for RA %X\n", AssertFatal(ra->state != IDLE, "RA is not active for RA %X\n",
...@@ -140,7 +143,13 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t *ra, frame_t frameP, ...@@ -140,7 +143,13 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t *ra, frame_t frameP,
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = get_TBS_UL (ra->msg3_mcs, ra->msg3_nb_rb); ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = get_TBS_UL (ra->msg3_mcs, ra->msg3_nb_rb);
// Re13 fields // Re13 fields
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type = ra->rach_resource_type > 2 ? 2 : 1; ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type = ra->rach_resource_type > 2 ? 2 : 1;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions = 1; if (ra->rach_resource_type > 0) {
pusch_maxNumRepetitionCEmodeA_r13= *(rrc->configuration.pusch_maxNumRepetitionCEmodeA_r13[CC_id]);
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions= pusch_repetition_Table8_2_36213[pusch_maxNumRepetitionCEmodeA_r13][ra->pusch_repetition_levels];
}
else{
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions=1;
}
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number = 1; ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number = 1;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io = (ra->Msg3_frame * 10) + ra->Msg3_subframe; ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io = (ra->Msg3_frame * 10) + ra->Msg3_subframe;
ul_req_body->number_of_pdus++; ul_req_body->number_of_pdus++;
...@@ -238,6 +247,7 @@ void generate_Msg2(module_id_t module_idP, ...@@ -238,6 +247,7 @@ void generate_Msg2(module_id_t module_idP,
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
eNB_MAC_INST *mac = RC.mac[module_idP]; eNB_MAC_INST *mac = RC.mac[module_idP];
eNB_RRC_INST *rrc = RC.rrc[module_idP];
COMMON_channels_t *cc = mac->common_channels; COMMON_channels_t *cc = mac->common_channels;
uint8_t *vrb_map = NULL; uint8_t *vrb_map = NULL;
int first_rb = 0; int first_rb = 0;
...@@ -250,6 +260,7 @@ void generate_Msg2(module_id_t module_idP, ...@@ -250,6 +260,7 @@ void generate_Msg2(module_id_t module_idP,
dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu]; dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu];
N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth); N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth);
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
uint8_t PUSCH_Rep_Level;
int rmax = 0; int rmax = 0;
int rep = 0; int rep = 0;
int reps = 0; int reps = 0;
...@@ -261,6 +272,13 @@ void generate_Msg2(module_id_t module_idP, ...@@ -261,6 +272,13 @@ void generate_Msg2(module_id_t module_idP,
uint16_t absSF = (10 * frameP) + subframeP; uint16_t absSF = (10 * frameP) + subframeP;
uint16_t absSF_Msg2 = (10 * ra->Msg2_frame) + ra->Msg2_subframe; uint16_t absSF_Msg2 = (10 * ra->Msg2_frame) + ra->Msg2_subframe;
if (ra->rach_resource_type > 0) {
PUSCH_Rep_Level= *(rrc->configuration.pusch_repetitionLevelCEmodeA_r13[CC_idP]);
}
else {
PUSCH_Rep_Level= 0;
}
if (absSF > absSF_Msg2) { if (absSF > absSF_Msg2) {
return; // we're not ready yet return; // we're not ready yet
} }
...@@ -402,6 +420,8 @@ void generate_Msg2(module_id_t module_idP, ...@@ -402,6 +420,8 @@ void generate_Msg2(module_id_t module_idP,
ra->msg2_mpdcch_repetition_cnt++; ra->msg2_mpdcch_repetition_cnt++;
} }
ra->pusch_repetition_levels = PUSCH_Rep_Level;
if((ra->Msg2_frame == frameP) && (ra->Msg2_subframe == subframeP)) { if((ra->Msg2_frame == frameP) && (ra->Msg2_subframe == subframeP)) {
/* Program PDSCH */ /* Program PDSCH */
LOG_D(MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming PDSCH\n", LOG_D(MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming PDSCH\n",
...@@ -1270,6 +1290,7 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP, ...@@ -1270,6 +1290,7 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP,
UE_id = find_UE_id(module_idP, ra->rnti); UE_id = find_UE_id(module_idP, ra->rnti);
DevAssert(UE_id != -1); DevAssert(UE_id != -1);
mac->UE_list.UE_template[UE_PCCID(module_idP, UE_id)][UE_id].configured = TRUE; mac->UE_list.UE_template[UE_PCCID(module_idP, UE_id)][UE_id].configured = TRUE;
mac->UE_list.UE_template[UE_PCCID(module_idP, UE_id)][UE_id].pusch_repetition_levels=ra->pusch_repetition_levels;
cancel_ra_proc(module_idP, CC_idP, frameP, ra->rnti); cancel_ra_proc(module_idP, CC_idP, frameP, ra->rnti);
} }
} }
......
...@@ -84,6 +84,14 @@ uint8_t rb_table[34] = { ...@@ -84,6 +84,14 @@ uint8_t rb_table[34] = {
81, 90, 96, 100 // 30-33 81, 90, 96, 100 // 30-33
}; };
// This table hold the possible number of MTC repetition for CE ModeA
const uint8_t pusch_repetition_Table8_2_36213[3][4]=
{
{1 , 2 , 4 , 8 },
{1 , 4 , 8 , 16},
{1 , 4 , 16, 32}
};
extern mui_t rrc_eNB_mui; extern mui_t rrc_eNB_mui;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -301,16 +309,22 @@ rx_sdu(const module_id_t enb_mod_idP, ...@@ -301,16 +309,22 @@ rx_sdu(const module_id_t enb_mod_idP,
if (ra->msg3_round >= mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx - 1) { if (ra->msg3_round >= mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx - 1) {
cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti);
} else { } else {
// first_rb = UE_template_ptr->first_rb_ul[harq_pid]; // UE_id = -1 !!!! if (ra->rach_resource_type > 0) {
ra->msg3_round++; cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); // TODO: Currently we don't support retransmission of Msg3 ( If in error Cancel RA procedure and reattach)
/* Prepare handling of retransmission */ }
get_Msg3allocret(&mac->common_channels[CC_idP], else
ra->Msg3_subframe, {
ra->Msg3_frame, // first_rb = UE_template_ptr->first_rb_ul[harq_pid]; // UE_id = -1 !!!!
&ra->Msg3_frame, ra->msg3_round++;
&ra->Msg3_subframe); /* Prepare handling of retransmission */
// prepare handling of retransmission get_Msg3allocret(&mac->common_channels[CC_idP],
add_msg3(enb_mod_idP, CC_idP, ra, frameP, subframeP); ra->Msg3_subframe,
ra->Msg3_frame,
&ra->Msg3_frame,
&ra->Msg3_subframe);
// prepare handling of retransmission
add_msg3(enb_mod_idP, CC_idP, ra, frameP, subframeP);
}
} }
/* TODO: program NACK for PHICH? */ /* TODO: program NACK for PHICH? */
...@@ -1958,10 +1972,13 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, ...@@ -1958,10 +1972,13 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP,
int tpc = 0; int tpc = 0;
int cqi_req = 0; int cqi_req = 0;
eNB_MAC_INST *eNB = RC.mac[module_idP]; eNB_MAC_INST *eNB = RC.mac[module_idP];
eNB_RRC_INST *rrc = RC.rrc[module_idP];
COMMON_channels_t *cc = eNB->common_channels; COMMON_channels_t *cc = eNB->common_channels;
UE_list_t *UE_list = &(eNB->UE_list); UE_list_t *UE_list = &(eNB->UE_list);
UE_TEMPLATE *UE_template = NULL; UE_TEMPLATE *UE_template = NULL;
UE_sched_ctrl_t *UE_sched_ctrl = NULL; UE_sched_ctrl_t *UE_sched_ctrl = NULL;
uint8_t Total_Num_Rep_ULSCH,pusch_maxNumRepetitionCEmodeA_r13;
uint8_t UL_Scheduling_DCI_SF,UL_Scheduling_DCI_Frame_Even_Odd_Flag; //TODO: To be removed after scheduler relaxation Task
if (sched_subframeP < subframeP) { if (sched_subframeP < subframeP) {
sched_frame++; sched_frame++;
...@@ -1970,11 +1987,9 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, ...@@ -1970,11 +1987,9 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP,
nfapi_hi_dci0_request_body_t *hi_dci0_req = &(eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body); nfapi_hi_dci0_request_body_t *hi_dci0_req = &(eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body);
nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = NULL; nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = NULL;
nfapi_ul_config_request_body_t *ul_req_tmp = &(eNB->UL_req_tmp[CC_id][sched_subframeP].ul_config_request_body); nfapi_ul_config_request_body_t *ul_req_tmp = &(eNB->UL_req_tmp[CC_id][sched_subframeP].ul_config_request_body);
nfapi_ul_config_request_body_t *ul_req_body_Rep;
/* If frameP odd don't schedule */ nfapi_ul_config_request_pdu_t *ul_config_pdu;
if ((frameP & 1) == 1) { nfapi_ul_config_request_pdu_t *ul_config_pdu_Rep;
return;
}
/* Loop over all active UEs */ /* Loop over all active UEs */
for (UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) { for (UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) {
...@@ -2032,8 +2047,18 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, ...@@ -2032,8 +2047,18 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP,
RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = UE_template->estimated_ul_buffer; RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = UE_template->estimated_ul_buffer;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO, UE_template->estimated_ul_buffer); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO, UE_template->estimated_ul_buffer);
pusch_maxNumRepetitionCEmodeA_r13= *(rrc->configuration.pusch_maxNumRepetitionCEmodeA_r13[CC_id]);
Total_Num_Rep_ULSCH = pusch_repetition_Table8_2_36213[pusch_maxNumRepetitionCEmodeA_r13][UE_template->pusch_repetition_levels];
UL_Scheduling_DCI_SF = (40-4 - Total_Num_Rep_ULSCH)%10; //TODO: [eMTC Scheduler] To be removed after scheduler relaxation task
UL_Scheduling_DCI_Frame_Even_Odd_Flag= ! (((40-4 - Total_Num_Rep_ULSCH)/10 )%2); //TODO: [eMTC Scheduler] To be removed after scheduler relaxation task
/* If frameP odd don't schedule */
if ((frameP&1) == UL_Scheduling_DCI_Frame_Even_Odd_Flag) //TODO: [eMTC Scheduler] To be removed after scheduler relaxation task
{
//if ((UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0) && (subframeP == 5)) { //if ((UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0) && (subframeP == 5)) {
if ((UE_template->ul_SR > 0 || round_UL > 0 || status < RRC_CONNECTED) && (subframeP == 5)) { if ((UE_template->ul_SR > 0 || round_UL > 0 || status < RRC_CONNECTED) && (subframeP == UL_Scheduling_DCI_SF)) {
/* /*
* if there is information on bsr of DCCH, DTCH, * if there is information on bsr of DCCH, DTCH,
* or if there is UL_SR, * or if there is UL_SR,
...@@ -2184,7 +2209,7 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, ...@@ -2184,7 +2209,7 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP,
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_start = UE_template->first_rb_ul[harq_pid]; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_start = UE_template->first_rb_ul[harq_pid];
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_resource_blocks = 6; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_resource_blocks = 6;
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB = 3 hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB = 3
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.pusch_repetition_levels = 0; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.pusch_repetition_levels = UE_template->pusch_repetition_levels;
AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13 == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13__setup__mpdcch_pdsch_HoppingConfig_r13_off, AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13 == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13__setup__mpdcch_pdsch_HoppingConfig_r13_off,
"epdcch_setconfig_r11->ext2->mpdcch_config_r13->mpdcch_pdsch_HoppingConfig_r13 is not off\n"); "epdcch_setconfig_r11->ext2->mpdcch_config_r13->mpdcch_pdsch_HoppingConfig_r13 is not off\n");
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.frequency_hopping_flag = 1 - epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.frequency_hopping_flag = 1 - epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13;
...@@ -2234,7 +2259,7 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, ...@@ -2234,7 +2259,7 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP,
); );
fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus],
UE_template->rach_resource_type > 2 ? 2 : 1, UE_template->rach_resource_type > 2 ? 2 : 1,
1, // total_number_of_repetitions Total_Num_Rep_ULSCH, // total_number_of_repetitions
1, // repetition_number 1, // repetition_number
(frameP * 10) + subframeP); (frameP * 10) + subframeP);
ul_req_tmp->number_of_pdus++; ul_req_tmp->number_of_pdus++;
...@@ -2363,6 +2388,25 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, ...@@ -2363,6 +2388,25 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP,
} }
} // UE_is_to_be_scheduled } // UE_is_to_be_scheduled
} // ULCCs } // ULCCs
} // loop over UE_id } // loop over UE_id
} // Schedule new ULSCH
// This section is to repeat ULSCH PDU for a number of MTC repetitions
for(int i=0;i<ul_req_tmp->number_of_pdus;i++)
{
ul_config_pdu = &ul_req_tmp->ul_config_pdu_list[i];
if (ul_config_pdu->pdu_type!=NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) // Repeat ULSCH PDUs only
continue ;
if(ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number < ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions)
{
ul_req_body_Rep = &eNB->UL_req_tmp[CC_id][(sched_subframeP+1)%10].ul_config_request_body;
ul_config_pdu_Rep = &ul_req_body_Rep->ul_config_pdu_list[ul_req_body_Rep->number_of_pdus];
memcpy ((void *) ul_config_pdu_Rep, ul_config_pdu, sizeof (nfapi_ul_config_request_pdu_t));
ul_config_pdu_Rep->ulsch_pdu.ulsch_pdu_rel8.handle = eNB->ul_handle++;
ul_config_pdu_Rep->ulsch_pdu.ulsch_pdu_rel13.repetition_number = ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number +1;
ul_req_body_Rep->number_of_pdus++;
} //repetition_number < total_number_of_repetitions
} // For loop on PDUs
} }
#endif #endif
...@@ -921,6 +921,8 @@ typedef struct { ...@@ -921,6 +921,8 @@ typedef struct {
uint8_t rach_resource_type; uint8_t rach_resource_type;
uint16_t mpdcch_repetition_cnt; uint16_t mpdcch_repetition_cnt;
frame_t Msg2_frame; frame_t Msg2_frame;
/// Repetition column in pusch_repetition Table 8.2.b in TS36.213
uint8_t pusch_repetition_levels;
#endif #endif
sub_frame_t Msg2_subframe; sub_frame_t Msg2_subframe;
...@@ -1133,6 +1135,8 @@ typedef struct { ...@@ -1133,6 +1135,8 @@ typedef struct {
uint8_t msg2_narrowband; uint8_t msg2_narrowband;
uint8_t msg34_narrowband; uint8_t msg34_narrowband;
int msg4_rrc_sdu_length; int msg4_rrc_sdu_length;
/// Repetition column in pusch_repetition Table 8.2.b in TS36.213
uint8_t pusch_repetition_levels;
#endif #endif
int32_t crnti_rrc_mui; int32_t crnti_rrc_mui;
int8_t crnti_harq_pid; int8_t crnti_harq_pid;
......
...@@ -127,7 +127,6 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB, ...@@ -127,7 +127,6 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB,
uint8_t *rar = (uint8_t *)(dlsch_buffer + 1); uint8_t *rar = (uint8_t *)(dlsch_buffer + 1);
uint32_t rballoc = 0; uint32_t rballoc = 0;
uint32_t reps = 0;
uint32_t ULdelay = 0; uint32_t ULdelay = 0;
uint32_t cqireq = 0; uint32_t cqireq = 0;
uint32_t mpdcch_nb_index = 0; uint32_t mpdcch_nb_index = 0;
...@@ -159,7 +158,6 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB, ...@@ -159,7 +158,6 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB,
N_NB_index = get_numnarrowbandbits(cc->mib->message.dl_Bandwidth); N_NB_index = get_numnarrowbandbits(cc->mib->message.dl_Bandwidth);
/* UL Grant */ /* UL Grant */
reps = 0;
ra->msg3_mcs = 7; ra->msg3_mcs = 7;
TPC = 3; // no power increase TPC = 3; // no power increase
ULdelay = 0; ULdelay = 0;
...@@ -170,7 +168,7 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB, ...@@ -170,7 +168,7 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB,
uint32_t buffer = 0; uint32_t buffer = 0;
buffer |= ra->msg34_narrowband << (16 + (4 - N_NB_index)); buffer |= ra->msg34_narrowband << (16 + (4 - N_NB_index));
buffer |= ((rballoc & 0x0F) << (12 + (4 - N_NB_index))); buffer |= ((rballoc & 0x0F) << (12 + (4 - N_NB_index)));
buffer |= ((reps & 0x03) << (10 + (4 - N_NB_index))); buffer |= ((ra->pusch_repetition_levels & 0x03) << (10 + (4 - N_NB_index)));
buffer |= ((ra->msg3_mcs & 0x07) << (7 + (4 - N_NB_index))); buffer |= ((ra->msg3_mcs & 0x07) << (7 + (4 - N_NB_index)));
buffer |= ((TPC & 0x07) << (4 + (4 - N_NB_index))); buffer |= ((TPC & 0x07) << (4 + (4 - N_NB_index)));
buffer |= ((cqireq & 0x01) << (3 + (4 - N_NB_index))); buffer |= ((cqireq & 0x01) << (3 + (4 - N_NB_index)));
......
...@@ -410,7 +410,6 @@ typedef int(*oai_transport_initfunc_t)(openair0_device *device, openair0_config_ ...@@ -410,7 +410,6 @@ typedef int(*oai_transport_initfunc_t)(openair0_device *device, openair0_config_
#define OPTION_LZ4 0x00000001 // LZ4 compression (option_value is set to compressed size) #define OPTION_LZ4 0x00000001 // LZ4 compression (option_value is set to compressed size)
#define sample_t struct complex16 // 2*16 bits complex number
typedef struct { typedef struct {
uint64_t magic; // Magic value (see defines above) uint64_t magic; // Magic value (see defines above)
......
#General # General
This is a RF simulator that allows to test OAI without a RF board. This is a RF simulator that allows to test OAI without a RF board.
It replaces a actual RF board driver. It replaces a actual RF board driver.
As much as possible, it works like a RF board, but not in realtime: it can run faster than realtime if there is enough CPU or slower (it is CPU bound instead of real time RF sampling bound) As much as possible, it works like a RF board, but not in realtime: it can run faster than realtime if there is enough CPU or slower (it is CPU bound instead of real time RF sampling bound)
#build # build
## From build_oai ## From [build_oai](../../../doc/BUILD.md) script
You can build it the same way, and together with actual RF driver The RF simulator is implemented as an oai device and is always build when you build the oai eNB or the oai UE.
Using the `-w SIMU` option it is possible to just re-build the RF simulator device
Example: Example:
```bash ```bash
./build_oai --ue-nas-use-tun --UE --eNB -w SIMU ./build_oai --UE --eNB
Will compile UE
Will compile eNB
CMAKE_CMD=cmake ..
No local radio head and no transport protocol selected
No radio head has been selected (HW set to None)
No transport protocol has been selected (TP set to None)
RF HW set to None
Flags for Deadline scheduler: False
..................
.................
Compiling rfsimulator
Log file for compilation has been written to: /usr/local/oai/rfsimu_config/openairinterface5g/cmake_targets/log/rfsimulator.Rel14.txt
rfsimulator compiled
......................
......................
``` ```
It is also possible to build actual RF and use choose on each run:
```bash
./build_oai --ue-nas-use-tun --UE --eNB -w USRP --rfsimulator
```
Will build both the eNB (lte-softmodem) and the UE (lte-uesoftmodem)
We recommend to use the option --ue-nas-use-tun that is much simpler to use than the OAI kernel driver.
## Add the rfsimulator after initial build ## Add the rfsimulator after initial build
After any regular build, you can compile the driver After any regular build, you can compile the device, from the build directory
```bash ```bash
cd <the_compilation_dir_from_bouild_oai_script>/build cd <path to oai sources>/openairinterface5g/cmake_targets/lte_build_oai/build
make rfsimulator make rfsimulator
``` ```
Then, you can use it freely this is equivalent to using `-w SIMU` when running the `build_oai` script.
e
# Usage # Usage
Setting the env variable RFSIMULATOR enables the RF board simulator To use the RF simulator you add the `--rfsim` option to the command line. By default the RF simulator device will try to connect to host 127.0.0.1, port 4043, which is usually the behavior for the UE.
It should the set to "server" in the eNB or gNB The RF simulator is using the configuration module, its parameters are defined in a specific section called "rfsimulator"
| parameter | usage | default |
|:---------------------|:------------------------------------------------------------------------------------------------------------------|----:|
| serveraddr | ip address to connect to, or "enb" to behave as a tcp server | 127.0.0.1 |
| serverport | port number to connect to or to listen on (eNB, which behaved as a tcp server) | 4043 |
| options | list of comma separated run-time options, two are supported: `chanmod` to enable channel modeling and `saviq` to write transmitted iqs to a file | all options disabled |
| modelname | Name of the channel model to apply on received iqs when the `chanmod` option is enabled | AWGN |
| IQfile | Path to the file to be used to store iqs, when the `saviq`option is enabled | /tmp/rfsimulator.iqs |
Setting the env variable RFSIMULATOR can be used instead of using the serveraddr parameter, it is to preserve compatibility with previous version.
## 4G case ## 4G case
For the UE, it should be set to the IP address of the eNB For the UE, it should be set to the IP address of the eNB
...@@ -38,13 +59,14 @@ example: ...@@ -38,13 +59,14 @@ example:
```bash ```bash
sudo RFSIMULATOR=192.168.2.200 ./lte-uesoftmodem -C 2685000000 -r 50 sudo RFSIMULATOR=192.168.2.200 ./lte-uesoftmodem -C 2685000000 -r 50
``` ```
Except this, the UE and the eNB can be used as it the RF is real Except this, the UE and the eNB can be used as it the RF is real. noS1 mode can also be used with the RF simulator.
If you reach 'RA not active' on UE, be careful to generate a valid SIM If you reach 'RA not active' on UE, be careful to generate a valid SIM.
```bash ```bash
$OPENAIR_DIR/targets/bin/conf2uedata -c $OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf -o . $OPENAIR_DIR/targets/bin/conf2uedata -c $OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf -o .
``` ```
## 5G case ## 5G case
5G RF simulator will be aligned with 4G as the effort to merge 5G specifuc branches into develop is making progress.
After regular build, add the simulation driver After regular build, add the simulation driver
(don't use ./build_oai -w SIMU until we merge 4G and 5G branches) (don't use ./build_oai -w SIMU until we merge 4G and 5G branches)
```bash ```bash
...@@ -66,7 +88,7 @@ In UE, you can add "-d" to get the softscope ...@@ -66,7 +88,7 @@ In UE, you can add "-d" to get the softscope
You can store emitted I/Q samples: You can store emitted I/Q samples:
If you set the environment variable: saveIQfile to a file name If you set the option `saviq`
The simulator will write all IQ samples into this file The simulator will write all IQ samples into this file
Then, you can replay with the executable "replay_node" Then, you can replay with the executable "replay_node"
...@@ -83,11 +105,11 @@ If you have existing stored I/Q, you can adpat the tool "replay_node" to convert ...@@ -83,11 +105,11 @@ If you have existing stored I/Q, you can adpat the tool "replay_node" to convert
The format intend to be compatible with the OAI store/replay feature on USRP The format intend to be compatible with the OAI store/replay feature on USRP
### Channel simulation ### Channel simulation
The RF channel simulator is called. When the `chanmod` option is enabled, The RF channel simulator is called.
In current version all channel paramters are hard coded in the call to: In current version all channel paramters are set depending on the model name via a call to:
``` ```
new_channel_desc_scm(bridge->tx_num_channels,bridge->rx_num_channels, new_channel_desc_scm(bridge->tx_num_channels,bridge->rx_num_channels,
AWGN, <model name>,
bridge->sample_rate, bridge->sample_rate,
bridge->tx_bw, bridge->tx_bw,
0.0, // forgetting_factor 0.0, // forgetting_factor
...@@ -95,7 +117,7 @@ new_channel_desc_scm(bridge->tx_num_channels,bridge->rx_num_channels, ...@@ -95,7 +117,7 @@ new_channel_desc_scm(bridge->tx_num_channels,bridge->rx_num_channels,
0); // path_loss in dB 0); // path_loss in dB
``` ```
Only the input noise can be changed on command line with -s parameter. Only the input noise can be changed on command line with -s parameter.
With path loss = 0 set "-s 5" to see a little noise With path loss = 0 set "-s 5" to see a little noise. -s is a shortcut to `channelmod.s`. It is expected to enhance the channel modedelization flexibility via the addition of more parameters in the channelmod section.
#Caveacts # Caveacts
Still issues in power control: txgain, rxgain are not used Still issues in power control: txgain, rxgain are not used
/*
Author: Laurent THOMAS, Open Cells for Nokia
copyleft: OpenAirInterface Software Alliance and it's licence
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
#include <errno.h>
#include <common/utils/assertions.h>
#include <common/utils/LOG/log.h>
#include <common/config/config_userapi.h>
#include <openair1/SIMULATION/TOOLS/sim.h>
/*
Legacy study:
The parameters are:
gain&loss (decay, signal power, ...)
either a fixed gain in dB, a target power in dBm or ACG (automatic control gain) to a target average
=> don't redo the AGC, as it was used in UE case, that must have a AGC inside the UE
will be better to handle the "set_gain()" called by UE to apply it's gain (enable test of UE power loop)
lin_amp = pow(10.0,.05*txpwr_dBm)/sqrt(nb_tx_antennas);
a lot of operations in legacy, grouped in one simulation signal decay: txgain*decay*rxgain
multi_path (auto convolution, ISI, ...)
either we regenerate the channel (call again random_channel(desc,0)), or we keep it over subframes
legacy: we regenerate each sub frame in UL, and each frame only in DL
*/
void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_sig,
int rxAnt,
channel_desc_t *channelDesc,
int nbSamples,
uint64_t TS,
uint32_t CirSize
) {
// channelDesc->path_loss_dB should contain the total path gain
// so, in actual RF: tx gain + path loss + rx gain (+antenna gain, ...)
// UE and NB gain control to be added
// Fixme: not sure when it is "volts" so dB is 20*log10(...) or "power", so dB is 10*log10(...)
const double pathLossLinear = pow(10,channelDesc->path_loss_dB/20.0);
// Energy in one sample to calibrate input noise
//Fixme: modified the N0W computation, not understand the origin value
const double KT=1.38e-23*290; //Boltzman*temperature
// sampling rate is linked to acquisition band (the input pass band filter)
const double noise_figure_watt = KT*channelDesc->sampling_rate;
// Fixme: how to convert a noise in Watt into a 12 bits value out of the RF ADC ?
// the parameter "-s" is declared as SNR, but the input power is not well defined
// −132.24 dBm is a LTE subcarrier noise, that was used in origin code (15KHz BW thermal noise)
const double rxGain= 132.24 - channelmod_get_snr_dB();
// sqrt(4*noise_figure_watt) is the thermal noise factor (volts)
// fixme: the last constant is pure trial results to make decent noise
const double noise_per_sample = sqrt(4*noise_figure_watt) * pow(10,rxGain/20) *10;
// Fixme: we don't fill the offset length samples at begining ?
// anyway, in today code, channel_offset=0
const int dd = abs(channelDesc->channel_offset);
const int nbTx=channelDesc->nb_tx;
for (int i=0; i<((int)nbSamples-dd); i++) {
struct complex16 *out_ptr=after_channel_sig+dd+i;
struct complex rx_tmp= {0};
for (int txAnt=0; txAnt < nbTx; txAnt++) {
const struct complex *channelModel= channelDesc->ch[rxAnt+(txAnt*channelDesc->nb_rx)];
//const struct complex *channelModelEnd=channelModel+channelDesc->channel_length;
for (int l = 0; l<(int)channelDesc->channel_length; l++) {
// let's assume TS+i >= l
// fixme: the rfsimulator current structure is interleaved antennas
// this has been designed to not have to wait a full block transmission
// but it is not very usefull
// it would be better to split out each antenna in a separate flow
// that will allow to mix ru antennas freely
struct complex16 tx16=input_sig[((TS+i-l)*nbTx+txAnt)%CirSize];
rx_tmp.x += tx16.r * channelModel[l].x - tx16.i * channelModel[l].y;
rx_tmp.y += tx16.i * channelModel[l].x + tx16.r * channelModel[l].y;
} //l
}
out_ptr->r += round(rx_tmp.x*pathLossLinear + noise_per_sample*gaussdouble(0.0,1.0));
out_ptr->i += round(rx_tmp.y*pathLossLinear + noise_per_sample*gaussdouble(0.0,1.0));
out_ptr++;
}
if ( (TS*nbTx)%CirSize+nbSamples <= CirSize )
// Cast to a wrong type for compatibility !
LOG_D(HW,"Input power %f, output power: %f, channel path loss %f, noise coeff: %f \n",
10*log10((double)signal_energy((int32_t *)&input_sig[(TS*nbTx)%CirSize], nbSamples)),
10*log10((double)signal_energy((int32_t *)after_channel_sig, nbSamples)),
channelDesc->path_loss_dB,
10*log10(noise_per_sample));
}
This diff is collapsed.
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <common/utils/simple_executable.h> #include <common/utils/simple_executable.h>
volatile int oai_exit = 0;
void fullwrite(int fd, void *_buf, int count) { void fullwrite(int fd, void *_buf, int count) {
char *buf = _buf; char *buf = _buf;
...@@ -123,7 +124,7 @@ int main(int argc, char *argv[]) { ...@@ -123,7 +124,7 @@ int main(int argc, char *argv[]) {
setblocking(serviceSock, blocking); setblocking(serviceSock, blocking);
AssertFatal(read(fd,&header,sizeof(header)), ""); AssertFatal(read(fd,&header,sizeof(header)), "");
fullwrite(serviceSock, &header, sizeof(header)); fullwrite(serviceSock, &header, sizeof(header));
int dataSize=sizeof(sample_t)*header.size*header.nbAnt; int dataSize=sizeof(int32_t)*header.size*header.nbAnt;
if (dataSize>bufSize) { if (dataSize>bufSize) {
void * new_buff = realloc(buff, dataSize); void * new_buff = realloc(buff, dataSize);
......
...@@ -230,6 +230,7 @@ eNBs = ...@@ -230,6 +230,7 @@ eNBs =
pdsch_maxNumRepetitionCEmodeA_r13 = "r16"; #0 pdsch_maxNumRepetitionCEmodeA_r13 = "r16"; #0
pusch_repetitionLevelCEmodeA_r13 = "l1"; #0
#pdsch_maxNumRepetitionCEmodeB_r13 = "r384"; # NULL - 2 #pdsch_maxNumRepetitionCEmodeB_r13 = "r384"; # NULL - 2
pusch_maxNumRepetitionCEmodeA_r13 = "r8"; #0 pusch_maxNumRepetitionCEmodeA_r13 = "r8"; #0
......
...@@ -275,12 +275,24 @@ NETWORK_CONTROLLER : ...@@ -275,12 +275,24 @@ NETWORK_CONTROLLER :
THREAD_STRUCT = ( THREAD_STRUCT = (
{ {
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; parallel_config = "PARALLEL_SINGLE_THREAD";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE"; worker_config = "WORKER_ENABLE";
} }
); );
/*
#example config for rfsimulator
rfsimulator :
{
serveraddr = "enb";
serverport = "4043";
options = ("saviq");
modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs";
};
*/
log_config : log_config :
{ {
global_log_level ="info"; global_log_level ="info";
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
static softmodem_params_t softmodem_params; static softmodem_params_t softmodem_params;
char *parallel_config=NULL; char *parallel_config=NULL;
char *worker_config=NULL; char *worker_config=NULL;
double snr_dB=25;
uint64_t get_softmodem_optmask(void) { uint64_t get_softmodem_optmask(void) {
return softmodem_params.optmask; return softmodem_params.optmask;
......
...@@ -78,7 +78,6 @@ ...@@ -78,7 +78,6 @@
#define CONFIG_HLP_MSLOTS "Skip the missed slots/subframes \n" #define CONFIG_HLP_MSLOTS "Skip the missed slots/subframes \n"
#define CONFIG_HLP_ULMCS "Set the maximum uplink MCS\n" #define CONFIG_HLP_ULMCS "Set the maximum uplink MCS\n"
#define CONFIG_HLP_TDD "Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n" #define CONFIG_HLP_TDD "Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n"
#define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\n"
#define CONFIG_HLP_UE "Set the lte softmodem as a UE\n" #define CONFIG_HLP_UE "Set the lte softmodem as a UE\n"
#define CONFIG_HLP_TQFS "Apply three-quarter of sampling frequency, 23.04 Msps to reduce the data rate on USB/PCIe transfers (only valid for 20 MHz)\n" #define CONFIG_HLP_TQFS "Apply three-quarter of sampling frequency, 23.04 Msps to reduce the data rate on USB/PCIe transfers (only valid for 20 MHz)\n"
#define CONFIG_HLP_TPORT "tracer port\n" #define CONFIG_HLP_TPORT "tracer port\n"
...@@ -200,7 +199,6 @@ ...@@ -200,7 +199,6 @@
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \ {"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \ {"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \
{"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \ {"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \
{"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \
{"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&NUMEROLOGY, defintval:0, TYPE_INT, 0}, \ {"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&NUMEROLOGY, defintval:0, TYPE_INT, 0}, \
{"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)&parallel_config, defstrval:NULL, TYPE_STRING, 0}, \ {"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)&parallel_config, defstrval:NULL, TYPE_STRING, 0}, \
{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \ {"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \
...@@ -264,9 +262,9 @@ typedef struct { ...@@ -264,9 +262,9 @@ typedef struct {
int numerology; int numerology;
unsigned int start_msc; unsigned int start_msc;
uint32_t clock_source; uint32_t clock_source;
uint32_t timing_source; uint32_t timing_source;
int hw_timing_advance; int hw_timing_advance;
uint32_t send_dmrs_sync; uint32_t send_dmrs_sync;
} softmodem_params_t; } softmodem_params_t;
#define IS_SOFTMODEM_NOS1 ( get_softmodem_optmask() & SOFTMODEM_NOS1_BIT) #define IS_SOFTMODEM_NOS1 ( get_softmodem_optmask() & SOFTMODEM_NOS1_BIT)
...@@ -285,8 +283,6 @@ uint64_t get_pdcp_optmask(void); ...@@ -285,8 +283,6 @@ uint64_t get_pdcp_optmask(void);
extern pthread_cond_t sync_cond; extern pthread_cond_t sync_cond;
extern pthread_mutex_t sync_mutex; extern pthread_mutex_t sync_mutex;
extern int sync_var; extern int sync_var;
extern double snr_dB;
extern uint32_t downlink_frequency[MAX_NUM_CCs][4]; extern uint32_t downlink_frequency[MAX_NUM_CCs][4];
extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
...@@ -311,7 +307,7 @@ extern void stop_eNB(int); ...@@ -311,7 +307,7 @@ extern void stop_eNB(int);
extern void kill_eNB_proc(int inst); extern void kill_eNB_proc(int inst);
// In lte-ru.c // In lte-ru.c
extern void init_RU(char*,clock_source_t clock_source,clock_source_t time_source,int send_dmrssync); extern void init_RU(char *,clock_source_t clock_source,clock_source_t time_source,int send_dmrssync);
extern void stop_ru(RU_t *ru); extern void stop_ru(RU_t *ru);
extern void init_ru_vnf(void); extern void init_ru_vnf(void);
extern void init_RU_proc(RU_t *ru); extern void init_RU_proc(RU_t *ru);
...@@ -337,7 +333,7 @@ extern void kill_td_thread(PHY_VARS_eNB *); ...@@ -337,7 +333,7 @@ extern void kill_td_thread(PHY_VARS_eNB *);
extern void kill_te_thread(PHY_VARS_eNB *); extern void kill_te_thread(PHY_VARS_eNB *);
extern void RCConfig_sim(void); extern void RCConfig_sim(void);
extern void init_ocm(double,double); extern void init_ocm(void);
extern void init_ue_devices(PHY_VARS_UE *); extern void init_ue_devices(PHY_VARS_UE *);
PHY_VARS_UE *init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, PHY_VARS_UE *init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms,
......
...@@ -323,12 +323,10 @@ static void get_options(void) { ...@@ -323,12 +323,10 @@ static void get_options(void) {
int CC_id; int CC_id;
int tddflag; int tddflag;
char *loopfile=NULL; char *loopfile=NULL;
int dumpframe=0; int dumpframe=0;
int timingadv; int timingadv;
uint8_t nfapi_mode; uint8_t nfapi_mode;
int simL1flag ; int simL1flag ;
set_default_frame_parms(frame_parms); set_default_frame_parms(frame_parms);
CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP); CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP);
/* unknown parameters on command line will be checked in main /* unknown parameters on command line will be checked in main
...@@ -616,7 +614,7 @@ int main( int argc, char **argv ) { ...@@ -616,7 +614,7 @@ int main( int argc, char **argv ) {
if (config_mod == NULL) { if (config_mod == NULL) {
exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
} }
mode = normal_txrx; mode = normal_txrx;
memset(&openair0_cfg[0],0,sizeof(openair0_config_t)*MAX_CARDS); memset(&openair0_cfg[0],0,sizeof(openair0_config_t)*MAX_CARDS);
set_latency_target(); set_latency_target();
...@@ -811,7 +809,7 @@ int main( int argc, char **argv ) { ...@@ -811,7 +809,7 @@ int main( int argc, char **argv ) {
//p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX; //p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX;
if (IS_SOFTMODEM_SIML1 ) { if (IS_SOFTMODEM_SIML1 ) {
init_ocm(snr_dB,0); init_ocm();
PHY_vars_UE_g[0][0]->no_timing_correction = 1; PHY_vars_UE_g[0][0]->no_timing_correction = 1;
} }
......
This diff is collapsed.
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#include "PHY/defs_UE.h" #include "PHY/defs_UE.h"
#include "PHY/defs_eNB.h" #include "PHY/defs_eNB.h"
void init_ocm(double snr_dB,double sinr_dB); void init_ocm(void);
void update_ocm(double snr_dB,double sinr_dB); void update_ocm(double snr_dB,double sinr_dB);
...@@ -37,4 +37,4 @@ void update_ocm(double snr_dB,double sinr_dB); ...@@ -37,4 +37,4 @@ void update_ocm(double snr_dB,double sinr_dB);
void init_channel_vars(void); void init_channel_vars(void);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment