Merge remote-tracking branch 'origin/develop' into nr_pucch2
This commit is contained in:
@@ -4,7 +4,7 @@ For more details of the license, refer to [LICENSE](LICENSE) file in the same di
|
|||||||
|
|
||||||
However, the source code also contains third party software that is acknowledged here for reference.
|
However, the source code also contains third party software that is acknowledged here for reference.
|
||||||
|
|
||||||
## Credits for LFDS user space source code located in folder openair2/UTILS/LFDS/liblfds6.1.1/ ##
|
## Credits for LFDS user space source code located in folder openair2/UTILS/LFDS/ ##
|
||||||
|
|
||||||
See on [liblfds website](https://liblfds.org/) the license section.
|
See on [liblfds website](https://liblfds.org/) the license section.
|
||||||
|
|
||||||
|
|||||||
@@ -5,3 +5,5 @@ iperf_*.*
|
|||||||
phones_list.txt
|
phones_list.txt
|
||||||
modules_list.txt
|
modules_list.txt
|
||||||
test_results*.html
|
test_results*.html
|
||||||
|
pMain*
|
||||||
|
__pycache__
|
||||||
|
|||||||
@@ -142,13 +142,39 @@ pipeline {
|
|||||||
stage ("Load Images") {
|
stage ("Load Images") {
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
|
// Adding a tempo after booking leases
|
||||||
|
sh "sleep 10"
|
||||||
|
sh "ssh -t inria_oaici@faraday.inria.fr 'rleases --check'"
|
||||||
|
sh "ssh -t inria_oaici@faraday.inria.fr 'all-off'"
|
||||||
|
sh "sleep 10"
|
||||||
|
|
||||||
echo '\u2705 \u001B[32mLoad Image for Python Executor\u001B[0m'
|
echo '\u2705 \u001B[32mLoad Image for Python Executor\u001B[0m'
|
||||||
sh "ssh -t inria_oaici@faraday.inria.fr 'rload -i oai-ci-cd-u18-lowlatency-enb-ue ${r2labPythonExeIdx} > /dev/null 2>&1'"
|
try {
|
||||||
sh "ssh -t inria_oaici@faraday.inria.fr 'rwait --silent ${r2labPythonExeIdx}'"
|
//sh "ssh -t inria_oaici@faraday.inria.fr 'rload -i oai-ci-cd-u18-lowlatency-enb-ue ${r2labPythonExeIdx} > /dev/null 2>&1'"
|
||||||
|
sh "ssh -t inria_oaici@faraday.inria.fr 'rload -i oai-ci-cd-u18-lowlatency-enb-ue ${r2labPythonExeIdx}'"
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "Why is it wrong?"
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
//sh "ssh -t inria_oaici@faraday.inria.fr 'rwait --silent ${r2labPythonExeIdx}'"
|
||||||
|
sh "ssh -t inria_oaici@faraday.inria.fr 'rwait ${r2labPythonExeIdx}'"
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "Why is it wrong?"
|
||||||
|
}
|
||||||
|
|
||||||
echo '\u2705 \u001B[32mLoad Image for two (2) eNBs\u001B[0m'
|
echo '\u2705 \u001B[32mLoad Image for two (2) eNBs\u001B[0m'
|
||||||
sh "ssh -t inria_oaici@faraday.inria.fr 'rload -i oai-ci-cd-u18-lowlatency-enb-ue ${r2labENB0Idx},${r2labENB1Idx} > /dev/null 2>&1'"
|
try {
|
||||||
sh "ssh -t inria_oaici@faraday.inria.fr 'rwait --silent ${r2labENB0Idx},${r2labENB1Idx}'"
|
//sh "ssh -t inria_oaici@faraday.inria.fr 'rload -i oai-ci-cd-u18-lowlatency-enb-ue ${r2labENB0Idx},${r2labENB1Idx} > /dev/null 2>&1'"
|
||||||
|
sh "ssh -t inria_oaici@faraday.inria.fr 'rload -i oai-ci-cd-u18-lowlatency-enb-ue ${r2labENB0Idx},${r2labENB1Idx}"
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "Why is it wrong?"
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
//sh "ssh -t inria_oaici@faraday.inria.fr 'rwait --silent ${r2labENB0Idx},${r2labENB1Idx}'"
|
||||||
|
sh "ssh -t inria_oaici@faraday.inria.fr 'rwait ${r2labENB0Idx},${r2labENB1Idx}'"
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "Why is it wrong?"
|
||||||
|
}
|
||||||
sh "ssh -t inria_oaici@faraday.inria.fr 'uon ${r2labENB0Idx},${r2labENB1Idx}'"
|
sh "ssh -t inria_oaici@faraday.inria.fr 'uon ${r2labENB0Idx},${r2labENB1Idx}'"
|
||||||
sh "sleep 5"
|
sh "sleep 5"
|
||||||
sh "ssh -t inria_oaici@faraday.inria.fr 'uon ${r2labENB0Idx},${r2labENB1Idx}'"
|
sh "ssh -t inria_oaici@faraday.inria.fr 'uon ${r2labENB0Idx},${r2labENB1Idx}'"
|
||||||
|
|||||||
@@ -288,7 +288,7 @@ MCEs = (
|
|||||||
mnc_length = 2;
|
mnc_length = 2;
|
||||||
}
|
}
|
||||||
service_id=0;
|
service_id=0;
|
||||||
lcid=8; #this must be properly defined lcid:8+service:0 -> rab_id:8
|
lcid=5; #this must be properly defined lcid:8+service:0 -> rab_id:5
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
#/*
|
||||||
|
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||||
|
# * contributor license agreements. See the NOTICE file distributed with
|
||||||
|
# * this work for additional information regarding copyright ownership.
|
||||||
|
# * The OpenAirInterface Software Alliance licenses this file to You under
|
||||||
|
# * the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||||
|
# * except in compliance with the License.
|
||||||
|
# * You may obtain a copy of the License at
|
||||||
|
# *
|
||||||
|
# * http://www.openairinterface.org/?page_id=698
|
||||||
|
# *
|
||||||
|
# * Unless required by applicable law or agreed to in writing, software
|
||||||
|
# * distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# * See the License for the specific language governing permissions and
|
||||||
|
# * limitations under the License.
|
||||||
|
# *-------------------------------------------------------------------------------
|
||||||
|
# * For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||||
|
# * contact@openairinterface.org
|
||||||
|
# */
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
# Python for CI of OAI-eNB + COTS-UE
|
||||||
|
#
|
||||||
|
# Required Python Version
|
||||||
|
# Python 3.x
|
||||||
|
#
|
||||||
|
# Required Python Package
|
||||||
|
# pexpect
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
# Version
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
Version = '0.2'
|
||||||
|
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
# Constants
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
ALL_PROCESSES_OK = 0
|
||||||
|
ENB_PROCESS_FAILED = -1
|
||||||
|
ENB_PROCESS_OK = +1
|
||||||
|
ENB_PROCESS_SEG_FAULT = -11
|
||||||
|
ENB_PROCESS_ASSERTION = -12
|
||||||
|
ENB_PROCESS_REALTIME_ISSUE = -13
|
||||||
|
ENB_PROCESS_NOLOGFILE_TO_ANALYZE = -14
|
||||||
|
ENB_PROCESS_SLAVE_RRU_NOT_SYNCED = -15
|
||||||
|
HSS_PROCESS_FAILED = -2
|
||||||
|
HSS_PROCESS_OK = +2
|
||||||
|
MME_PROCESS_FAILED = -3
|
||||||
|
MME_PROCESS_OK = +3
|
||||||
|
SPGW_PROCESS_FAILED = -4
|
||||||
|
SPGW_PROCESS_OK = +4
|
||||||
|
UE_IP_ADDRESS_ISSUE = -5
|
||||||
|
OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE = -20
|
||||||
|
OAI_UE_PROCESS_COULD_NOT_SYNC = -21
|
||||||
|
OAI_UE_PROCESS_ASSERTION = -22
|
||||||
|
OAI_UE_PROCESS_FAILED = -23
|
||||||
|
OAI_UE_PROCESS_NO_TUNNEL_INTERFACE = -24
|
||||||
|
OAI_UE_PROCESS_SEG_FAULT = -25
|
||||||
|
OAI_UE_PROCESS_OK = +6
|
||||||
|
|
||||||
|
UE_STATUS_DETACHED = 0
|
||||||
|
UE_STATUS_DETACHING = 1
|
||||||
|
UE_STATUS_ATTACHING = 2
|
||||||
|
UE_STATUS_ATTACHED = 3
|
||||||
|
|
||||||
|
X2_HO_REQ_STATE__IDLE = 0
|
||||||
|
X2_HO_REQ_STATE__TARGET_RECEIVES_REQ = 1
|
||||||
|
X2_HO_REQ_STATE__TARGET_RRC_RECFG_COMPLETE = 2
|
||||||
|
X2_HO_REQ_STATE__TARGET_SENDS_SWITCH_REQ = 3
|
||||||
|
X2_HO_REQ_STATE__SOURCE_RECEIVES_REQ_ACK = 10
|
||||||
@@ -76,6 +76,11 @@ nullPointer:common/utils/T/local_tracer.c:243
|
|||||||
// first iteration of the loop
|
// first iteration of the loop
|
||||||
nullPointer:common/utils/T/tracer/multi.c:264
|
nullPointer:common/utils/T/tracer/multi.c:264
|
||||||
nullPointer:common/utils/T/tracer/multi.c:265
|
nullPointer:common/utils/T/tracer/multi.c:265
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// this file is used for testing the RLC V2 implementation, this error is
|
||||||
|
// not a problem, the programmer has to know what she does when writing
|
||||||
|
// the tests
|
||||||
|
arrayIndexOutOfBounds:openair2/LAYER2/rlc_v2/tests/test.c:401
|
||||||
//
|
//
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -0,0 +1,397 @@
|
|||||||
|
#/*
|
||||||
|
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||||
|
# * contributor license agreements. See the NOTICE file distributed with
|
||||||
|
# * this work for additional information regarding copyright ownership.
|
||||||
|
# * The OpenAirInterface Software Alliance licenses this file to You under
|
||||||
|
# * the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||||
|
# * except in compliance with the License.
|
||||||
|
# * You may obtain a copy of the License at
|
||||||
|
# *
|
||||||
|
# * http://www.openairinterface.org/?page_id=698
|
||||||
|
# *
|
||||||
|
# * Unless required by applicable law or agreed to in writing, software
|
||||||
|
# * distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# * See the License for the specific language governing permissions and
|
||||||
|
# * limitations under the License.
|
||||||
|
# *-------------------------------------------------------------------------------
|
||||||
|
# * For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||||
|
# * contact@openairinterface.org
|
||||||
|
# */
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
# Python for CI of OAI-eNB + COTS-UE
|
||||||
|
#
|
||||||
|
# Required Python Version
|
||||||
|
# Python 3.x
|
||||||
|
#
|
||||||
|
# Required Python Package
|
||||||
|
# pexpect
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
# Import
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
import sys # arg
|
||||||
|
import re # reg
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import signal
|
||||||
|
|
||||||
|
from multiprocessing import Process, Lock, SimpleQueue
|
||||||
|
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
# OAI Testing modules
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
import sshconnection as SSH
|
||||||
|
import helpreadme as HELP
|
||||||
|
import constants as CONST
|
||||||
|
import html
|
||||||
|
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
# Class Declaration
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
class EPCManagement():
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
|
||||||
|
self.IPAddress = ''
|
||||||
|
self.UserName = ''
|
||||||
|
self.Password = ''
|
||||||
|
self.SourceCodePath = ''
|
||||||
|
self.Type = ''
|
||||||
|
self.PcapFileName = ''
|
||||||
|
self.htmlObj = None
|
||||||
|
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
# Setter and Getters on Public Members
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
|
||||||
|
def SetIPAddress(self, ipaddress):
|
||||||
|
self.IPAddress = ipaddress
|
||||||
|
def GetIPAddress(self):
|
||||||
|
return self.IPAddress
|
||||||
|
def SetUserName(self, username):
|
||||||
|
self.UserName = username
|
||||||
|
def GetUserName(self):
|
||||||
|
return self.UserName
|
||||||
|
def SetPassword(self, password):
|
||||||
|
self.Password = password
|
||||||
|
def GetPassword(self):
|
||||||
|
return self.Password
|
||||||
|
def SetSourceCodePath(self, sourcecodepath):
|
||||||
|
self.SourceCodePath = sourcecodepath
|
||||||
|
def GetSourceCodePath(self):
|
||||||
|
return self.SourceCodePath
|
||||||
|
def SetType(self, kind):
|
||||||
|
self.Type = kind
|
||||||
|
def GetType(self):
|
||||||
|
return self.Type
|
||||||
|
def SetHtmlObj(self, obj):
|
||||||
|
self.htmlObj = obj
|
||||||
|
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
# EPC management functions
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
|
||||||
|
def InitializeHSS(self):
|
||||||
|
if self.IPAddress == '' or self.UserName == '' or self.Password == '' or self.SourceCodePath == '' or self.Type == '':
|
||||||
|
HELP.GenericHelp(CONST.Version)
|
||||||
|
HELP.EPCSrvHelp(self.IPAddress, self.UserName, self.Password, self.SourceCodePath, self.Type)
|
||||||
|
sys.exit('Insufficient EPC Parameters')
|
||||||
|
mySSH = SSH.SSHConnection()
|
||||||
|
mySSH.open(self.IPAddress, self.UserName, self.Password)
|
||||||
|
if re.match('OAI-Rel14-CUPS', self.Type, re.IGNORECASE):
|
||||||
|
logging.debug('Using the OAI EPC Release 14 Cassandra-based HSS')
|
||||||
|
mySSH.command('cd ' + self.SourceCodePath + '/scripts', '\$', 5)
|
||||||
|
logging.debug('\u001B[1m Launching tshark on all interfaces \u001B[0m')
|
||||||
|
self.PcapFileName = 'epc_' + self.testCase_id + '.pcap'
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S rm -f ' + self.PcapFileName, '\$', 5)
|
||||||
|
mySSH.command('echo $USER; nohup sudo tshark -f "tcp port not 22 and port not 53" -i any -w ' + self.SourceCodePath + '/scripts/' + self.PcapFileName + ' > /tmp/tshark.log 2>&1 &', self.UserName, 5)
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S mkdir -p logs', '\$', 5)
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S rm -f hss_' + self.testCase_id + '.log logs/hss*.*', '\$', 5)
|
||||||
|
mySSH.command('echo "oai_hss -j /usr/local/etc/oai/hss_rel14.json" > ./my-hss.sh', '\$', 5)
|
||||||
|
mySSH.command('chmod 755 ./my-hss.sh', '\$', 5)
|
||||||
|
mySSH.command('sudo daemon --unsafe --name=hss_daemon --chdir=' + self.SourceCodePath + '/scripts -o ' + self.SourceCodePath + '/scripts/hss_' + self.testCase_id + '.log ./my-hss.sh', '\$', 5)
|
||||||
|
elif re.match('OAI', self.Type, re.IGNORECASE):
|
||||||
|
logging.debug('Using the OAI EPC HSS')
|
||||||
|
mySSH.command('cd ' + self.SourceCodePath, '\$', 5)
|
||||||
|
mySSH.command('source oaienv', '\$', 5)
|
||||||
|
mySSH.command('cd scripts', '\$', 5)
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S ./run_hss 2>&1 | stdbuf -o0 awk \'{ print strftime("[%Y/%m/%d %H:%M:%S] ",systime()) $0 }\' | stdbuf -o0 tee -a hss_' + self.testCase_id + '.log &', 'Core state: 2 -> 3', 35)
|
||||||
|
elif re.match('ltebox', self.Type, re.IGNORECASE):
|
||||||
|
logging.debug('Using the ltebox simulated HSS')
|
||||||
|
mySSH.command('if [ -d ' + self.SourceCodePath + '/scripts ]; then echo ' + self.Password + ' | sudo -S rm -Rf ' + self.SourceCodePath + '/scripts ; fi', '\$', 5)
|
||||||
|
mySSH.command('mkdir -p ' + self.SourceCodePath + '/scripts', '\$', 5)
|
||||||
|
mySSH.command('cd /opt/hss_sim0609', '\$', 5)
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S rm -f hss.log', '\$', 5)
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S echo "Starting sudo session" && sudo su -c "screen -dm -S simulated_hss ./starthss"', '\$', 5)
|
||||||
|
else:
|
||||||
|
logging.error('This option should not occur!')
|
||||||
|
mySSH.close()
|
||||||
|
if self.htmlObj is not None:
|
||||||
|
self.htmlObj.CreateHtmlTestRow(self.Type, 'OK', CONST.ALL_PROCESSES_OK)
|
||||||
|
|
||||||
|
def InitializeMME(self):
|
||||||
|
if self.IPAddress == '' or self.UserName == '' or self.Password == '' or self.SourceCodePath == '' or self.Type == '':
|
||||||
|
HELP.GenericHelp(CONST.Version)
|
||||||
|
HELP.EPCSrvHelp(self.IPAddress, self.UserName, self.Password, self.SourceCodePath, self.Type)
|
||||||
|
sys.exit('Insufficient EPC Parameters')
|
||||||
|
mySSH = SSH.SSHConnection()
|
||||||
|
mySSH.open(self.IPAddress, self.UserName, self.Password)
|
||||||
|
if re.match('OAI-Rel14-CUPS', self.Type, re.IGNORECASE):
|
||||||
|
logging.debug('Using the OAI EPC Release 14 MME')
|
||||||
|
mySSH.command('cd ' + self.SourceCodePath + '/scripts', '\$', 5)
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S rm -f mme_' + self.testCase_id + '.log', '\$', 5)
|
||||||
|
mySSH.command('echo "./run_mme --config-file /usr/local/etc/oai/mme.conf --set-virt-if" > ./my-mme.sh', '\$', 5)
|
||||||
|
mySSH.command('chmod 755 ./my-mme.sh', '\$', 5)
|
||||||
|
mySSH.command('sudo daemon --unsafe --name=mme_daemon --chdir=' + self.SourceCodePath + '/scripts -o ' + self.SourceCodePath + '/scripts/mme_' + self.testCase_id + '.log ./my-mme.sh', '\$', 5)
|
||||||
|
elif re.match('OAI', self.Type, re.IGNORECASE):
|
||||||
|
mySSH.command('cd ' + self.SourceCodePath, '\$', 5)
|
||||||
|
mySSH.command('source oaienv', '\$', 5)
|
||||||
|
mySSH.command('cd scripts', '\$', 5)
|
||||||
|
mySSH.command('stdbuf -o0 hostname', '\$', 5)
|
||||||
|
result = re.search('hostname\\\\r\\\\n(?P<host_name>[a-zA-Z0-9\-\_]+)\\\\r\\\\n', mySSH.getBefore())
|
||||||
|
if result is None:
|
||||||
|
logging.debug('\u001B[1;37;41m Hostname Not Found! \u001B[0m')
|
||||||
|
sys.exit(1)
|
||||||
|
host_name = result.group('host_name')
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S ./run_mme 2>&1 | stdbuf -o0 tee -a mme_' + self.testCase_id + '.log &', 'MME app initialization complete', 100)
|
||||||
|
elif re.match('ltebox', self.Type, re.IGNORECASE):
|
||||||
|
mySSH.command('cd /opt/ltebox/tools', '\$', 5)
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S ./start_mme', '\$', 5)
|
||||||
|
else:
|
||||||
|
logging.error('This option should not occur!')
|
||||||
|
mySSH.close()
|
||||||
|
if self.htmlObj is not None:
|
||||||
|
self.htmlObj.CreateHtmlTestRow(self.Type, 'OK', CONST.ALL_PROCESSES_OK)
|
||||||
|
|
||||||
|
def InitializeSPGW(self):
|
||||||
|
if self.IPAddress == '' or self.UserName == '' or self.Password == '' or self.SourceCodePath == '' or self.Type == '':
|
||||||
|
HELP.GenericHelp(CONST.Version)
|
||||||
|
HELP.EPCSrvHelp(self.IPAddress, self.UserName, self.Password, self.SourceCodePath, self.Type)
|
||||||
|
sys.exit('Insufficient EPC Parameters')
|
||||||
|
mySSH = SSH.SSHConnection()
|
||||||
|
mySSH.open(self.IPAddress, self.UserName, self.Password)
|
||||||
|
if re.match('OAI-Rel14-CUPS', self.Type, re.IGNORECASE):
|
||||||
|
logging.debug('Using the OAI EPC Release 14 SPGW-CUPS')
|
||||||
|
mySSH.command('cd ' + self.SourceCodePath + '/scripts', '\$', 5)
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S rm -f spgwc_' + self.testCase_id + '.log spgwu_' + self.testCase_id + '.log', '\$', 5)
|
||||||
|
mySSH.command('echo "spgwc -c /usr/local/etc/oai/spgw_c.conf" > ./my-spgwc.sh', '\$', 5)
|
||||||
|
mySSH.command('chmod 755 ./my-spgwc.sh', '\$', 5)
|
||||||
|
mySSH.command('sudo daemon --unsafe --name=spgwc_daemon --chdir=' + self.SourceCodePath + '/scripts -o ' + self.SourceCodePath + '/scripts/spgwc_' + self.testCase_id + '.log ./my-spgwc.sh', '\$', 5)
|
||||||
|
time.sleep(5)
|
||||||
|
mySSH.command('echo "spgwu -c /usr/local/etc/oai/spgw_u.conf" > ./my-spgwu.sh', '\$', 5)
|
||||||
|
mySSH.command('chmod 755 ./my-spgwu.sh', '\$', 5)
|
||||||
|
mySSH.command('sudo daemon --unsafe --name=spgwu_daemon --chdir=' + self.SourceCodePath + '/scripts -o ' + self.SourceCodePath + '/scripts/spgwu_' + self.testCase_id + '.log ./my-spgwu.sh', '\$', 5)
|
||||||
|
elif re.match('OAI', self.Type, re.IGNORECASE):
|
||||||
|
mySSH.command('cd ' + self.SourceCodePath, '\$', 5)
|
||||||
|
mySSH.command('source oaienv', '\$', 5)
|
||||||
|
mySSH.command('cd scripts', '\$', 5)
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S ./run_spgw 2>&1 | stdbuf -o0 tee -a spgw_' + self.testCase_id + '.log &', 'Initializing SPGW-APP task interface: DONE', 30)
|
||||||
|
elif re.match('ltebox', self.Type, re.IGNORECASE):
|
||||||
|
mySSH.command('cd /opt/ltebox/tools', '\$', 5)
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S ./start_xGw', '\$', 5)
|
||||||
|
else:
|
||||||
|
logging.error('This option should not occur!')
|
||||||
|
mySSH.close()
|
||||||
|
if self.htmlObj is not None:
|
||||||
|
self.htmlObj.CreateHtmlTestRow(self.Type, 'OK', CONST.ALL_PROCESSES_OK)
|
||||||
|
|
||||||
|
def CheckHSSProcess(self, status_queue):
|
||||||
|
try:
|
||||||
|
mySSH = SSH.SSHConnection()
|
||||||
|
mySSH.open(self.IPAddress, self.UserName, self.Password)
|
||||||
|
mySSH.command('stdbuf -o0 ps -aux | grep --color=never hss | grep -v grep', '\$', 5)
|
||||||
|
if re.match('OAI-Rel14-CUPS', self.Type, re.IGNORECASE):
|
||||||
|
result = re.search('oai_hss -j', mySSH.getBefore())
|
||||||
|
elif re.match('OAI', self.Type, re.IGNORECASE):
|
||||||
|
result = re.search('\/bin\/bash .\/run_', mySSH.getBefore())
|
||||||
|
elif re.match('ltebox', self.Type, re.IGNORECASE):
|
||||||
|
result = re.search('hss_sim s6as diam_hss', mySSH.getBefore())
|
||||||
|
else:
|
||||||
|
logging.error('This should not happen!')
|
||||||
|
if result is None:
|
||||||
|
logging.debug('\u001B[1;37;41m HSS Process Not Found! \u001B[0m')
|
||||||
|
status_queue.put(CONST.HSS_PROCESS_FAILED)
|
||||||
|
else:
|
||||||
|
status_queue.put(CONST.HSS_PROCESS_OK)
|
||||||
|
mySSH.close()
|
||||||
|
except:
|
||||||
|
os.kill(os.getppid(),signal.SIGUSR1)
|
||||||
|
|
||||||
|
def CheckMMEProcess(self, status_queue):
|
||||||
|
try:
|
||||||
|
mySSH = SSH.SSHConnection()
|
||||||
|
mySSH.open(self.IPAddress, self.UserName, self.Password)
|
||||||
|
mySSH.command('stdbuf -o0 ps -aux | grep --color=never mme | grep -v grep', '\$', 5)
|
||||||
|
if re.match('OAI-Rel14-CUPS', self.Type, re.IGNORECASE):
|
||||||
|
result = re.search('mme -c', mySSH.getBefore())
|
||||||
|
elif re.match('OAI', self.Type, re.IGNORECASE):
|
||||||
|
result = re.search('\/bin\/bash .\/run_', mySSH.getBefore())
|
||||||
|
elif re.match('ltebox', self.Type, re.IGNORECASE):
|
||||||
|
result = re.search('mme', mySSH.getBefore())
|
||||||
|
else:
|
||||||
|
logging.error('This should not happen!')
|
||||||
|
if result is None:
|
||||||
|
logging.debug('\u001B[1;37;41m MME Process Not Found! \u001B[0m')
|
||||||
|
status_queue.put(CONST.MME_PROCESS_FAILED)
|
||||||
|
else:
|
||||||
|
status_queue.put(CONST.MME_PROCESS_OK)
|
||||||
|
mySSH.close()
|
||||||
|
except:
|
||||||
|
os.kill(os.getppid(),signal.SIGUSR1)
|
||||||
|
|
||||||
|
def CheckSPGWProcess(self, status_queue):
|
||||||
|
try:
|
||||||
|
mySSH = SSH.SSHConnection()
|
||||||
|
mySSH.open(self.IPAddress, self.UserName, self.Password)
|
||||||
|
if re.match('OAI-Rel14-CUPS', self.Type, re.IGNORECASE):
|
||||||
|
mySSH.command('stdbuf -o0 ps -aux | grep --color=never spgw | grep -v grep', '\$', 5)
|
||||||
|
result = re.search('spgwu -c ', mySSH.getBefore())
|
||||||
|
elif re.match('OAI', self.Type, re.IGNORECASE):
|
||||||
|
mySSH.command('stdbuf -o0 ps -aux | grep --color=never spgw | grep -v grep', '\$', 5)
|
||||||
|
result = re.search('\/bin\/bash .\/run_', mySSH.getBefore())
|
||||||
|
elif re.match('ltebox', self.Type, re.IGNORECASE):
|
||||||
|
mySSH.command('stdbuf -o0 ps -aux | grep --color=never xGw | grep -v grep', '\$', 5)
|
||||||
|
result = re.search('xGw', mySSH.getBefore())
|
||||||
|
else:
|
||||||
|
logging.error('This should not happen!')
|
||||||
|
if result is None:
|
||||||
|
logging.debug('\u001B[1;37;41m SPGW Process Not Found! \u001B[0m')
|
||||||
|
status_queue.put(CONST.SPGW_PROCESS_FAILED)
|
||||||
|
else:
|
||||||
|
status_queue.put(CONST.SPGW_PROCESS_OK)
|
||||||
|
mySSH.close()
|
||||||
|
except:
|
||||||
|
os.kill(os.getppid(),signal.SIGUSR1)
|
||||||
|
|
||||||
|
def TerminateHSS(self):
|
||||||
|
mySSH = SSH.SSHConnection()
|
||||||
|
mySSH.open(self.IPAddress, self.UserName, self.Password)
|
||||||
|
if re.match('OAI-Rel14-CUPS', self.Type, re.IGNORECASE):
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S killall --signal SIGINT oai_hss || true', '\$', 5)
|
||||||
|
time.sleep(2)
|
||||||
|
mySSH.command('stdbuf -o0 ps -aux | grep hss | grep -v grep', '\$', 5)
|
||||||
|
result = re.search('oai_hss -j', mySSH.getBefore())
|
||||||
|
if result is not None:
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S killall --signal SIGKILL oai_hss || true', '\$', 5)
|
||||||
|
mySSH.command('rm -f ' + self.SourceCodePath + '/scripts/my-hss.sh', '\$', 5)
|
||||||
|
elif re.match('OAI', self.Type, re.IGNORECASE):
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S killall --signal SIGINT run_hss oai_hss || true', '\$', 5)
|
||||||
|
time.sleep(2)
|
||||||
|
mySSH.command('stdbuf -o0 ps -aux | grep hss | grep -v grep', '\$', 5)
|
||||||
|
result = re.search('\/bin\/bash .\/run_', mySSH.getBefore())
|
||||||
|
if result is not None:
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S killall --signal SIGKILL run_hss oai_hss || true', '\$', 5)
|
||||||
|
elif re.match('ltebox', self.Type, re.IGNORECASE):
|
||||||
|
mySSH.command('cd ' + self.SourceCodePath, '\$', 5)
|
||||||
|
mySSH.command('cd scripts', '\$', 5)
|
||||||
|
time.sleep(1)
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S killall --signal SIGKILL hss_sim', '\$', 5)
|
||||||
|
else:
|
||||||
|
logging.error('This should not happen!')
|
||||||
|
mySSH.close()
|
||||||
|
if self.htmlObj is not None:
|
||||||
|
self.htmlObj.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
|
||||||
|
|
||||||
|
def TerminateMME(self):
|
||||||
|
mySSH = SSH.SSHConnection()
|
||||||
|
mySSH.open(self.IPAddress, self.UserName, self.Password)
|
||||||
|
if re.match('OAI', self.Type, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.Type, re.IGNORECASE):
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S killall --signal SIGINT run_mme mme || true', '\$', 5)
|
||||||
|
time.sleep(2)
|
||||||
|
mySSH.command('stdbuf -o0 ps -aux | grep mme | grep -v grep', '\$', 5)
|
||||||
|
result = re.search('mme -c', mySSH.getBefore())
|
||||||
|
if result is not None:
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S killall --signal SIGKILL run_mme mme || true', '\$', 5)
|
||||||
|
mySSH.command('rm -f ' + self.SourceCodePath + '/scripts/my-mme.sh', '\$', 5)
|
||||||
|
elif re.match('ltebox', self.Type, re.IGNORECASE):
|
||||||
|
mySSH.command('cd /opt/ltebox/tools', '\$', 5)
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S ./stop_mme', '\$', 5)
|
||||||
|
else:
|
||||||
|
logging.error('This should not happen!')
|
||||||
|
mySSH.close()
|
||||||
|
if self.htmlObj is not None:
|
||||||
|
self.htmlObj.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
|
||||||
|
|
||||||
|
def TerminateSPGW(self):
|
||||||
|
mySSH = SSH.SSHConnection()
|
||||||
|
mySSH.open(self.IPAddress, self.UserName, self.Password)
|
||||||
|
if re.match('OAI-Rel14-CUPS', self.Type, re.IGNORECASE):
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S killall --signal SIGINT spgwc spgwu || true', '\$', 5)
|
||||||
|
time.sleep(2)
|
||||||
|
mySSH.command('stdbuf -o0 ps -aux | grep spgw | grep -v grep', '\$', 5)
|
||||||
|
result = re.search('spgwc -c |spgwu -c ', mySSH.getBefore())
|
||||||
|
if result is not None:
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S killall --signal SIGKILL spgwc spgwu || true', '\$', 5)
|
||||||
|
mySSH.command('rm -f ' + self.SourceCodePath + '/scripts/my-spgw*.sh', '\$', 5)
|
||||||
|
mySSH.command('stdbuf -o0 ps -aux | grep tshark | grep -v grep', '\$', 5)
|
||||||
|
result = re.search('-w ', mySSH.getBefore())
|
||||||
|
if result is not None:
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S killall --signal SIGINT tshark || true', '\$', 5)
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S chmod 666 ' + self.SourceCodePath + '/scripts/*.pcap', '\$', 5)
|
||||||
|
elif re.match('OAI', self.Type, re.IGNORECASE):
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S killall --signal SIGINT run_spgw spgw || true', '\$', 5)
|
||||||
|
time.sleep(2)
|
||||||
|
mySSH.command('stdbuf -o0 ps -aux | grep spgw | grep -v grep', '\$', 5)
|
||||||
|
result = re.search('\/bin\/bash .\/run_', mySSH.getBefore())
|
||||||
|
if result is not None:
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S killall --signal SIGKILL run_spgw spgw || true', '\$', 5)
|
||||||
|
elif re.match('ltebox', self.Type, re.IGNORECASE):
|
||||||
|
mySSH.command('cd /opt/ltebox/tools', '\$', 5)
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S ./stop_xGw', '\$', 5)
|
||||||
|
else:
|
||||||
|
logging.error('This should not happen!')
|
||||||
|
mySSH.close()
|
||||||
|
if self.htmlObj is not None:
|
||||||
|
self.htmlObj.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
|
||||||
|
|
||||||
|
def LogCollectHSS(self):
|
||||||
|
mySSH = SSH.SSHConnection()
|
||||||
|
mySSH.open(self.IPAddress, self.UserName, self.Password)
|
||||||
|
mySSH.command('cd ' + self.SourceCodePath + '/scripts', '\$', 5)
|
||||||
|
mySSH.command('rm -f hss.log.zip', '\$', 5)
|
||||||
|
if re.match('OAI', self.Type, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.Type, re.IGNORECASE):
|
||||||
|
mySSH.command('zip hss.log.zip hss*.log', '\$', 60)
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S rm hss*.log', '\$', 5)
|
||||||
|
if re.match('OAI-Rel14-CUPS', self.Type, re.IGNORECASE):
|
||||||
|
mySSH.command('zip hss.log.zip logs/hss*.* *.pcap', '\$', 60)
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S rm -f logs/hss*.* *.pcap', '\$', 5)
|
||||||
|
elif re.match('ltebox', self.Type, re.IGNORECASE):
|
||||||
|
mySSH.command('cp /opt/hss_sim0609/hss.log .', '\$', 60)
|
||||||
|
mySSH.command('zip hss.log.zip hss.log', '\$', 60)
|
||||||
|
else:
|
||||||
|
logging.error('This option should not occur!')
|
||||||
|
mySSH.close()
|
||||||
|
|
||||||
|
def LogCollectMME(self):
|
||||||
|
mySSH = SSH.SSHConnection()
|
||||||
|
mySSH.open(self.IPAddress, self.UserName, self.Password)
|
||||||
|
mySSH.command('cd ' + self.SourceCodePath + '/scripts', '\$', 5)
|
||||||
|
mySSH.command('rm -f mme.log.zip', '\$', 5)
|
||||||
|
if re.match('OAI', self.Type, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.Type, re.IGNORECASE):
|
||||||
|
mySSH.command('zip mme.log.zip mme*.log', '\$', 60)
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S rm mme*.log', '\$', 5)
|
||||||
|
elif re.match('ltebox', self.Type, re.IGNORECASE):
|
||||||
|
mySSH.command('cp /opt/ltebox/var/log/*Log.0 .', '\$', 5)
|
||||||
|
mySSH.command('zip mme.log.zip mmeLog.0 s1apcLog.0 s1apsLog.0 s11cLog.0 libLog.0 s1apCodecLog.0', '\$', 60)
|
||||||
|
else:
|
||||||
|
logging.error('This option should not occur!')
|
||||||
|
mySSH.close()
|
||||||
|
|
||||||
|
def LogCollectSPGW(self):
|
||||||
|
mySSH = SSH.SSHConnection()
|
||||||
|
mySSH.open(self.IPAddress, self.UserName, self.Password)
|
||||||
|
mySSH.command('cd ' + self.SourceCodePath + '/scripts', '\$', 5)
|
||||||
|
mySSH.command('rm -f spgw.log.zip', '\$', 5)
|
||||||
|
if re.match('OAI', self.Type, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.Type, re.IGNORECASE):
|
||||||
|
mySSH.command('zip spgw.log.zip spgw*.log', '\$', 60)
|
||||||
|
mySSH.command('echo ' + self.Password + ' | sudo -S rm spgw*.log', '\$', 5)
|
||||||
|
elif re.match('ltebox', self.Type, re.IGNORECASE):
|
||||||
|
mySSH.command('cp /opt/ltebox/var/log/xGwLog.0 .', '\$', 5)
|
||||||
|
mySSH.command('zip spgw.log.zip xGwLog.0', '\$', 60)
|
||||||
|
else:
|
||||||
|
logging.error('This option should not occur!')
|
||||||
|
mySSH.close()
|
||||||
|
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
#/*
|
||||||
|
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||||
|
# * contributor license agreements. See the NOTICE file distributed with
|
||||||
|
# * this work for additional information regarding copyright ownership.
|
||||||
|
# * The OpenAirInterface Software Alliance licenses this file to You under
|
||||||
|
# * the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||||
|
# * except in compliance with the License.
|
||||||
|
# * You may obtain a copy of the License at
|
||||||
|
# *
|
||||||
|
# * http://www.openairinterface.org/?page_id=698
|
||||||
|
# *
|
||||||
|
# * Unless required by applicable law or agreed to in writing, software
|
||||||
|
# * distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# * See the License for the specific language governing permissions and
|
||||||
|
# * limitations under the License.
|
||||||
|
# *-------------------------------------------------------------------------------
|
||||||
|
# * For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||||
|
# * contact@openairinterface.org
|
||||||
|
# */
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
# Python for CI of OAI-eNB + COTS-UE
|
||||||
|
#
|
||||||
|
# Required Python Version
|
||||||
|
# Python 3.x
|
||||||
|
#
|
||||||
|
# Required Python Package
|
||||||
|
# pexpect
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
# Functions Declaration
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
|
||||||
|
def GenericHelp(vers):
|
||||||
|
print('----------------------------------------------------------------------------------------------------------------------')
|
||||||
|
print('main.py Ver: ' + vers)
|
||||||
|
print('----------------------------------------------------------------------------------------------------------------------')
|
||||||
|
print('python main.py [options]')
|
||||||
|
print(' --help Show this help.')
|
||||||
|
print(' --mode=[Mode]')
|
||||||
|
print(' TesteNB')
|
||||||
|
print(' InitiateHtml, FinalizeHtml')
|
||||||
|
print(' TerminateeNB, TerminateUE, TerminateHSS, TerminateMME, TerminateSPGW')
|
||||||
|
print(' LogCollectBuild, LogCollecteNB, LogCollectHSS, LogCollectMME, LogCollectSPGW, LogCollectPing, LogCollectIperf')
|
||||||
|
|
||||||
|
def GitSrvHelp(repository,branch,commit,mergeallow,targetbranch):
|
||||||
|
print(' --ranRepository=[OAI RAN Repository URL] -- ' + repository)
|
||||||
|
print(' --ranBranch=[OAI RAN Repository Branch] -- ' + branch)
|
||||||
|
print(' --ranCommitID=[OAI RAN Repository Commit SHA-1] -- ' + commit)
|
||||||
|
print(' --ranAllowMerge=[Allow Merge Request (with target branch) (true or false)] -- ' + mergeallow)
|
||||||
|
print(' --ranTargetBranch=[Target Branch in case of a Merge Request] -- ' + targetbranch)
|
||||||
|
|
||||||
|
def eNBSrvHelp(ipaddr, username, password, sourcepath):
|
||||||
|
print(' --eNBIPAddress=[eNB\'s IP Address] -- ' + ipaddr)
|
||||||
|
print(' --eNBUserName=[eNB\'s Login User Name] -- ' + username)
|
||||||
|
print(' --eNBPassword=[eNB\'s Login Password] -- ' + password)
|
||||||
|
print(' --eNBSourceCodePath=[eNB\'s Source Code Path] -- ' + sourcepath)
|
||||||
|
|
||||||
|
def OAIUESrvHelp(ipaddr, username, password, sourcepath):
|
||||||
|
print(' --UEIPAddress=[UE\'s IP Address] -- ' + ipaddr)
|
||||||
|
print(' --UEUserName=[UE\'s Login User Name] -- ' + username)
|
||||||
|
print(' --UEPassword=[UE\'s Login Password] -- ' + password)
|
||||||
|
print(' --UESourceCodePath=[UE\'s Source Code Path] -- ' + sourcepath)
|
||||||
|
|
||||||
|
def EPCSrvHelp(ipaddr, username, password, sourcepath, epctype):
|
||||||
|
print(' --EPCIPAddress=[EPC\'s IP Address] -- ' + ipaddr)
|
||||||
|
print(' --EPCUserName=[EPC\'s Login User Name] -- ' + username)
|
||||||
|
print(' --EPCPassword=[EPC\'s Login Password] -- ' + password)
|
||||||
|
print(' --EPCSourceCodePath=[EPC\'s Source Code Path] -- ' + sourcepath)
|
||||||
|
print(' --EPCType=[EPC\'s Type: OAI or ltebox or OAI-Rel14-CUPS] -- ' + epctype)
|
||||||
|
|
||||||
|
def ADBSrvHelp(ipaddr, username, password):
|
||||||
|
print(' --ADBIPAddress=[ADB\'s IP Address] -- ' + ipaddr)
|
||||||
|
print(' --ADBUserName=[ADB\'s Login User Name] -- ' + username)
|
||||||
|
print(' --ADBPassword=[ADB\'s Login Password] -- ' + password)
|
||||||
|
|
||||||
|
def XmlHelp(filename):
|
||||||
|
print(' --XMLTestFile=[XML Test File to be run] -- ' + filename)
|
||||||
|
print(' Note: multiple xml files can be specified (--XMLFile=File1 ... --XMLTestFile=FileN) when HTML headers are created ("InitiateHtml" mode)')
|
||||||
|
|
||||||
@@ -0,0 +1,476 @@
|
|||||||
|
#/*
|
||||||
|
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||||
|
# * contributor license agreements. See the NOTICE file distributed with
|
||||||
|
# * this work for additional information regarding copyright ownership.
|
||||||
|
# * The OpenAirInterface Software Alliance licenses this file to You under
|
||||||
|
# * the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||||
|
# * except in compliance with the License.
|
||||||
|
# * You may obtain a copy of the License at
|
||||||
|
# *
|
||||||
|
# * http://www.openairinterface.org/?page_id=698
|
||||||
|
# *
|
||||||
|
# * Unless required by applicable law or agreed to in writing, software
|
||||||
|
# * distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# * See the License for the specific language governing permissions and
|
||||||
|
# * limitations under the License.
|
||||||
|
# *-------------------------------------------------------------------------------
|
||||||
|
# * For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||||
|
# * contact@openairinterface.org
|
||||||
|
# */
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
# Python for CI of OAI-eNB + COTS-UE
|
||||||
|
#
|
||||||
|
# Required Python Version
|
||||||
|
# Python 3.x
|
||||||
|
#
|
||||||
|
# Required Python Package
|
||||||
|
# pexpect
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
# Import
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
import sys # arg
|
||||||
|
import re # reg
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import subprocess
|
||||||
|
from multiprocessing import Process, Lock, SimpleQueue
|
||||||
|
|
||||||
|
import constants as CONST
|
||||||
|
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
# Class Declaration
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
class HTMLManagement():
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
|
||||||
|
self.htmlFile = ''
|
||||||
|
self.htmlHeaderCreated = False
|
||||||
|
self.htmlFooterCreated = False
|
||||||
|
|
||||||
|
self.ranRepository = ''
|
||||||
|
self.ranBranch = ''
|
||||||
|
self.ranCommitID = ''
|
||||||
|
self.ranAllowMerge = False
|
||||||
|
self.ranTargetBranch = ''
|
||||||
|
|
||||||
|
self.nbTestXMLfiles = 0
|
||||||
|
self.htmlTabRefs = []
|
||||||
|
self.htmlTabNames = []
|
||||||
|
self.htmlTabIcons = []
|
||||||
|
self.testXMLfiles = []
|
||||||
|
|
||||||
|
self.htmleNBFailureMsg = ''
|
||||||
|
self.htmlUEFailureMsg = ''
|
||||||
|
|
||||||
|
self.startTime = int(round(time.time() * 1000))
|
||||||
|
self.testCase_id = ''
|
||||||
|
self.desc = ''
|
||||||
|
|
||||||
|
self.OsVersion = ['', '']
|
||||||
|
self.KernelVersion = ['', '']
|
||||||
|
self.UhdVersion = ['', '']
|
||||||
|
self.UsrpBoard = ['', '']
|
||||||
|
self.CpuNb = ['', '']
|
||||||
|
self.CpuModel = ['', '']
|
||||||
|
self.CpuMHz = ['', '']
|
||||||
|
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
# Setters and Getters
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
def SethtmlUEFailureMsg(self,huefa):
|
||||||
|
self.htmlUEFailureMsg = huefa
|
||||||
|
def GethtmlUEFailureMsg(self):
|
||||||
|
return self.htmlUEFailureMsg
|
||||||
|
def SetHmleNBFailureMsg(self, msg):
|
||||||
|
self.htmleNBFailureMsg = msg
|
||||||
|
|
||||||
|
def Setdesc(self, dsc):
|
||||||
|
self.desc = dsc
|
||||||
|
|
||||||
|
def SetstartTime(self, sttime):
|
||||||
|
self.startTime = sttime
|
||||||
|
|
||||||
|
def SettestCase_id(self, tcid):
|
||||||
|
self.testCase_id = tcid
|
||||||
|
def GettestCase_id(self):
|
||||||
|
return self.testCase_id
|
||||||
|
|
||||||
|
def SetranRepository(self, repository):
|
||||||
|
self.ranRepository = repository
|
||||||
|
def SetranAllowMerge(self, merge):
|
||||||
|
self.ranAllowMerge = merge
|
||||||
|
def SetranBranch(self, branch):
|
||||||
|
self.ranBranch = branch
|
||||||
|
def SetranCommitID(self, commitid):
|
||||||
|
self.ranCommitID = commitid
|
||||||
|
def SetranTargetBranch(self, tbranch):
|
||||||
|
self.ranTargetBranch = tbranch
|
||||||
|
|
||||||
|
def SethtmlUEConnected(self, nbUEs):
|
||||||
|
self.htmlUEConnected = nbUEs
|
||||||
|
def SethtmlNb_Smartphones(self, nbUEs):
|
||||||
|
self.htmlNb_Smartphones = nbUEs
|
||||||
|
def SethtmlNb_CATM_Modules(self, nbUEs):
|
||||||
|
self.htmlNb_CATM_Modules = nbUEs
|
||||||
|
|
||||||
|
def SetnbTestXMLfiles(self, nb):
|
||||||
|
self.nbTestXMLfiles = nb
|
||||||
|
def GetnbTestXMLfiles(self):
|
||||||
|
return self.nbTestXMLfiles
|
||||||
|
|
||||||
|
def SettestXMLfiles(self, xmlFile):
|
||||||
|
self.testXMLfiles.append(xmlFile)
|
||||||
|
def SethtmlTabRefs(self, tabRef):
|
||||||
|
self.htmlTabRefs.append(tabRef)
|
||||||
|
def SethtmlTabNames(self, tabName):
|
||||||
|
self.htmlTabNames.append(tabName)
|
||||||
|
def SethtmlTabIcons(self, tabIcon):
|
||||||
|
self.htmlTabIcons.append(tabIcon)
|
||||||
|
|
||||||
|
def SetOsVersion(self, version, idx):
|
||||||
|
self.OsVersion[idx] = version
|
||||||
|
def SetKernelVersion(self, version, idx):
|
||||||
|
self.KernelVersion[idx] = version
|
||||||
|
def SetUhdVersion(self, version, idx):
|
||||||
|
self.UhdVersion[idx] = version
|
||||||
|
def SetUsrpBoard(self, version, idx):
|
||||||
|
self.UsrpBoard[idx] = version
|
||||||
|
def SetCpuNb(self, nb, idx):
|
||||||
|
self.CpuNb[idx] = nb
|
||||||
|
def SetCpuModel(self, model, idx):
|
||||||
|
self.CpuModel[idx] = model
|
||||||
|
def SetCpuMHz(self, freq, idx):
|
||||||
|
self.CpuMHz[idx] = freq
|
||||||
|
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
# HTML structure creation functions
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
def CreateHtmlHeader(self, ADBIPAddress):
|
||||||
|
if (not self.htmlHeaderCreated):
|
||||||
|
logging.debug('\u001B[1m----------------------------------------\u001B[0m')
|
||||||
|
logging.debug('\u001B[1m Creating HTML header \u001B[0m')
|
||||||
|
logging.debug('\u001B[1m----------------------------------------\u001B[0m')
|
||||||
|
self.htmlFile = open('test_results.html', 'w')
|
||||||
|
self.htmlFile.write('<!DOCTYPE html>\n')
|
||||||
|
self.htmlFile.write('<html class="no-js" lang="en-US">\n')
|
||||||
|
self.htmlFile.write('<head>\n')
|
||||||
|
self.htmlFile.write(' <meta name="viewport" content="width=device-width, initial-scale=1">\n')
|
||||||
|
self.htmlFile.write(' <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">\n')
|
||||||
|
self.htmlFile.write(' <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>\n')
|
||||||
|
self.htmlFile.write(' <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>\n')
|
||||||
|
self.htmlFile.write(' <title>Test Results for TEMPLATE_JOB_NAME job build #TEMPLATE_BUILD_ID</title>\n')
|
||||||
|
self.htmlFile.write('</head>\n')
|
||||||
|
self.htmlFile.write('<body><div class="container">\n')
|
||||||
|
self.htmlFile.write(' <br>\n')
|
||||||
|
self.htmlFile.write(' <table style="border-collapse: collapse; border: none;">\n')
|
||||||
|
self.htmlFile.write(' <tr style="border-collapse: collapse; border: none;">\n')
|
||||||
|
self.htmlFile.write(' <td style="border-collapse: collapse; border: none;">\n')
|
||||||
|
self.htmlFile.write(' <a href="http://www.openairinterface.org/">\n')
|
||||||
|
self.htmlFile.write(' <img src="http://www.openairinterface.org/wp-content/uploads/2016/03/cropped-oai_final_logo2.png" alt="" border="none" height=50 width=150>\n')
|
||||||
|
self.htmlFile.write(' </img>\n')
|
||||||
|
self.htmlFile.write(' </a>\n')
|
||||||
|
self.htmlFile.write(' </td>\n')
|
||||||
|
self.htmlFile.write(' <td style="border-collapse: collapse; border: none; vertical-align: center;">\n')
|
||||||
|
self.htmlFile.write(' <b><font size = "6">Job Summary -- Job: TEMPLATE_JOB_NAME -- Build-ID: TEMPLATE_BUILD_ID</font></b>\n')
|
||||||
|
self.htmlFile.write(' </td>\n')
|
||||||
|
self.htmlFile.write(' </tr>\n')
|
||||||
|
self.htmlFile.write(' </table>\n')
|
||||||
|
self.htmlFile.write(' <br>\n')
|
||||||
|
self.htmlFile.write(' <div class="alert alert-info"><strong> <span class="glyphicon glyphicon-dashboard"></span> TEMPLATE_STAGE_NAME</strong></div>\n')
|
||||||
|
self.htmlFile.write(' <table border = "1">\n')
|
||||||
|
self.htmlFile.write(' <tr>\n')
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-time"></span> Build Start Time (UTC) </td>\n')
|
||||||
|
self.htmlFile.write(' <td>TEMPLATE_BUILD_TIME</td>\n')
|
||||||
|
self.htmlFile.write(' </tr>\n')
|
||||||
|
self.htmlFile.write(' <tr>\n')
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-cloud-upload"></span> GIT Repository </td>\n')
|
||||||
|
self.htmlFile.write(' <td><a href="' + self.ranRepository + '">' + self.ranRepository + '</a></td>\n')
|
||||||
|
self.htmlFile.write(' </tr>\n')
|
||||||
|
self.htmlFile.write(' <tr>\n')
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-wrench"></span> Job Trigger </td>\n')
|
||||||
|
if (self.ranAllowMerge):
|
||||||
|
self.htmlFile.write(' <td>Merge-Request</td>\n')
|
||||||
|
else:
|
||||||
|
self.htmlFile.write(' <td>Push to Branch</td>\n')
|
||||||
|
self.htmlFile.write(' </tr>\n')
|
||||||
|
self.htmlFile.write(' <tr>\n')
|
||||||
|
if (self.ranAllowMerge):
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-log-out"></span> Source Branch </td>\n')
|
||||||
|
else:
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-tree-deciduous"></span> Branch</td>\n')
|
||||||
|
self.htmlFile.write(' <td>' + self.ranBranch + '</td>\n')
|
||||||
|
self.htmlFile.write(' </tr>\n')
|
||||||
|
self.htmlFile.write(' <tr>\n')
|
||||||
|
if (self.ranAllowMerge):
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-tag"></span> Source Commit ID </td>\n')
|
||||||
|
else:
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-tag"></span> Commit ID </td>\n')
|
||||||
|
self.htmlFile.write(' <td>' + self.ranCommitID + '</td>\n')
|
||||||
|
self.htmlFile.write(' </tr>\n')
|
||||||
|
if self.ranAllowMerge != '':
|
||||||
|
commit_message = subprocess.check_output("git log -n1 --pretty=format:\"%s\" " + self.ranCommitID, shell=True, universal_newlines=True)
|
||||||
|
commit_message = commit_message.strip()
|
||||||
|
self.htmlFile.write(' <tr>\n')
|
||||||
|
if (self.ranAllowMerge):
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-comment"></span> Source Commit Message </td>\n')
|
||||||
|
else:
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-comment"></span> Commit Message </td>\n')
|
||||||
|
self.htmlFile.write(' <td>' + commit_message + '</td>\n')
|
||||||
|
self.htmlFile.write(' </tr>\n')
|
||||||
|
if (self.ranAllowMerge):
|
||||||
|
self.htmlFile.write(' <tr>\n')
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-log-in"></span> Target Branch </td>\n')
|
||||||
|
if (self.ranTargetBranch == ''):
|
||||||
|
self.htmlFile.write(' <td>develop</td>\n')
|
||||||
|
else:
|
||||||
|
self.htmlFile.write(' <td>' + self.ranTargetBranch + '</td>\n')
|
||||||
|
self.htmlFile.write(' </tr>\n')
|
||||||
|
self.htmlFile.write(' </table>\n')
|
||||||
|
|
||||||
|
if (ADBIPAddress != 'none'):
|
||||||
|
self.htmlFile.write(' <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(self.htmlNb_Smartphones) + ' UE(s) is(are) connected to ADB bench server</h2>\n')
|
||||||
|
self.htmlFile.write(' <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(self.htmlNb_CATM_Modules) + ' CAT-M UE(s) is(are) connected to bench server</h2>\n')
|
||||||
|
else:
|
||||||
|
self.htmlUEConnected = 1
|
||||||
|
self.htmlFile.write(' <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> 1 OAI UE(s) is(are) connected to CI bench</h2>\n')
|
||||||
|
self.htmlFile.write(' <br>\n')
|
||||||
|
self.htmlFile.write(' <ul class="nav nav-pills">\n')
|
||||||
|
count = 0
|
||||||
|
while (count < self.nbTestXMLfiles):
|
||||||
|
pillMsg = ' <li><a data-toggle="pill" href="#'
|
||||||
|
pillMsg += self.htmlTabRefs[count]
|
||||||
|
pillMsg += '">'
|
||||||
|
pillMsg += '__STATE_' + self.htmlTabNames[count] + '__'
|
||||||
|
pillMsg += self.htmlTabNames[count]
|
||||||
|
pillMsg += ' <span class="glyphicon glyphicon-'
|
||||||
|
pillMsg += self.htmlTabIcons[count]
|
||||||
|
pillMsg += '"></span></a></li>\n'
|
||||||
|
self.htmlFile.write(pillMsg)
|
||||||
|
count += 1
|
||||||
|
self.htmlFile.write(' </ul>\n')
|
||||||
|
self.htmlFile.write(' <div class="tab-content">\n')
|
||||||
|
self.htmlFile.close()
|
||||||
|
|
||||||
|
def CreateHtmlTabHeader(self):
|
||||||
|
if (not self.htmlHeaderCreated):
|
||||||
|
if (not os.path.isfile('test_results.html')):
|
||||||
|
self.CreateHtmlHeader('none')
|
||||||
|
self.htmlFile = open('test_results.html', 'a')
|
||||||
|
if (self.nbTestXMLfiles == 1):
|
||||||
|
self.htmlFile.write(' <div id="' + self.htmlTabRefs[0] + '" class="tab-pane fade">\n')
|
||||||
|
self.htmlFile.write(' <h3>Test Summary for <span class="glyphicon glyphicon-file"></span> ' + self.testXMLfiles[0] + '</h3>\n')
|
||||||
|
else:
|
||||||
|
self.htmlFile.write(' <div id="build-tab" class="tab-pane fade">\n')
|
||||||
|
self.htmlFile.write(' <table class="table" border = "1">\n')
|
||||||
|
self.htmlFile.write(' <tr bgcolor = "#33CCFF" >\n')
|
||||||
|
self.htmlFile.write(' <th>Relative Time (ms)</th>\n')
|
||||||
|
self.htmlFile.write(' <th>Test Id</th>\n')
|
||||||
|
self.htmlFile.write(' <th>Test Desc</th>\n')
|
||||||
|
self.htmlFile.write(' <th>Test Options</th>\n')
|
||||||
|
self.htmlFile.write(' <th>Test Status</th>\n')
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
while (i < self.htmlUEConnected):
|
||||||
|
self.htmlFile.write(' <th>UE' + str(i) + ' Status</th>\n')
|
||||||
|
i += 1
|
||||||
|
self.htmlFile.write(' </tr>\n')
|
||||||
|
self.htmlFile.close()
|
||||||
|
self.htmlHeaderCreated = True
|
||||||
|
|
||||||
|
def CreateHtmlTabFooter(self, passStatus):
|
||||||
|
if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)):
|
||||||
|
self.htmlFile = open('test_results.html', 'a')
|
||||||
|
self.htmlFile.write(' <tr>\n')
|
||||||
|
self.htmlFile.write(' <th bgcolor = "#33CCFF" colspan=3>Final Tab Status</th>\n')
|
||||||
|
if passStatus:
|
||||||
|
self.htmlFile.write(' <th bgcolor = "green" colspan=' + str(2 + self.htmlUEConnected) + '><font color="white">PASS <span class="glyphicon glyphicon-ok"></span> </font></th>\n')
|
||||||
|
else:
|
||||||
|
self.htmlFile.write(' <th bgcolor = "red" colspan=' + str(2 + self.htmlUEConnected) + '><font color="white">FAIL <span class="glyphicon glyphicon-remove"></span> </font></th>\n')
|
||||||
|
self.htmlFile.write(' </tr>\n')
|
||||||
|
self.htmlFile.write(' </table>\n')
|
||||||
|
self.htmlFile.write(' </div>\n')
|
||||||
|
self.htmlFile.close()
|
||||||
|
time.sleep(1)
|
||||||
|
if passStatus:
|
||||||
|
cmd = "sed -i -e 's/__STATE_" + self.htmlTabNames[0] + "__//' test_results.html"
|
||||||
|
subprocess.run(cmd, shell=True)
|
||||||
|
else:
|
||||||
|
cmd = "sed -i -e 's/__STATE_" + self.htmlTabNames[0] + "__/<span class=\"glyphicon glyphicon-remove\"><\/span>/' test_results.html"
|
||||||
|
subprocess.run(cmd, shell=True)
|
||||||
|
self.htmlFooterCreated = False
|
||||||
|
|
||||||
|
def CreateHtmlFooter(self, passStatus):
|
||||||
|
if (os.path.isfile('test_results.html')):
|
||||||
|
self.htmlFile = open('test_results.html', 'a')
|
||||||
|
self.htmlFile.write('</div>\n')
|
||||||
|
self.htmlFile.write(' <p></p>\n')
|
||||||
|
self.htmlFile.write(' <table class="table table-condensed">\n')
|
||||||
|
|
||||||
|
machines = [ 'eNB', 'UE' ]
|
||||||
|
for machine in machines:
|
||||||
|
if machine == 'eNB':
|
||||||
|
idx = 0
|
||||||
|
else:
|
||||||
|
idx = 1
|
||||||
|
if self.OsVersion[idx] == '':
|
||||||
|
continue
|
||||||
|
|
||||||
|
self.htmlFile.write(' <tr>\n')
|
||||||
|
self.htmlFile.write(' <th colspan=8>' + str('eNB') + ' Server Characteristics</th>\n')
|
||||||
|
self.htmlFile.write(' </tr>\n')
|
||||||
|
self.htmlFile.write(' <tr>\n')
|
||||||
|
self.htmlFile.write(' <td>OS Version</td>\n')
|
||||||
|
self.htmlFile.write(' <td><span class="label label-default">' + self.OsVersion[idx] + '</span></td>\n')
|
||||||
|
self.htmlFile.write(' <td>Kernel Version</td>\n')
|
||||||
|
self.htmlFile.write(' <td><span class="label label-default">' + self.KernelVersion[idx] + '</span></td>\n')
|
||||||
|
self.htmlFile.write(' <td>UHD Version</td>\n')
|
||||||
|
self.htmlFile.write(' <td><span class="label label-default">' + self.UhdVersion[idx] + '</span></td>\n')
|
||||||
|
self.htmlFile.write(' <td>USRP Board</td>\n')
|
||||||
|
self.htmlFile.write(' <td><span class="label label-default">' + self.UsrpBoard[idx] + '</span></td>\n')
|
||||||
|
self.htmlFile.write(' </tr>\n')
|
||||||
|
self.htmlFile.write(' <tr>\n')
|
||||||
|
self.htmlFile.write(' <td>Nb CPUs</td>\n')
|
||||||
|
self.htmlFile.write(' <td><span class="label label-default">' + self.CpuNb[idx] + '</span></td>\n')
|
||||||
|
self.htmlFile.write(' <td>CPU Model Name</td>\n')
|
||||||
|
self.htmlFile.write(' <td><span class="label label-default">' + self.CpuModel[idx] + '</span></td>\n')
|
||||||
|
self.htmlFile.write(' <td>CPU Frequency</td>\n')
|
||||||
|
self.htmlFile.write(' <td><span class="label label-default">' + self.CpuMHz[idx] + '</span></td>\n')
|
||||||
|
self.htmlFile.write(' <td></td>\n')
|
||||||
|
self.htmlFile.write(' <td></td>\n')
|
||||||
|
self.htmlFile.write(' </tr>\n')
|
||||||
|
|
||||||
|
self.htmlFile.write(' <tr>\n')
|
||||||
|
self.htmlFile.write(' <th colspan=5 bgcolor = "#33CCFF">Final Status</th>\n')
|
||||||
|
if passStatus:
|
||||||
|
self.htmlFile.write(' <th colspan=3 bgcolor="green"><font color="white">PASS <span class="glyphicon glyphicon-ok"></span></font></th>\n')
|
||||||
|
else:
|
||||||
|
self.htmlFile.write(' <th colspan=3 bgcolor="red"><font color="white">FAIL <span class="glyphicon glyphicon-remove"></span> </font></th>\n')
|
||||||
|
self.htmlFile.write(' </tr>\n')
|
||||||
|
self.htmlFile.write(' </table>\n')
|
||||||
|
self.htmlFile.write(' <p></p>\n')
|
||||||
|
self.htmlFile.write(' <div class="well well-lg">End of Test Report -- Copyright <span class="glyphicon glyphicon-copyright-mark"></span> 2018 <a href="http://www.openairinterface.org/">OpenAirInterface</a>. All Rights Reserved.</div>\n')
|
||||||
|
self.htmlFile.write('</div></body>\n')
|
||||||
|
self.htmlFile.write('</html>\n')
|
||||||
|
self.htmlFile.close()
|
||||||
|
|
||||||
|
def CreateHtmlRetrySeparator(self, cntnumfails):
|
||||||
|
if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)):
|
||||||
|
self.htmlFile = open('test_results.html', 'a')
|
||||||
|
self.htmlFile.write(' <tr bgcolor = "#F0F0F0" >\n')
|
||||||
|
self.htmlFile.write(' <td colspan=' + str(5+self.htmlUEConnected) + '><b> ---- Try Run #' + str(cntnumfails) + ' ---- </b></td>\n')
|
||||||
|
self.htmlFile.write(' </tr>\n')
|
||||||
|
self.htmlFile.close()
|
||||||
|
|
||||||
|
def CreateHtmlTestRow(self, options, status, processesStatus, machine='eNB'):
|
||||||
|
if (self.htmlFooterCreated or (not self.htmlHeaderCreated)):
|
||||||
|
return
|
||||||
|
self.htmlFile = open('test_results.html', 'a')
|
||||||
|
currentTime = int(round(time.time() * 1000)) - self.startTime
|
||||||
|
self.htmlFile.write(' <tr>\n')
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcyan" >' + format(currentTime / 1000, '.1f') + '</td>\n')
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcyan" >' + self.testCase_id + '</td>\n')
|
||||||
|
self.htmlFile.write(' <td>' + self.desc + '</td>\n')
|
||||||
|
self.htmlFile.write(' <td>' + str(options) + '</td>\n')
|
||||||
|
if (str(status) == 'OK'):
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightgreen" >' + str(status) + '</td>\n')
|
||||||
|
elif (str(status) == 'KO'):
|
||||||
|
if (processesStatus == 0):
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcoral" >' + str(status) + '</td>\n')
|
||||||
|
elif (processesStatus == CONST.ENB_PROCESS_FAILED):
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - eNB process not found</td>\n')
|
||||||
|
elif (processesStatus == CONST.OAI_UE_PROCESS_FAILED):
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - OAI UE process not found</td>\n')
|
||||||
|
elif (processesStatus == CONST.ENB_PROCESS_SEG_FAULT) or (processesStatus == CONST.OAI_UE_PROCESS_SEG_FAULT):
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - ' + machine + ' process ended in Segmentation Fault</td>\n')
|
||||||
|
elif (processesStatus == CONST.ENB_PROCESS_ASSERTION) or (processesStatus == CONST.OAI_UE_PROCESS_ASSERTION):
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - ' + machine + ' process ended in Assertion</td>\n')
|
||||||
|
elif (processesStatus == CONST.ENB_PROCESS_REALTIME_ISSUE):
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - ' + machine + ' process faced Real Time issue(s)</td>\n')
|
||||||
|
elif (processesStatus == CONST.ENB_PROCESS_NOLOGFILE_TO_ANALYZE) or (processesStatus == CONST.OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE):
|
||||||
|
self.htmlFile.write(' <td bgcolor = "orange" >OK?</td>\n')
|
||||||
|
elif (processesStatus == CONST.ENB_PROCESS_SLAVE_RRU_NOT_SYNCED):
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - ' + machine + ' Slave RRU could not synch</td>\n')
|
||||||
|
elif (processesStatus == CONST.OAI_UE_PROCESS_COULD_NOT_SYNC):
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - UE could not sync</td>\n')
|
||||||
|
elif (processesStatus == CONST.HSS_PROCESS_FAILED):
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - HSS process not found</td>\n')
|
||||||
|
elif (processesStatus == CONST.MME_PROCESS_FAILED):
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - MME process not found</td>\n')
|
||||||
|
elif (processesStatus == CONST.SPGW_PROCESS_FAILED):
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - SPGW process not found</td>\n')
|
||||||
|
elif (processesStatus == CONST.UE_IP_ADDRESS_ISSUE):
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - Could not retrieve UE IP address</td>\n')
|
||||||
|
else:
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcoral" >' + str(status) + '</td>\n')
|
||||||
|
else:
|
||||||
|
self.htmlFile.write(' <td bgcolor = "orange" >' + str(status) + '</td>\n')
|
||||||
|
if (len(str(self.htmleNBFailureMsg)) > 2):
|
||||||
|
cellBgColor = 'white'
|
||||||
|
result = re.search('ended with|faced real time issues', self.htmleNBFailureMsg)
|
||||||
|
if result is not None:
|
||||||
|
cellBgColor = 'red'
|
||||||
|
else:
|
||||||
|
result = re.search('showed|Reestablishment|Could not copy eNB logfile', self.htmleNBFailureMsg)
|
||||||
|
if result is not None:
|
||||||
|
cellBgColor = 'orange'
|
||||||
|
self.htmlFile.write(' <td bgcolor = "' + cellBgColor + '" colspan=' + str(self.htmlUEConnected) + '><pre style="background-color:' + cellBgColor + '">' + self.htmleNBFailureMsg + '</pre></td>\n')
|
||||||
|
self.htmleNBFailureMsg = ''
|
||||||
|
elif (len(str(self.htmlUEFailureMsg)) > 2):
|
||||||
|
cellBgColor = 'white'
|
||||||
|
result = re.search('ended with|faced real time issues', self.htmlUEFailureMsg)
|
||||||
|
if result is not None:
|
||||||
|
cellBgColor = 'red'
|
||||||
|
else:
|
||||||
|
result = re.search('showed|Could not copy UE logfile|oaitun_ue1 interface is either NOT mounted or NOT configured', self.htmlUEFailureMsg)
|
||||||
|
if result is not None:
|
||||||
|
cellBgColor = 'orange'
|
||||||
|
self.htmlFile.write(' <td bgcolor = "' + cellBgColor + '" colspan=' + str(self.htmlUEConnected) + '><pre style="background-color:' + cellBgColor + '">' + self.htmlUEFailureMsg + '</pre></td>\n')
|
||||||
|
self.htmlUEFailureMsg = ''
|
||||||
|
else:
|
||||||
|
i = 0
|
||||||
|
while (i < self.htmlUEConnected):
|
||||||
|
self.htmlFile.write(' <td>-</td>\n')
|
||||||
|
i += 1
|
||||||
|
self.htmlFile.write(' </tr>\n')
|
||||||
|
self.htmlFile.close()
|
||||||
|
|
||||||
|
def CreateHtmlTestRowQueue(self, options, status, ue_status, ue_queue):
|
||||||
|
if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)):
|
||||||
|
self.htmlFile = open('test_results.html', 'a')
|
||||||
|
currentTime = int(round(time.time() * 1000)) - self.startTime
|
||||||
|
addOrangeBK = False
|
||||||
|
self.htmlFile.write(' <tr>\n')
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcyan" >' + format(currentTime / 1000, '.1f') + '</td>\n')
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcyan" >' + self.testCase_id + '</td>\n')
|
||||||
|
self.htmlFile.write(' <td>' + self.desc + '</td>\n')
|
||||||
|
self.htmlFile.write(' <td>' + str(options) + '</td>\n')
|
||||||
|
if (str(status) == 'OK'):
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightgreen" >' + str(status) + '</td>\n')
|
||||||
|
elif (str(status) == 'KO'):
|
||||||
|
self.htmlFile.write(' <td bgcolor = "lightcoral" >' + str(status) + '</td>\n')
|
||||||
|
else:
|
||||||
|
addOrangeBK = True
|
||||||
|
self.htmlFile.write(' <td bgcolor = "orange" >' + str(status) + '</td>\n')
|
||||||
|
i = 0
|
||||||
|
while (i < self.htmlUEConnected):
|
||||||
|
if (i < ue_status):
|
||||||
|
if (not ue_queue.empty()):
|
||||||
|
if (addOrangeBK):
|
||||||
|
self.htmlFile.write(' <td bgcolor = "orange" >' + str(ue_queue.get()).replace('white', 'orange') + '</td>\n')
|
||||||
|
else:
|
||||||
|
self.htmlFile.write(' <td>' + str(ue_queue.get()) + '</td>\n')
|
||||||
|
else:
|
||||||
|
self.htmlFile.write(' <td>-</td>\n')
|
||||||
|
else:
|
||||||
|
self.htmlFile.write(' <td>-</td>\n')
|
||||||
|
i += 1
|
||||||
|
self.htmlFile.write(' </tr>\n')
|
||||||
|
self.htmlFile.close()
|
||||||
|
|
||||||
+1042
-2621
File diff suppressed because it is too large
Load Diff
+1051
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,217 @@
|
|||||||
|
#/*
|
||||||
|
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||||
|
# * contributor license agreements. See the NOTICE file distributed with
|
||||||
|
# * this work for additional information regarding copyright ownership.
|
||||||
|
# * The OpenAirInterface Software Alliance licenses this file to You under
|
||||||
|
# * the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||||
|
# * except in compliance with the License.
|
||||||
|
# * You may obtain a copy of the License at
|
||||||
|
# *
|
||||||
|
# * http://www.openairinterface.org/?page_id=698
|
||||||
|
# *
|
||||||
|
# * Unless required by applicable law or agreed to in writing, software
|
||||||
|
# * distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# * See the License for the specific language governing permissions and
|
||||||
|
# * limitations under the License.
|
||||||
|
# *-------------------------------------------------------------------------------
|
||||||
|
# * For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||||
|
# * contact@openairinterface.org
|
||||||
|
# */
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
# Python for CI of OAI-eNB + COTS-UE
|
||||||
|
#
|
||||||
|
# Required Python Version
|
||||||
|
# Python 3.x
|
||||||
|
#
|
||||||
|
# Required Python Package
|
||||||
|
# pexpect
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
# Import
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
import pexpect # pexpect
|
||||||
|
import logging
|
||||||
|
import time # sleep
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
# Class Declaration
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
class SSHConnection():
|
||||||
|
def __init__(self):
|
||||||
|
self.ssh = ''
|
||||||
|
self.picocom_closure = False
|
||||||
|
|
||||||
|
def disablePicocomClosure(self):
|
||||||
|
self.picocom_closure = False
|
||||||
|
|
||||||
|
def enablePicocomClosure(self):
|
||||||
|
self.picocom_closure = True
|
||||||
|
|
||||||
|
def open(self, ipaddress, username, password):
|
||||||
|
count = 0
|
||||||
|
connect_status = False
|
||||||
|
while count < 4:
|
||||||
|
self.ssh = pexpect.spawn('ssh', [username + '@' + ipaddress], timeout = 5)
|
||||||
|
self.sshresponse = self.ssh.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', 'Last login', pexpect.EOF, pexpect.TIMEOUT])
|
||||||
|
if self.sshresponse == 0:
|
||||||
|
self.ssh.sendline('yes')
|
||||||
|
self.ssh.expect('password:')
|
||||||
|
self.ssh.sendline(password)
|
||||||
|
self.sshresponse = self.ssh.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
|
||||||
|
if self.sshresponse == 0:
|
||||||
|
count = 10
|
||||||
|
connect_status = True
|
||||||
|
else:
|
||||||
|
logging.debug('self.sshresponse = ' + str(self.sshresponse))
|
||||||
|
elif self.sshresponse == 1:
|
||||||
|
self.ssh.sendline(password)
|
||||||
|
self.sshresponse = self.ssh.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
|
||||||
|
if self.sshresponse == 0:
|
||||||
|
count = 10
|
||||||
|
connect_status = True
|
||||||
|
else:
|
||||||
|
logging.debug('self.sshresponse = ' + str(self.sshresponse))
|
||||||
|
elif self.sshresponse == 2:
|
||||||
|
# Checking if we are really on the remote client defined by its IP address
|
||||||
|
self.command('stdbuf -o0 ifconfig | egrep --color=never "inet addr:|inet "', '\$', 5)
|
||||||
|
result = re.search(str(ipaddress), str(self.ssh.before))
|
||||||
|
if result is None:
|
||||||
|
self.close()
|
||||||
|
else:
|
||||||
|
count = 10
|
||||||
|
connect_status = True
|
||||||
|
else:
|
||||||
|
# debug output
|
||||||
|
logging.debug(str(self.ssh.before))
|
||||||
|
logging.debug('self.sshresponse = ' + str(self.sshresponse))
|
||||||
|
# adding a tempo when failure
|
||||||
|
if not connect_status:
|
||||||
|
time.sleep(1)
|
||||||
|
count += 1
|
||||||
|
if connect_status:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
sys.exit('SSH Connection Failed')
|
||||||
|
|
||||||
|
def command(self, commandline, expectedline, timeout):
|
||||||
|
logging.debug(commandline)
|
||||||
|
self.ssh.timeout = timeout
|
||||||
|
self.ssh.sendline(commandline)
|
||||||
|
self.sshresponse = self.ssh.expect([expectedline, pexpect.EOF, pexpect.TIMEOUT])
|
||||||
|
if self.sshresponse == 0:
|
||||||
|
return 0
|
||||||
|
elif self.sshresponse == 1:
|
||||||
|
logging.debug('\u001B[1;37;41m Unexpected EOF \u001B[0m')
|
||||||
|
logging.debug('Expected Line : ' + expectedline)
|
||||||
|
logging.debug(str(self.ssh.before))
|
||||||
|
sys.exit(self.sshresponse)
|
||||||
|
elif self.sshresponse == 2:
|
||||||
|
logging.debug('\u001B[1;37;41m Unexpected TIMEOUT \u001B[0m')
|
||||||
|
logging.debug('Expected Line : ' + expectedline)
|
||||||
|
result = re.search('ping |iperf |picocom', str(commandline))
|
||||||
|
if result is None:
|
||||||
|
logging.debug(str(self.ssh.before))
|
||||||
|
sys.exit(self.sshresponse)
|
||||||
|
else:
|
||||||
|
return -1
|
||||||
|
else:
|
||||||
|
logging.debug('\u001B[1;37;41m Unexpected Others \u001B[0m')
|
||||||
|
logging.debug('Expected Line : ' + expectedline)
|
||||||
|
sys.exit(self.sshresponse)
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
self.ssh.timeout = 5
|
||||||
|
self.ssh.sendline('exit')
|
||||||
|
self.sshresponse = self.ssh.expect([pexpect.EOF, pexpect.TIMEOUT])
|
||||||
|
if self.sshresponse == 0:
|
||||||
|
pass
|
||||||
|
elif self.sshresponse == 1:
|
||||||
|
if not self.picocom_closure:
|
||||||
|
logging.debug('\u001B[1;37;41m Unexpected TIMEOUT during closing\u001B[0m')
|
||||||
|
else:
|
||||||
|
logging.debug('\u001B[1;37;41m Unexpected Others during closing\u001B[0m')
|
||||||
|
|
||||||
|
def copyin(self, ipaddress, username, password, source, destination):
|
||||||
|
count = 0
|
||||||
|
copy_status = False
|
||||||
|
logging.debug('scp '+ username + '@' + ipaddress + ':' + source + ' ' + destination)
|
||||||
|
while count < 10:
|
||||||
|
scp_spawn = pexpect.spawn('scp '+ username + '@' + ipaddress + ':' + source + ' ' + destination, timeout = 100)
|
||||||
|
scp_response = scp_spawn.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', pexpect.EOF, pexpect.TIMEOUT])
|
||||||
|
if scp_response == 0:
|
||||||
|
scp_spawn.sendline('yes')
|
||||||
|
scp_spawn.expect('password:')
|
||||||
|
scp_spawn.sendline(password)
|
||||||
|
scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
|
||||||
|
if scp_response == 0:
|
||||||
|
count = 10
|
||||||
|
copy_status = True
|
||||||
|
else:
|
||||||
|
logging.debug('1 - scp_response = ' + str(scp_response))
|
||||||
|
elif scp_response == 1:
|
||||||
|
scp_spawn.sendline(password)
|
||||||
|
scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
|
||||||
|
if scp_response == 0 or scp_response == 3:
|
||||||
|
count = 10
|
||||||
|
copy_status = True
|
||||||
|
else:
|
||||||
|
logging.debug('2 - scp_response = ' + str(scp_response))
|
||||||
|
elif scp_response == 2:
|
||||||
|
count = 10
|
||||||
|
copy_status = True
|
||||||
|
else:
|
||||||
|
logging.debug('3 - scp_response = ' + str(scp_response))
|
||||||
|
# adding a tempo when failure
|
||||||
|
if not copy_status:
|
||||||
|
time.sleep(1)
|
||||||
|
count += 1
|
||||||
|
if copy_status:
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
return -1
|
||||||
|
|
||||||
|
def copyout(self, ipaddress, username, password, source, destination):
|
||||||
|
count = 0
|
||||||
|
copy_status = False
|
||||||
|
logging.debug('scp ' + source + ' ' + username + '@' + ipaddress + ':' + destination)
|
||||||
|
while count < 4:
|
||||||
|
scp_spawn = pexpect.spawn('scp ' + source + ' ' + username + '@' + ipaddress + ':' + destination, timeout = 100)
|
||||||
|
scp_response = scp_spawn.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', pexpect.EOF, pexpect.TIMEOUT])
|
||||||
|
if scp_response == 0:
|
||||||
|
scp_spawn.sendline('yes')
|
||||||
|
scp_spawn.expect('password:')
|
||||||
|
scp_spawn.sendline(password)
|
||||||
|
scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
|
||||||
|
if scp_response == 0:
|
||||||
|
count = 10
|
||||||
|
copy_status = True
|
||||||
|
else:
|
||||||
|
logging.debug('1 - scp_response = ' + str(scp_response))
|
||||||
|
elif scp_response == 1:
|
||||||
|
scp_spawn.sendline(password)
|
||||||
|
scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
|
||||||
|
if scp_response == 0 or scp_response == 3:
|
||||||
|
count = 10
|
||||||
|
copy_status = True
|
||||||
|
else:
|
||||||
|
logging.debug('2 - scp_response = ' + str(scp_response))
|
||||||
|
elif scp_response == 2:
|
||||||
|
count = 10
|
||||||
|
copy_status = True
|
||||||
|
else:
|
||||||
|
logging.debug('3 - scp_response = ' + str(scp_response))
|
||||||
|
# adding a tempo when failure
|
||||||
|
if not copy_status:
|
||||||
|
time.sleep(1)
|
||||||
|
count += 1
|
||||||
|
if copy_status:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
sys.exit('SCP failed')
|
||||||
|
|
||||||
|
def getBefore(self):
|
||||||
|
return str(self.ssh.before)
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
<htmlTabRef>test-lte-m-10-tm1</htmlTabRef>
|
<htmlTabRef>test-lte-m-10-tm1</htmlTabRef>
|
||||||
<htmlTabName>Test-LTE-M-10MHz-TM1</htmlTabName>
|
<htmlTabName>Test-LTE-M-10MHz-TM1</htmlTabName>
|
||||||
<htmlTabIcon>tasks</htmlTabIcon>
|
<htmlTabIcon>tasks</htmlTabIcon>
|
||||||
<repeatCount>2</repeatCount>
|
<repeatCount>1</repeatCount>
|
||||||
<TestCaseRequestedList>
|
<TestCaseRequestedList>
|
||||||
030201
|
030201
|
||||||
040102
|
040102
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
<htmlTabRef>test-05-tm2</htmlTabRef>
|
<htmlTabRef>test-05-tm2</htmlTabRef>
|
||||||
<htmlTabName>Test-05MHz-TM2</htmlTabName>
|
<htmlTabName>Test-05MHz-TM2</htmlTabName>
|
||||||
<htmlTabIcon>tasks</htmlTabIcon>
|
<htmlTabIcon>tasks</htmlTabIcon>
|
||||||
<repeatCount>3</repeatCount>
|
<repeatCount>2</repeatCount>
|
||||||
<TestCaseRequestedList>
|
<TestCaseRequestedList>
|
||||||
030201
|
030201
|
||||||
040101
|
040101
|
||||||
|
|||||||
@@ -72,7 +72,11 @@
|
|||||||
<testCase id="030105">
|
<testCase id="030105">
|
||||||
<class>Initialize_eNB</class>
|
<class>Initialize_eNB</class>
|
||||||
<desc>Initialize eNB #1 (FDD/Band7/5MHz)</desc>
|
<desc>Initialize eNB #1 (FDD/Band7/5MHz)</desc>
|
||||||
|
<<<<<<< HEAD
|
||||||
|
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf --eNBs.[0].rrc_inactivity_threshold 0 --RUs.[0].max_rxgain 120 --eNBs.[0].component_carriers.[0].pusch_p0_Nominal -90 --eNBs.[0].component_carriers.[0].pucch_p0_Nominal -96 --eNBs.[0].tracking_area_code 600 --eNBs.[0].plmn_list.[0].mnc 95 --THREAD_STRUCT.[0].parallel_config PARALLEL_RU_L1_TRX_SPLIT --eNBs.[0].enable_measurement_reports yes --eNBs.[0].enable_x2 yes --eNBs.[0].target_enb_x2_ip_address.[0].ipv4 CI_RCC_IP_ADDR --eNBs.[0].target_enb_x2_ip_address.[0].preference ipv4 --eNBs.[0].eNB_ID 0xe01 --eNBs.[0].component_carriers.[0].Nid_cell 1 --eNBs.[0].nr_cellid 98765</Initialize_eNB_args>
|
||||||
|
=======
|
||||||
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.25PRB.slave.usrpb210.conf --eNBs.[0].rrc_inactivity_threshold 0 --RUs.[0].max_rxgain 120 --eNBs.[0].component_carriers.[0].pusch_p0_Nominal -90 --eNBs.[0].component_carriers.[0].pucch_p0_Nominal -96 --eNBs.[0].tracking_area_code 600 --eNBs.[0].plmn_list.[0].mnc 95 --THREAD_STRUCT.[0].parallel_config PARALLEL_RU_L1_TRX_SPLIT --eNBs.[0].enable_measurement_reports yes --eNBs.[0].enable_x2 yes --eNBs.[0].nr_cellid 98765</Initialize_eNB_args>
|
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.25PRB.slave.usrpb210.conf --eNBs.[0].rrc_inactivity_threshold 0 --RUs.[0].max_rxgain 120 --eNBs.[0].component_carriers.[0].pusch_p0_Nominal -90 --eNBs.[0].component_carriers.[0].pucch_p0_Nominal -96 --eNBs.[0].tracking_area_code 600 --eNBs.[0].plmn_list.[0].mnc 95 --THREAD_STRUCT.[0].parallel_config PARALLEL_RU_L1_TRX_SPLIT --eNBs.[0].enable_measurement_reports yes --eNBs.[0].enable_x2 yes --eNBs.[0].nr_cellid 98765</Initialize_eNB_args>
|
||||||
|
>>>>>>> origin/develop_inria_ci_deployment
|
||||||
<eNB_instance>1</eNB_instance>
|
<eNB_instance>1</eNB_instance>
|
||||||
<eNB_serverId>1</eNB_serverId>
|
<eNB_serverId>1</eNB_serverId>
|
||||||
</testCase>
|
</testCase>
|
||||||
|
|||||||
@@ -727,7 +727,6 @@ Message("CPU_Affinity flag is ${CPU_AFFINITY}")
|
|||||||
##############################################################
|
##############################################################
|
||||||
|
|
||||||
add_boolean_option(NO_RRM True "DO WE HAVE A RADIO RESSOURCE MANAGER: NO")
|
add_boolean_option(NO_RRM True "DO WE HAVE A RADIO RESSOURCE MANAGER: NO")
|
||||||
add_boolean_option(RRC_DEFAULT_RAB_IS_AM False "set the RLC mode to AM for the default bearer")
|
|
||||||
|
|
||||||
add_boolean_option(OAI_NW_DRIVER_TYPE_ETHERNET False "????")
|
add_boolean_option(OAI_NW_DRIVER_TYPE_ETHERNET False "????")
|
||||||
add_boolean_option(DEADLINE_SCHEDULER True "Use the Linux scheduler SCHED_DEADLINE: kernel >= 3.14")
|
add_boolean_option(DEADLINE_SCHEDULER True "Use the Linux scheduler SCHED_DEADLINE: kernel >= 3.14")
|
||||||
@@ -828,7 +827,7 @@ add_boolean_option(TRACE_RLC_UM_TX_STATUS False "TRACE for RLC UM, TO BE CHANGE
|
|||||||
##########################
|
##########################
|
||||||
# RRC LAYER OPTIONS
|
# RRC LAYER OPTIONS
|
||||||
##########################
|
##########################
|
||||||
add_boolean_option(RRC_DEFAULT_RAB_IS_AM False "Otherwise it is UM, configure params are actually set in rrc_eNB.c:rrc_eNB_generate_defaultRRCConnectionReconfiguration(...)")
|
add_boolean_option(RRC_DEFAULT_RAB_IS_AM True "set the RLC mode to AM for the default bearer, otherwise it is UM.")
|
||||||
|
|
||||||
|
|
||||||
##########################
|
##########################
|
||||||
@@ -884,6 +883,7 @@ include_directories("${OPENAIR2_DIR}/LAYER2/PDCP_v10.1.0")
|
|||||||
include_directories("${OPENAIR2_DIR}/RRC/LTE/MESSAGES")
|
include_directories("${OPENAIR2_DIR}/RRC/LTE/MESSAGES")
|
||||||
include_directories("${OPENAIR2_DIR}/RRC/LTE")
|
include_directories("${OPENAIR2_DIR}/RRC/LTE")
|
||||||
include_directories("${OPENAIR_DIR}/common/utils")
|
include_directories("${OPENAIR_DIR}/common/utils")
|
||||||
|
include_directories("${OPENAIR_DIR}/common/utils/collection")
|
||||||
include_directories("${OPENAIR_DIR}/common/utils/ocp_itti")
|
include_directories("${OPENAIR_DIR}/common/utils/ocp_itti")
|
||||||
include_directories("${OPENAIR3_DIR}/NAS/COMMON")
|
include_directories("${OPENAIR3_DIR}/NAS/COMMON")
|
||||||
include_directories("${OPENAIR3_DIR}/NAS/COMMON/API/NETWORK")
|
include_directories("${OPENAIR3_DIR}/NAS/COMMON/API/NETWORK")
|
||||||
@@ -1593,6 +1593,7 @@ add_library(PHY_COMMON ${PHY_SRC_COMMON})
|
|||||||
add_dependencies(PHY_COMMON rrc_flag)
|
add_dependencies(PHY_COMMON rrc_flag)
|
||||||
add_dependencies(PHY_COMMON dfts)
|
add_dependencies(PHY_COMMON dfts)
|
||||||
add_library(PHY ${PHY_SRC})
|
add_library(PHY ${PHY_SRC})
|
||||||
|
|
||||||
add_dependencies(PHY rrc_flag)
|
add_dependencies(PHY rrc_flag)
|
||||||
add_library(PHY_UE ${PHY_SRC_UE})
|
add_library(PHY_UE ${PHY_SRC_UE})
|
||||||
add_dependencies(PHY_UE rrc_flag)
|
add_dependencies(PHY_UE rrc_flag)
|
||||||
@@ -1643,7 +1644,7 @@ set(NR_RRC_DIR ${OPENAIR2_DIR}/RRC/NR)
|
|||||||
set(NR_UE_RRC_DIR ${OPENAIR2_DIR}/RRC/NR_UE)
|
set(NR_UE_RRC_DIR ${OPENAIR2_DIR}/RRC/NR_UE)
|
||||||
set(PDCP_DIR ${OPENAIR2_DIR}/LAYER2/PDCP_v10.1.0)
|
set(PDCP_DIR ${OPENAIR2_DIR}/LAYER2/PDCP_v10.1.0)
|
||||||
|
|
||||||
set(LTE_RLC_SRC
|
set(RLC_V1
|
||||||
${RLC_AM_DIR}/rlc_am.c
|
${RLC_AM_DIR}/rlc_am.c
|
||||||
${RLC_AM_DIR}/rlc_am_init.c
|
${RLC_AM_DIR}/rlc_am_init.c
|
||||||
${RLC_AM_DIR}/rlc_am_timer_poll_retransmit.c
|
${RLC_AM_DIR}/rlc_am_timer_poll_retransmit.c
|
||||||
@@ -1673,6 +1674,17 @@ set(LTE_RLC_SRC
|
|||||||
${RLC_DIR}/rlc_mpls.c
|
${RLC_DIR}/rlc_mpls.c
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set(RLC_V2
|
||||||
|
${OPENAIR2_DIR}/LAYER2/rlc_v2/rlc_oai_api.c
|
||||||
|
${OPENAIR2_DIR}/LAYER2/rlc_v2/asn1_utils.c
|
||||||
|
${OPENAIR2_DIR}/LAYER2/rlc_v2/rlc_ue_manager.c
|
||||||
|
${OPENAIR2_DIR}/LAYER2/rlc_v2/rlc_entity.c
|
||||||
|
${OPENAIR2_DIR}/LAYER2/rlc_v2/rlc_entity_am.c
|
||||||
|
${OPENAIR2_DIR}/LAYER2/rlc_v2/rlc_entity_um.c
|
||||||
|
${OPENAIR2_DIR}/LAYER2/rlc_v2/rlc_pdu.c
|
||||||
|
${OPENAIR2_DIR}/LAYER2/rlc_v2/rlc_sdu.c
|
||||||
|
)
|
||||||
|
|
||||||
set(NR_RLC_SRC
|
set(NR_RLC_SRC
|
||||||
${OPENAIR2_DIR}/LAYER2/nr_rlc/asn1_utils.c
|
${OPENAIR2_DIR}/LAYER2/nr_rlc/asn1_utils.c
|
||||||
${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_entity.c
|
${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_entity.c
|
||||||
@@ -1707,7 +1719,7 @@ set(L2_SRC
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(L2_LTE_SRC
|
set(L2_LTE_SRC
|
||||||
${LTE_RLC_SRC}
|
${RLC_V2}
|
||||||
)
|
)
|
||||||
|
|
||||||
set(L2_NR_SRC
|
set(L2_NR_SRC
|
||||||
@@ -1744,7 +1756,7 @@ set(LTE_NR_L2_SRC_UE
|
|||||||
${PDCP_DIR}/pdcp_util.c
|
${PDCP_DIR}/pdcp_util.c
|
||||||
${PDCP_DIR}/pdcp_security.c
|
${PDCP_DIR}/pdcp_security.c
|
||||||
${PDCP_DIR}/pdcp_netlink.c
|
${PDCP_DIR}/pdcp_netlink.c
|
||||||
${LTE_RLC_SRC}
|
${RLC_V2}
|
||||||
)
|
)
|
||||||
|
|
||||||
set(NR_L2_SRC_UE
|
set(NR_L2_SRC_UE
|
||||||
@@ -2484,6 +2496,7 @@ add_executable(lte-softmodem
|
|||||||
${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/lte-softmodem.c
|
${OPENAIR_TARGETS}/RT/USER/lte-softmodem.c
|
||||||
|
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||||
${OPENAIR_DIR}/executables/softmodem-common.c
|
${OPENAIR_DIR}/executables/softmodem-common.c
|
||||||
${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c
|
${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c
|
||||||
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
|
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
|
||||||
@@ -2519,6 +2532,43 @@ target_link_libraries (lte-softmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_L
|
|||||||
target_link_libraries (lte-softmodem ${LIB_LMS_LIBRARIES})
|
target_link_libraries (lte-softmodem ${LIB_LMS_LIBRARIES})
|
||||||
target_link_libraries (lte-softmodem ${T_LIB})
|
target_link_libraries (lte-softmodem ${T_LIB})
|
||||||
|
|
||||||
|
|
||||||
|
add_executable(ocp-enb
|
||||||
|
${OPENAIR_DIR}/executables/main-ocp.c
|
||||||
|
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||||
|
${OPENAIR_DIR}/executables/softmodem-common.c
|
||||||
|
${OPENAIR_DIR}/executables/main-fs6.c
|
||||||
|
${OPENAIR_DIR}/executables/transport_split.c
|
||||||
|
${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c
|
||||||
|
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
|
||||||
|
${OPENAIR_TARGETS}/COMMON/create_tasks.c
|
||||||
|
${OPENAIR_TARGETS}/COMMON/create_tasks_mbms.c
|
||||||
|
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
|
||||||
|
${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c
|
||||||
|
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
|
||||||
|
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
|
||||||
|
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
||||||
|
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c
|
||||||
|
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/socket.c
|
||||||
|
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
|
||||||
|
${OPENAIR_DIR}/common/utils/utils.c
|
||||||
|
${OPENAIR_DIR}/common/utils/system.c
|
||||||
|
${GTPU_need_ITTI}
|
||||||
|
${XFORMSINTERFACE_SOURCE}
|
||||||
|
${T_SOURCE}
|
||||||
|
${CONFIG_SOURCES}
|
||||||
|
${SHLIB_LOADER_SOURCES}
|
||||||
|
)
|
||||||
|
add_dependencies(ocp-enb rrc_flag s1ap_flag x2_flag oai_iqplayer)
|
||||||
|
|
||||||
|
target_link_libraries (ocp-enb
|
||||||
|
-Wl,--start-group
|
||||||
|
RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB
|
||||||
|
PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7
|
||||||
|
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB}
|
||||||
|
-Wl,--end-group z dl)
|
||||||
|
target_link_libraries (ocp-enb ${LIBXML2_LIBRARIES} pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${LIB_LMS_LIBRARIES} ${T_LIB})
|
||||||
|
|
||||||
add_executable(cu_test
|
add_executable(cu_test
|
||||||
${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/cu_test.c
|
${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/cu_test.c
|
||||||
${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_handler.c
|
${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_handler.c
|
||||||
@@ -2859,6 +2909,7 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr
|
|||||||
|
|
||||||
add_executable(${myExe}
|
add_executable(${myExe}
|
||||||
${OPENAIR1_DIR}/SIMULATION/LTE_PHY/${myExe}.c
|
${OPENAIR1_DIR}/SIMULATION/LTE_PHY/${myExe}.c
|
||||||
|
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||||
${OPENAIR_DIR}/common/utils/backtrace.c
|
${OPENAIR_DIR}/common/utils/backtrace.c
|
||||||
${OPENAIR_DIR}/common/utils/system.c
|
${OPENAIR_DIR}/common/utils/system.c
|
||||||
${XFORMS_SOURCE}
|
${XFORMS_SOURCE}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ set(CMAKE_C_FLAGS
|
|||||||
|
|
||||||
set(OPENAIR_DIR $ENV{OPENAIR_DIR})
|
set(OPENAIR_DIR $ENV{OPENAIR_DIR})
|
||||||
set(OPENAIR3_DIR $ENV{OPENAIR_DIR}/openair3)
|
set(OPENAIR3_DIR $ENV{OPENAIR_DIR}/openair3)
|
||||||
|
include_directories (${OPENAIR_DIR}/openair2/COMMON)
|
||||||
|
|
||||||
set(CONF2UEDATA_LIB_SRC
|
set(CONF2UEDATA_LIB_SRC
|
||||||
${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_emm.c
|
${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_emm.c
|
||||||
|
|||||||
@@ -1,13 +1,19 @@
|
|||||||
cmake_minimum_required(VERSION 2.8)
|
cmake_minimum_required(VERSION 2.8)
|
||||||
set(PACKAGE_NAME "unitary_tests_simulators")
|
set ( CMAKE_BUILD_TYPE )
|
||||||
set(PHYSIM True)
|
set ( CFLAGS_PROCESSOR_USER "" )
|
||||||
set(RF_BOARD None)
|
set ( UE_EXPANSION False )
|
||||||
set(XFORMS True)
|
set ( PRE_SCD_THREAD False )
|
||||||
set(ENABLE_ITTI True)
|
set ( UESIM_EXPANSION False )
|
||||||
set(DEBUG_PHY False)
|
set ( ENABLE_VCD_FIFO False )
|
||||||
set(MU_RECIEVER False)
|
set ( RF_BOARD "OAI_USRP")
|
||||||
set(NAS_UE False)
|
set ( TRANSP_PRO "None")
|
||||||
set(MESSAGE_CHART_GENERATOR False)
|
set ( PACKAGE_NAME "")
|
||||||
set(RRC_ASN1_VERSION "Rel15")
|
set ( DEADLINE_SCHEDULER "False" )
|
||||||
|
set ( CPU_AFFINITY "False" )
|
||||||
set ( T_TRACER True )
|
set ( T_TRACER True )
|
||||||
|
set ( UE_AUTOTEST_TRACE False )
|
||||||
|
set ( UE_DEBUG_TRACE False )
|
||||||
|
set ( UE_TIMING_TRACE False )
|
||||||
|
set ( USRP_REC_PLAY False )
|
||||||
|
set ( SKIP_SHARED_LIB_FLAG False )
|
||||||
include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)
|
include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# use UP and DOWN arrow keys to scroll the view displayed by timeplot
|
||||||
|
|
||||||
|
while read -n 1 key
|
||||||
|
do
|
||||||
|
case "$key" in
|
||||||
|
'B' )
|
||||||
|
kill -SIGUSR1 `ps aux|grep timeplot|grep -v grep|grep -v sh|tr -s ' ' :|cut -f 2 -d :`
|
||||||
|
;;
|
||||||
|
'A' )
|
||||||
|
kill -SIGUSR2 `ps aux|grep timeplot|grep -v grep|grep -v sh|tr -s ' ' :|cut -f 2 -d :`
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
@@ -13,7 +13,8 @@ void usage(void)
|
|||||||
"options:\n"
|
"options:\n"
|
||||||
" -d <database file> this option is mandatory\n"
|
" -d <database file> this option is mandatory\n"
|
||||||
" -ip <host> connect to given IP address (default %s)\n"
|
" -ip <host> connect to given IP address (default %s)\n"
|
||||||
" -p <port> connect to given port (default %d)\n",
|
" -p <port> connect to given port (default %d)\n"
|
||||||
|
" -e <event> event to trace (default VCD_FUNCTION_ENB_DLSCH_ULSCH_SCHEDULER)\n",
|
||||||
DEFAULT_REMOTE_IP,
|
DEFAULT_REMOTE_IP,
|
||||||
DEFAULT_REMOTE_PORT
|
DEFAULT_REMOTE_PORT
|
||||||
);
|
);
|
||||||
@@ -47,6 +48,7 @@ int main(int n, char **v)
|
|||||||
int ev_fun;
|
int ev_fun;
|
||||||
int start_valid = 0;
|
int start_valid = 0;
|
||||||
struct timespec start_time, stop_time, delta_time;
|
struct timespec start_time, stop_time, delta_time;
|
||||||
|
char *name = "VCD_FUNCTION_ENB_DLSCH_ULSCH_SCHEDULER";
|
||||||
|
|
||||||
for (i = 1; i < n; i++) {
|
for (i = 1; i < n; i++) {
|
||||||
if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage();
|
if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage();
|
||||||
@@ -55,6 +57,7 @@ int main(int n, char **v)
|
|||||||
if (!strcmp(v[i], "-ip")) { if (i > n-2) usage(); ip = v[++i]; continue; }
|
if (!strcmp(v[i], "-ip")) { if (i > n-2) usage(); ip = v[++i]; continue; }
|
||||||
if (!strcmp(v[i], "-p"))
|
if (!strcmp(v[i], "-p"))
|
||||||
{ if (i > n-2) usage(); port = atoi(v[++i]); continue; }
|
{ if (i > n-2) usage(); port = atoi(v[++i]); continue; }
|
||||||
|
if (!strcmp(v[i], "-e")) { if (i > n-2) usage(); name = v[++i]; continue; }
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,10 +74,9 @@ int main(int n, char **v)
|
|||||||
is_on = calloc(number_of_events, sizeof(int));
|
is_on = calloc(number_of_events, sizeof(int));
|
||||||
if (is_on == NULL) abort();
|
if (is_on == NULL) abort();
|
||||||
|
|
||||||
on_off(database, "VCD_FUNCTION_ENB_DLSCH_ULSCH_SCHEDULER", is_on, 1);
|
on_off(database, name, is_on, 1);
|
||||||
|
|
||||||
ev_fun = event_id_from_name(database,
|
ev_fun = event_id_from_name(database, name);
|
||||||
"VCD_FUNCTION_ENB_DLSCH_ULSCH_SCHEDULER");
|
|
||||||
|
|
||||||
socket = connect_to(ip, port);
|
socket = connect_to(ip, port);
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ int bins[50];
|
|||||||
|
|
||||||
#define N 1000
|
#define N 1000
|
||||||
int data[N];
|
int data[N];
|
||||||
|
long start = 100;
|
||||||
|
|
||||||
void plot(void)
|
void plot(void)
|
||||||
{
|
{
|
||||||
@@ -45,7 +46,8 @@ void plot(void)
|
|||||||
if (data[i] < vmin) vmin = data[i];
|
if (data[i] < vmin) vmin = data[i];
|
||||||
if (data[i] > vmax) vmax = data[i];
|
if (data[i] > vmax) vmax = data[i];
|
||||||
vavg += data[i];
|
vavg += data[i];
|
||||||
int ms2 = data[i]/binsize_ns;
|
int ms2 = (data[i] - start * 1000)/binsize_ns;
|
||||||
|
if (ms2 < 0) ms2 = 0;
|
||||||
if (ms2 > 49) ms2 = 49;
|
if (ms2 > 49) ms2 = 49;
|
||||||
bins[ms2]++;
|
bins[ms2]++;
|
||||||
if (bins[ms2] > max) max = bins[ms2];
|
if (bins[ms2] > max) max = bins[ms2];
|
||||||
@@ -55,7 +57,7 @@ void plot(void)
|
|||||||
|
|
||||||
GOTO(1,1);
|
GOTO(1,1);
|
||||||
for (i = 0; i < 50; i++) {
|
for (i = 0; i < 50; i++) {
|
||||||
double binend = (i+1) * binsize_ns / 1000.;
|
double binend = (i+1) * binsize_ns / 1000. + start;
|
||||||
int k;
|
int k;
|
||||||
int width = bins[i] * 70 / max;
|
int width = bins[i] * 70 / max;
|
||||||
/* force at least width of 1 if some point is there */
|
/* force at least width of 1 if some point is there */
|
||||||
@@ -68,11 +70,23 @@ void plot(void)
|
|||||||
printf("min %d ns max %d ns avg %ld ns\n", vmin, vmax, vavg);
|
printf("min %d ns max %d ns avg %ld ns\n", vmin, vmax, vavg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void up(int x)
|
||||||
|
{
|
||||||
|
start += 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
void down(int x)
|
||||||
|
{
|
||||||
|
start -= 5;
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
signal(SIGINT, sig);
|
signal(SIGINT, sig);
|
||||||
|
signal(SIGUSR1, up);
|
||||||
|
signal(SIGUSR2, down);
|
||||||
RESET();
|
RESET();
|
||||||
HIDE_CURSOR();
|
HIDE_CURSOR();
|
||||||
while (!feof(stdin)) {
|
while (!feof(stdin)) {
|
||||||
|
|||||||
@@ -1,12 +1,32 @@
|
|||||||
/*
|
/*
|
||||||
Author: Laurent THOMAS, Open Cells
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||||
copyleft: OpenAirInterface Software Alliance and it's licence
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||||
|
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||||
|
* except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.openairinterface.org/?page_id=698
|
||||||
|
*
|
||||||
|
* Author and copyright: Laurent Thomas, open-cells.com
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*-------------------------------------------------------------------------------
|
||||||
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||||
|
* contact@openairinterface.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <sys/eventfd.h>
|
#include <sys/eventfd.h>
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
#include <intertask_interface.h>
|
#include <intertask_interface.h>
|
||||||
#include <common/utils/system.h>
|
#include <common/utils/system.h>
|
||||||
|
|
||||||
@@ -35,7 +55,6 @@ typedef struct task_list_s {
|
|||||||
int timer_expired(int fd);
|
int timer_expired(int fd);
|
||||||
task_list_t tasks[TASK_MAX];
|
task_list_t tasks[TASK_MAX];
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
void *pool_buffer_init (void) {
|
void *pool_buffer_init (void) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -86,6 +105,9 @@ extern "C" {
|
|||||||
temp->ittiMsgHeader.messageId = message_id;
|
temp->ittiMsgHeader.messageId = message_id;
|
||||||
temp->ittiMsgHeader.originTaskId = origin_task_id;
|
temp->ittiMsgHeader.originTaskId = origin_task_id;
|
||||||
temp->ittiMsgHeader.ittiMsgSize = size;
|
temp->ittiMsgHeader.ittiMsgSize = size;
|
||||||
|
temp->ittiMsgHeader.destinationTaskId=TASK_UNKNOWN;
|
||||||
|
temp->ittiMsgHeader.instance=0;
|
||||||
|
temp->ittiMsgHeader.lte_time={0};
|
||||||
return temp;
|
return temp;
|
||||||
//return itti_alloc_new_message_sized(origin_task_id, message_id, messages_info[message_id].size);
|
//return itti_alloc_new_message_sized(origin_task_id, message_id, messages_info[message_id].size);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,26 @@
|
|||||||
/*
|
/*
|
||||||
Author: Laurent THOMAS, Open Cells
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||||
Copyleft: OpenAirInterface software alliance and it's license
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||||
|
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||||
|
* except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.openairinterface.org/?page_id=698
|
||||||
|
*
|
||||||
|
* Author and copyright: Laurent Thomas, open-cells.com
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*-------------------------------------------------------------------------------
|
||||||
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||||
|
* contact@openairinterface.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef INTERTASK_INTERFACE_H_
|
#ifndef INTERTASK_INTERFACE_H_
|
||||||
#define INTERTASK_INTERFACE_H_
|
#define INTERTASK_INTERFACE_H_
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@@ -275,7 +294,7 @@ typedef struct {
|
|||||||
//TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200, NULL, NULL)
|
//TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200, NULL, NULL)
|
||||||
//TASK_DEF(TASK_GTPV1_U, TASK_PRIORITY_MED, 1000,NULL, NULL)
|
//TASK_DEF(TASK_GTPV1_U, TASK_PRIORITY_MED, 1000,NULL, NULL)
|
||||||
//TASK_DEF(TASK_UDP, TASK_PRIORITY_MED, 1000, NULL, NULL)
|
//TASK_DEF(TASK_UDP, TASK_PRIORITY_MED, 1000, NULL, NULL)
|
||||||
|
void * rrc_enb_process_msg(void*);
|
||||||
#define FOREACH_TASK(TASK_DEF) \
|
#define FOREACH_TASK(TASK_DEF) \
|
||||||
TASK_DEF(TASK_UNKNOWN, TASK_PRIORITY_MED, 50, NULL, NULL) \
|
TASK_DEF(TASK_UNKNOWN, TASK_PRIORITY_MED, 50, NULL, NULL) \
|
||||||
TASK_DEF(TASK_TIMER, TASK_PRIORITY_MED, 10, NULL, NULL) \
|
TASK_DEF(TASK_TIMER, TASK_PRIORITY_MED, 10, NULL, NULL) \
|
||||||
|
|||||||
@@ -243,6 +243,8 @@ void configure_linux(void) {
|
|||||||
|
|
||||||
// Set CPU frequency to it's maximum
|
// Set CPU frequency to it's maximum
|
||||||
if ( 0 != system("for d in /sys/devices/system/cpu/cpu[0-9]*; do cat $d/cpufreq/cpuinfo_max_freq > $d/cpufreq/scaling_min_freq; done"))
|
if ( 0 != system("for d in /sys/devices/system/cpu/cpu[0-9]*; do cat $d/cpufreq/cpuinfo_max_freq > $d/cpufreq/scaling_min_freq; done"))
|
||||||
LOG_W(HW,"Can't set cpu frequency\n");
|
LOG_E(HW,"Can't set cpu frequency\n");
|
||||||
|
|
||||||
|
mlockall(MCL_CURRENT | MCL_FUTURE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,26 @@
|
|||||||
/*
|
/*
|
||||||
Author: Laurent THOMAS, Open Cells
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||||
copyleft: OpenAirInterface Software Alliance and it's licence
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||||
|
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||||
|
* except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.openairinterface.org/?page_id=698
|
||||||
|
*
|
||||||
|
* Author and copyright: Laurent Thomas, open-cells.com
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*-------------------------------------------------------------------------------
|
||||||
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||||
|
* contact@openairinterface.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <common/utils/simple_executable.h>
|
#include <common/utils/simple_executable.h>
|
||||||
|
|
||||||
#include "thread-pool.h"
|
#include "thread-pool.h"
|
||||||
|
|||||||
@@ -1,8 +1,27 @@
|
|||||||
/*
|
/*
|
||||||
Author: Laurent THOMAS, Open Cells
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||||
copyleft: OpenAirInterface Software Alliance and it's licence
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||||
|
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||||
|
* except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.openairinterface.org/?page_id=698
|
||||||
|
*
|
||||||
|
* Author and copyright: Laurent Thomas, open-cells.com
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*-------------------------------------------------------------------------------
|
||||||
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||||
|
* contact@openairinterface.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|||||||
@@ -1,8 +1,27 @@
|
|||||||
/*
|
/*
|
||||||
Author: Laurent THOMAS, Open Cells
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||||
copyleft: OpenAirInterface Software Alliance and it's licence
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||||
|
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||||
|
* except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.openairinterface.org/?page_id=698
|
||||||
|
*
|
||||||
|
* Author and copyright: Laurent Thomas, open-cells.com
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*-------------------------------------------------------------------------------
|
||||||
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||||
|
* contact@openairinterface.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef THREAD_POOL_H
|
#ifndef THREAD_POOL_H
|
||||||
#define THREAD_POOL_H
|
#define THREAD_POOL_H
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
@@ -217,11 +236,11 @@ static inline void pushTpool(tpool_t *t, notifiedFIFO_elt_t *msg) {
|
|||||||
|
|
||||||
static inline notifiedFIFO_elt_t *pullTpool(notifiedFIFO_t *responseFifo, tpool_t *t) {
|
static inline notifiedFIFO_elt_t *pullTpool(notifiedFIFO_t *responseFifo, tpool_t *t) {
|
||||||
notifiedFIFO_elt_t *msg= pullNotifiedFIFO(responseFifo);
|
notifiedFIFO_elt_t *msg= pullNotifiedFIFO(responseFifo);
|
||||||
|
AssertFatal(t->traceFd, "Thread pool used while not initialized");
|
||||||
if (t->measurePerf)
|
if (t->measurePerf)
|
||||||
msg->returnTime=rdtsc();
|
msg->returnTime=rdtsc();
|
||||||
|
|
||||||
if (t->traceFd >= 0)
|
if (t->traceFd > 0)
|
||||||
if(write(t->traceFd, msg, sizeof(*msg)));
|
if(write(t->traceFd, msg, sizeof(*msg)));
|
||||||
|
|
||||||
return msg;
|
return msg;
|
||||||
@@ -229,7 +248,7 @@ static inline notifiedFIFO_elt_t *pullTpool(notifiedFIFO_t *responseFifo, tpool_
|
|||||||
|
|
||||||
static inline notifiedFIFO_elt_t *tryPullTpool(notifiedFIFO_t *responseFifo, tpool_t *t) {
|
static inline notifiedFIFO_elt_t *tryPullTpool(notifiedFIFO_t *responseFifo, tpool_t *t) {
|
||||||
notifiedFIFO_elt_t *msg= pollNotifiedFIFO(responseFifo);
|
notifiedFIFO_elt_t *msg= pollNotifiedFIFO(responseFifo);
|
||||||
|
AssertFatal(t->traceFd, "Thread pool used while not initialized");
|
||||||
if (msg == NULL)
|
if (msg == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|||||||
+12
-7
@@ -14,19 +14,24 @@
|
|||||||
|
|
||||||
This simulator allows to test L2 and above Layers using the nFAPI interface.
|
This simulator allows to test L2 and above Layers using the nFAPI interface.
|
||||||
|
|
||||||
|
The UE executable is able to "simulate" multiple UEs in order to stimulate the scheduler in the eNB.
|
||||||
|
|
||||||
**This simulator is available starting the `v1.0.0` release on the `master` branch.**
|
**This simulator is available starting the `v1.0.0` release on the `master` branch.**
|
||||||
|
|
||||||
Currently the only validated deployment by CI and developers is *with S1 interface and eNB / UEs are on the same machine*.
|
Currently the Continuous Integration process is validating this simulator the following way:
|
||||||
|
|
||||||
Others deployments will be supported later after bug fixes and validation in the CI process.
|
|
||||||
|
|
||||||
1. [With S1 -- eNB and UE on same machine](L2NFAPI_S1.md)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* the LTE modem executable is run on one host (in our CI deployment it is a **Xenial Virtual Machine**)
|
||||||
|
* the UE(s) modem executable is run on another host (in our CI deployment it is also a **Xenial Virtual Machine**)
|
||||||
|
* We are testing:
|
||||||
|
* in S1 mode (ie we are connected to a 3rd-party EPC)
|
||||||
|
* in noS1 mode (no need for an EPC)
|
||||||
|
|
||||||
|
Normally it should be fine to run both executables on the same host using the `loopback` interface to communicate. **But we are not guaranting it**
|
||||||
|
|
||||||
|
1. [With S1 -- eNB and UE on 2 hosts](L2NFAPI_S1.md)
|
||||||
|
2. [No S1 -- eNB and UE on 2 hosts](L2NFAPI_NOS1.md)
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
[oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
|
[oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,349 @@
|
|||||||
|
<table style="border-collapse: collapse; border: none;">
|
||||||
|
<tr style="border-collapse: collapse; border: none;">
|
||||||
|
<td style="border-collapse: collapse; border: none;">
|
||||||
|
<a href="http://www.openairinterface.org/">
|
||||||
|
<img src="./images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||||
|
</img>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td style="border-collapse: collapse; border: none; vertical-align: center;">
|
||||||
|
<b><font size = "5">L2 nFAPI Simulator (no S1 Mode / 2-host deployment)</font></b>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
## Table of Contents ##
|
||||||
|
|
||||||
|
1. [Environment](#1-environment)
|
||||||
|
2. [Retrieve the OAI eNB-UE source code](#2-retrieve-the-oai-enb-ue-source-code)
|
||||||
|
3. [Setup of the USIM information in UE folder](#3-setup-of-the-usim-information-in-ue-folder)
|
||||||
|
4. [Setup of the Configuration files](#4-setup-of-the-configuration-files)
|
||||||
|
1. [The eNB Configuration file](#41-the-enb-configuration-file)
|
||||||
|
2. [The UE Configuration file](#42-the-ue-configuration-file)
|
||||||
|
5. [Build OAI UE and eNodeB](#5-build-oai-ue-and-enodeb)
|
||||||
|
6. [Start the eNB](#6-start-the-enb)
|
||||||
|
7. [Start the UE](#7-start-the-ue)
|
||||||
|
8. [Test with ping](#8-test-with-ping)
|
||||||
|
9. [Limitations](#9-limitations)
|
||||||
|
|
||||||
|
# 1. Environment #
|
||||||
|
|
||||||
|
You may not have access to an EPC or you don't want to hassle to deploy one.
|
||||||
|
|
||||||
|
2 servers are used in this deployment. You can use Virtual Machines instead of each server; like it is done in the CI process.
|
||||||
|
|
||||||
|
* Machine B contains the OAI eNB executable (`lte-softmodem`)
|
||||||
|
* Machine C contains the OAI UE(s) executable (`lte-uesoftmodem`)
|
||||||
|
|
||||||
|
Example of L2 nFAPI Simulator testing environment:
|
||||||
|
|
||||||
|
<img src="./images/L2-sim-noS1-2-host-deployment.png" alt="" border=3>
|
||||||
|
|
||||||
|
Note that the IP addresses are indicative and need to be adapted to your environment.
|
||||||
|
|
||||||
|
# 2. Retrieve the OAI eNB-UE source code #
|
||||||
|
|
||||||
|
At the time of writing, the tag used in the `develop` branch to do this documentation was `2020.w16`.
|
||||||
|
|
||||||
|
The tutorial should be valid for the `master` branch tags such as `v1.2.0` or `v1.2.1`. But you may face issues that could be fixed in newer `develop` tags.
|
||||||
|
|
||||||
|
Please try to use the same commit ID on both eNB/UE hosts.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ssh sudousername@machineB
|
||||||
|
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git enb_folder
|
||||||
|
cd enb_folder
|
||||||
|
git checkout develop
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ssh sudousername@machineC
|
||||||
|
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git ue_folder
|
||||||
|
cd ue_folder
|
||||||
|
git checkout develop
|
||||||
|
```
|
||||||
|
|
||||||
|
# 3. Setup of the USIM information in UE folder #
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ssh sudousername@machineC
|
||||||
|
cd ue_folder
|
||||||
|
# Edit openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf with your preferred editor
|
||||||
|
```
|
||||||
|
|
||||||
|
Edit the USIM information within this file in order to match the HSS database. They **HAVE TO** match:
|
||||||
|
|
||||||
|
* PLMN+MSIN and IMSI of users table of HSS database **SHALL** be the same.
|
||||||
|
* OPC of this file and OPC of users table of HSS database **SHALL** be the same.
|
||||||
|
* USIM_API_K of this file and the key of users table of HSS database **SHALL** be the same.
|
||||||
|
|
||||||
|
When testing multiple UEs, it is necessary to add other UEs information like described below for 2 Users. Only UE0 (first UE) information is written in the original file.
|
||||||
|
|
||||||
|
```
|
||||||
|
UE0:
|
||||||
|
{
|
||||||
|
USER: {
|
||||||
|
IMEI="356113022094149";
|
||||||
|
MANUFACTURER="EURECOM";
|
||||||
|
MODEL="LTE Android PC";
|
||||||
|
PIN="0000";
|
||||||
|
};
|
||||||
|
|
||||||
|
SIM: {
|
||||||
|
MSIN="0000000001"; // <-- Modify here
|
||||||
|
USIM_API_K="8baf473f2f8fd09487cccbd7097c6862";
|
||||||
|
OPC="e734f8734007d6c5ce7a0508809e7e9c";
|
||||||
|
MSISDN="33611123456";
|
||||||
|
};
|
||||||
|
...
|
||||||
|
};
|
||||||
|
// Copy the UE0 and edit
|
||||||
|
UE1: // <- Edit here
|
||||||
|
{
|
||||||
|
USER: {
|
||||||
|
IMEI="356113022094149";
|
||||||
|
MANUFACTURER="EURECOM";
|
||||||
|
MODEL="LTE Android PC";
|
||||||
|
PIN="0000";
|
||||||
|
};
|
||||||
|
|
||||||
|
SIM: {
|
||||||
|
MSIN="0000000002"; // <-- Modify here
|
||||||
|
USIM_API_K="8baf473f2f8fd09487cccbd7097c6862";
|
||||||
|
OPC="e734f8734007d6c5ce7a0508809e7e9c";
|
||||||
|
MSISDN="33611123456";
|
||||||
|
};
|
||||||
|
...
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
You can repeat the operation for as many users you want to test with.
|
||||||
|
|
||||||
|
# 4. Setup of the Configuration files #
|
||||||
|
|
||||||
|
**CAUTION: both proposed configuration files resides in the ci-scripts realm. You can copy them but you CANNOT push any modification on these 2 files as part of an MR without informing the CI team.**
|
||||||
|
|
||||||
|
## 4.1. The eNB Configuration file ##
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ssh sudousername@machineB
|
||||||
|
cd enb_folder
|
||||||
|
# Edit ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf with your preferred editor
|
||||||
|
```
|
||||||
|
|
||||||
|
First verify the nFAPI interface setup on the physical ethernet interface of machineB and put the proper IP addresses for both hosts.
|
||||||
|
|
||||||
|
```
|
||||||
|
MACRLCs = (
|
||||||
|
{
|
||||||
|
num_cc = 1;
|
||||||
|
local_s_if_name = "ens3"; // <-- HERE
|
||||||
|
remote_s_address = "192.168.122.169"; // <-- HERE
|
||||||
|
local_s_address = "192.168.122.31"; // <-- HERE
|
||||||
|
local_s_portc = 50001;
|
||||||
|
remote_s_portc = 50000;
|
||||||
|
local_s_portd = 50011;
|
||||||
|
remote_s_portd = 50010;
|
||||||
|
tr_s_preference = "nfapi";
|
||||||
|
tr_n_preference = "local_RRC";
|
||||||
|
}
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
If you are testing more than 16 UEs, a proper setting on the RUs is necessary. **Note that this part is NOT present in the original configuration file**.
|
||||||
|
|
||||||
|
```
|
||||||
|
RUs = (
|
||||||
|
{
|
||||||
|
local_rf = "yes"
|
||||||
|
nb_tx = 1
|
||||||
|
nb_rx = 1
|
||||||
|
att_tx = 20
|
||||||
|
att_rx = 0;
|
||||||
|
bands = [38];
|
||||||
|
max_pdschReferenceSignalPower = -23;
|
||||||
|
max_rxgain = 116;
|
||||||
|
eNB_instances = [0];
|
||||||
|
}
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
Last, the S1 interface shall be properly set.
|
||||||
|
|
||||||
|
```
|
||||||
|
////////// MME parameters:
|
||||||
|
mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; // replace with 192.168.122.195
|
||||||
|
ipv6 = "192:168:30::17";
|
||||||
|
active = "yes";
|
||||||
|
preference = "ipv4";
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
NETWORK_INTERFACES :
|
||||||
|
{
|
||||||
|
ENB_INTERFACE_NAME_FOR_S1_MME = "ens3"; // replace with the proper interface name
|
||||||
|
ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; // replace with 192.168.122.31
|
||||||
|
ENB_INTERFACE_NAME_FOR_S1U = "ens3"; // replace with the proper interface name
|
||||||
|
ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; // replace with 192.168.122.31
|
||||||
|
ENB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||||
|
ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; // replace with 192.168.122.31
|
||||||
|
ENB_PORT_FOR_X2C = 36422; # Spec 36422
|
||||||
|
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4.2. The UE Configuration file ##
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ssh sudousername@machineB
|
||||||
|
cd ue_folder
|
||||||
|
# Edit ci-scripts/conf_files/ue.nfapi.conf with your preferred editor
|
||||||
|
```
|
||||||
|
|
||||||
|
Verify the nFAPI interface setup on the loopback interface.
|
||||||
|
|
||||||
|
```
|
||||||
|
L1s = (
|
||||||
|
{
|
||||||
|
num_cc = 1;
|
||||||
|
tr_n_preference = "nfapi";
|
||||||
|
local_n_if_name = "ens3"; // <- HERE
|
||||||
|
remote_n_address = "192.168.122.31"; // <- HERE
|
||||||
|
local_n_address = "192.168.122.169"; // <- HERE
|
||||||
|
local_n_portc = 50000;
|
||||||
|
remote_n_portc = 50001;
|
||||||
|
local_n_portd = 50010;
|
||||||
|
remote_n_portd = 50011;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
# 5. Build OAI UE and eNodeB #
|
||||||
|
|
||||||
|
See [Build documentation](./BUILD.md).
|
||||||
|
|
||||||
|
# 6. Start the eNB #
|
||||||
|
|
||||||
|
In the first terminal (the one you used to build the eNB):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ssh sudousername@machineB
|
||||||
|
cd enb_folder/cmake_targets
|
||||||
|
sudo -E ./ran_build/build/lte-softmodem -O ../ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf --noS1 > enb.log 2>&1
|
||||||
|
sleep 10
|
||||||
|
ifconfig
|
||||||
|
ens3 Link encap:Ethernet HWaddr XX:XX:XX:XX:XX:XX
|
||||||
|
inet addr:192.168.122.31 Bcast:192.168.122.255 Mask:255.255.255.0
|
||||||
|
....
|
||||||
|
oaitun_enb1 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
|
||||||
|
inet addr:10.0.1.1 P-t-P:192.172.0.2 Mask:255.255.255.0
|
||||||
|
....
|
||||||
|
```
|
||||||
|
|
||||||
|
If you don't use redirection, you can test but many logs are printed on the console and this may affect performance of the L2-nFAPI simulator.
|
||||||
|
|
||||||
|
We do recommend the redirection in steady mode once your setup is correct.
|
||||||
|
|
||||||
|
# 7. Start the UE #
|
||||||
|
|
||||||
|
In the second terminal (the one you used to build the UE):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ssh sudousername@machineC
|
||||||
|
cd ue_folder/cmake_targets
|
||||||
|
# Test 64 UEs, 1 thread in FDD mode
|
||||||
|
sudo -E ./ran_build/build/lte-uesoftmodem -O ../ci-scripts/conf_files/ue.nfapi.conf --noS1 --L2-emul 3 --num-ues 64 --nums_ue_thread 1 --nokrnmod 1 > ue.log 2>&1
|
||||||
|
# Test 64 UEs, 1 thread in TDD mode
|
||||||
|
sudo -E ./ran_build/build/lte-uesoftmodem -O ../ci-scripts/conf_files/ue.nfapi.conf --noS1 --L2-emul 3 --num-ues 64 --nums_ue_thread 1 --nokrnmod 1 -T 1 > ue.log 2>&1
|
||||||
|
# The "-T 1" option means TDD config
|
||||||
|
```
|
||||||
|
|
||||||
|
- The number of UEs can set by using `--num-ues` option and the maximum UE number is 255 (with the `--mu*` options, otherwise 16).
|
||||||
|
- The number of threads can set with the `--nums-ue-thread`. This number **SHALL NOT** be greater than the number of UEs.
|
||||||
|
* At the time of writing, it seems to be enough to run on a single thread.
|
||||||
|
- The `--nokrnmod 1` option makes use of the preferred and supported tunnel interface.
|
||||||
|
- How many UE that can be tested depends on hardware (server , PC, etc) performance in your environment.
|
||||||
|
|
||||||
|
For example, running with 4 UEs:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ssh sudousername@machineC
|
||||||
|
cd ue_folder/cmake_targets
|
||||||
|
sudo -E ./ran_build/build/lte-uesoftmodem -O ../ci-scripts/conf_files/ue.nfapi.conf --noS1 --L2-emul 3 --num-ues 64 --nums_ue_thread 1 --nokrnmod 1 > ue.log 2>&1
|
||||||
|
sleep 10
|
||||||
|
ifconfig
|
||||||
|
ens3 Link encap:Ethernet HWaddr XX:XX:XX:XX:XX:XX
|
||||||
|
inet addr:192.168.122.169 Bcast:192.168.122.255 Mask:255.255.255.0
|
||||||
|
....
|
||||||
|
oaitun_ue1 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
|
||||||
|
inet addr:10.0.1.2 P-t-P:192.172.0.2 Mask:255.255.255.0
|
||||||
|
....
|
||||||
|
oaitun_ue2 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
|
||||||
|
inet addr:10.0.1.3 P-t-P:192.172.0.3 Mask:255.255.255.0
|
||||||
|
....
|
||||||
|
oaitun_ue3 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
|
||||||
|
inet addr:10.0.1.4 P-t-P:192.172.0.4 Mask:255.255.255.0
|
||||||
|
....
|
||||||
|
oaitun_ue4 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
|
||||||
|
inet addr:10.0.1.5 P-t-P:192.172.0.5 Mask:255.255.255.0
|
||||||
|
....
|
||||||
|
oaitun_uem1 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
|
||||||
|
inet addr:10.0.2.2 P-t-P:10.0.2.2 Mask:255.255.255.0
|
||||||
|
....
|
||||||
|
....
|
||||||
|
```
|
||||||
|
|
||||||
|
Having the 4 oaitun_ue tunnel interfaces up and with an allocated address means the connection with EPC went alright.
|
||||||
|
|
||||||
|
# 8. Test with ping #
|
||||||
|
|
||||||
|
In a third terminal, after around 10 seconds, the UE(s) shall be connected to the eNB: Check with ifconfig
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ssh sudousername@machineB
|
||||||
|
# Ping UE1 IP address based on the EPC pool used: in this example:
|
||||||
|
ping -I oaitun_enb1 -c 20 10.0.1.2
|
||||||
|
# Ping UE4 IP address based on the EPC pool used: in this example:
|
||||||
|
ping -I oaitun_enb1 -c 20 10.0.1.5
|
||||||
|
```
|
||||||
|
|
||||||
|
Ping from the UE side:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ssh sudousername@machineC
|
||||||
|
ping -I oaitun_ue1 -c 20 10.0.1.1
|
||||||
|
ping -I oaitun_ue3 -c 20 10.0.1.1
|
||||||
|
```
|
||||||
|
|
||||||
|
iperf operations can also be performed.
|
||||||
|
|
||||||
|
DL traffic:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ssh sudousername@machineC
|
||||||
|
iperf -B 10.0.1.2 -u -s -i 1 -fm -p 5002
|
||||||
|
$ ssh sudousername@machineB
|
||||||
|
iperf -c 10.0.1.2 -u -t 30 -b 3M -i 1 -fm -B 10.0.1.1 -p 5002
|
||||||
|
```
|
||||||
|
|
||||||
|
UL traffic:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ssh sudousername@machineB
|
||||||
|
iperf -B 10.0.1.1 -u -s -i 1 -fm -p 5002
|
||||||
|
$ ssh sudousername@machineC
|
||||||
|
iperf -c 10.0.1.1 -u -t 30 -b 2M -i 1 -fm -B 10.0.1.2 -p 5002
|
||||||
|
```
|
||||||
|
|
||||||
|
# 9. Limitations #
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
[oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
|
||||||
|
|
||||||
|
[oai softmodem features](FEATURE_SET.md)
|
||||||
|
|
||||||
|
[oai softmodem build procedure](BUILD.md)
|
||||||
|
|
||||||
|
[L2 nfapi simulator](L2NFAPI.md)
|
||||||
+97
-70
@@ -7,7 +7,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td style="border-collapse: collapse; border: none; vertical-align: center;">
|
<td style="border-collapse: collapse; border: none; vertical-align: center;">
|
||||||
<b><font size = "5">L2 nFAPI Simulator (with S1 / same machine deployment)</font></b>
|
<b><font size = "5">L2 nFAPI Simulator (with S1 / 2-host deployment)</font></b>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@@ -21,25 +21,24 @@
|
|||||||
5. [Setup of the Configuration files](#5-setup-of-the-configuration-files)
|
5. [Setup of the Configuration files](#5-setup-of-the-configuration-files)
|
||||||
1. [The eNB Configuration file](#51-the-enb-configuration-file)
|
1. [The eNB Configuration file](#51-the-enb-configuration-file)
|
||||||
2. [The UE Configuration file](#52-the-ue-configuration-file)
|
2. [The UE Configuration file](#52-the-ue-configuration-file)
|
||||||
6. [Bring Up a second loopback interface](#6-bring-up-a-second-loopback-interface)
|
6. [Build OAI UE and eNodeB](#6-build-oai-ue-and-enodeb)
|
||||||
7. [Build the eNB](#7-build-the-enb)
|
7. [Start EPC](#7-start-epc)
|
||||||
8. [Build the UE](#8-build-the-ue)
|
8. [Start the eNB](#8-start-the-enb)
|
||||||
9. [Initialize the NAS UE Layer](#9-initialize-the-nas-ue-layer)
|
9. [Start the UE](#9-start-the-ue)
|
||||||
10. [Start the eNB](#10-start-the-enb)
|
10. [Test with ping](#10-test-with-ping)
|
||||||
11. [Start the UE](#11-start-the-ue)
|
11. [Limitations](#11-limitations)
|
||||||
12. [Test with ping](#12-test-with-ping)
|
|
||||||
13. [Limitations](#13-limitations)
|
|
||||||
|
|
||||||
# 1. Environment #
|
# 1. Environment #
|
||||||
|
|
||||||
2 servers are used in this deployment. You can use Virtual Machines instead of each server; like it is done in the CI process.
|
3 servers are used in this deployment. You can use Virtual Machines instead of each server; like it is done in the CI process.
|
||||||
|
|
||||||
* Machine A contains the EPC.
|
* Machine A contains the EPC.
|
||||||
* Machine B contains the OAI eNB and the OAI UE(s)
|
* Machine B contains the OAI eNB executable (`lte-softmodem`)
|
||||||
|
* Machine C contains the OAI UE(s) executable (`lte-uesoftmodem`)
|
||||||
|
|
||||||
Example of L2 nFAPI Simulator testing environment:
|
Example of L2 nFAPI Simulator testing environment:
|
||||||
|
|
||||||
<img src="../l2-nfapi-simulator/L2-sim-single-server-deployment.png" alt="" border=3>
|
<img src="./images/L2-sim-S1-3-host-deployment.png" alt="" border=3>
|
||||||
|
|
||||||
Note that the IP addresses are indicative and need to be adapted to your environment.
|
Note that the IP addresses are indicative and need to be adapted to your environment.
|
||||||
|
|
||||||
@@ -47,26 +46,35 @@ Note that the IP addresses are indicative and need to be adapted to your environ
|
|||||||
|
|
||||||
Create the environment for the EPC and register all **USIM** information into the **HSS** database.
|
Create the environment for the EPC and register all **USIM** information into the **HSS** database.
|
||||||
|
|
||||||
If you are using OAI-EPC ([see on GitHub](https://github.com/OPENAIRINTERFACE/openair-cn)), build **HSS/MME/SPGW** and create config files.
|
If you are using OAI-EPC ([see on GitHub](https://github.com/OPENAIRINTERFACE/openair-epc-fed)), build **HSS/MME/SPGW** and create config files.
|
||||||
|
|
||||||
# 3. Retrieve the OAI eNB-UE source code #
|
# 3. Retrieve the OAI eNB-UE source code #
|
||||||
|
|
||||||
The eNB and the UE executables will compiled into 2 separate folders on the same machine `B`.
|
At the time of writing, the tag used in the `develop` branch to do this documentation was `2020.w16`.
|
||||||
|
|
||||||
|
The tutorial should be valid for the `master` branch tags such as `v1.2.0` or `v1.2.1`. But you may face issues that could be fixed in newer `develop` tags.
|
||||||
|
|
||||||
|
Please try to use the same commit ID on both eNB/UE hosts.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ ssh sudousername@machineB
|
$ ssh sudousername@machineB
|
||||||
$ git clone https://gitlab.eurecom.fr/oai/openairinterface5g/ enb_folder
|
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git enb_folder
|
||||||
$ cd enb_folder
|
cd enb_folder
|
||||||
$ git checkout -f v1.0.0
|
git checkout develop
|
||||||
$ cd ..
|
```
|
||||||
$ cp -Rf enb_folder ue_folder
|
|
||||||
|
```bash
|
||||||
|
$ ssh sudousername@machineC
|
||||||
|
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git ue_folder
|
||||||
|
cd ue_folder
|
||||||
|
git checkout develop
|
||||||
```
|
```
|
||||||
|
|
||||||
# 4. Setup of the USIM information in UE folder #
|
# 4. Setup of the USIM information in UE folder #
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ ssh sudousername@machineB
|
$ ssh sudousername@machineC
|
||||||
$ cd ue_folder
|
cd ue_folder
|
||||||
# Edit openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf with your preferred editor
|
# Edit openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf with your preferred editor
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -126,19 +134,19 @@ You can repeat the operation for as many users you want to test with.
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ ssh sudousername@machineB
|
$ ssh sudousername@machineB
|
||||||
$ cd enb_folder
|
cd enb_folder
|
||||||
# Edit ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf with your preferred editor
|
# Edit ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf with your preferred editor
|
||||||
```
|
```
|
||||||
|
|
||||||
First verify the nFAPI interface setup on the 2nd loopback interface.
|
First verify the nFAPI interface setup on the physical ethernet interface of machineB and put the proper IP addresses for both hosts.
|
||||||
|
|
||||||
```
|
```
|
||||||
MACRLCs = (
|
MACRLCs = (
|
||||||
{
|
{
|
||||||
num_cc = 1;
|
num_cc = 1;
|
||||||
local_s_if_name = "lo:"; // <-- HERE
|
local_s_if_name = "ens3"; // <-- HERE
|
||||||
remote_s_address = "127.0.0.1"; // <-- HERE
|
remote_s_address = "192.168.122.169"; // <-- HERE
|
||||||
local_s_address = "127.0.0.2"; // <-- HERE
|
local_s_address = "192.168.122.31"; // <-- HERE
|
||||||
local_s_portc = 50001;
|
local_s_portc = 50001;
|
||||||
remote_s_portc = 50000;
|
remote_s_portc = 50000;
|
||||||
local_s_portd = 50011;
|
local_s_portd = 50011;
|
||||||
@@ -171,7 +179,7 @@ Last, the S1 interface shall be properly set.
|
|||||||
|
|
||||||
```
|
```
|
||||||
////////// MME parameters:
|
////////// MME parameters:
|
||||||
mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; // replace with 192.168.10.20
|
mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; // replace with 192.168.122.195
|
||||||
ipv6 = "192:168:30::17";
|
ipv6 = "192:168:30::17";
|
||||||
active = "yes";
|
active = "yes";
|
||||||
preference = "ipv4";
|
preference = "ipv4";
|
||||||
@@ -181,11 +189,11 @@ Last, the S1 interface shall be properly set.
|
|||||||
NETWORK_INTERFACES :
|
NETWORK_INTERFACES :
|
||||||
{
|
{
|
||||||
ENB_INTERFACE_NAME_FOR_S1_MME = "ens3"; // replace with the proper interface name
|
ENB_INTERFACE_NAME_FOR_S1_MME = "ens3"; // replace with the proper interface name
|
||||||
ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; // replace with 192.168.10.10
|
ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; // replace with 192.168.122.31
|
||||||
ENB_INTERFACE_NAME_FOR_S1U = "ens3"; // replace with the proper interface name
|
ENB_INTERFACE_NAME_FOR_S1U = "ens3"; // replace with the proper interface name
|
||||||
ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; // replace with 192.168.10.10
|
ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; // replace with 192.168.122.31
|
||||||
ENB_PORT_FOR_S1U = 2152; # Spec 2152
|
ENB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||||
ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; // replace with 192.168.10.10
|
ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; // replace with 192.168.122.31
|
||||||
ENB_PORT_FOR_X2C = 36422; # Spec 36422
|
ENB_PORT_FOR_X2C = 36422; # Spec 36422
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -195,7 +203,7 @@ Last, the S1 interface shall be properly set.
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ ssh sudousername@machineB
|
$ ssh sudousername@machineB
|
||||||
$ cd ue_folder
|
cd ue_folder
|
||||||
# Edit ci-scripts/conf_files/ue.nfapi.conf with your preferred editor
|
# Edit ci-scripts/conf_files/ue.nfapi.conf with your preferred editor
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -206,9 +214,9 @@ L1s = (
|
|||||||
{
|
{
|
||||||
num_cc = 1;
|
num_cc = 1;
|
||||||
tr_n_preference = "nfapi";
|
tr_n_preference = "nfapi";
|
||||||
local_n_if_name = "lo"; // <- HERE
|
local_n_if_name = "ens3"; // <- HERE
|
||||||
remote_n_address = "127.0.0.2"; // <- HERE
|
remote_n_address = "192.168.122.31"; // <- HERE
|
||||||
local_n_address = "127.0.0.1"; // <- HERE
|
local_n_address = "192.168.122.169"; // <- HERE
|
||||||
local_n_portc = 50000;
|
local_n_portc = 50000;
|
||||||
remote_n_portc = 50001;
|
remote_n_portc = 50001;
|
||||||
local_n_portd = 50010;
|
local_n_portd = 50010;
|
||||||
@@ -217,20 +225,11 @@ L1s = (
|
|||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
# 6. Bring Up a second loopback interface #
|
# 6. Build OAI UE and eNodeB #
|
||||||
|
|
||||||
A second loopback interface is used to connect the eNB and the UEs.
|
See [Build documentation](./BUILD.md).
|
||||||
|
|
||||||
```bash
|
# 7. Start EPC #
|
||||||
$ ssh sudousername@machineB
|
|
||||||
$ sudo ifconfig lo: 127.0.0.2 netmask 255.0.0.0 up
|
|
||||||
```
|
|
||||||
|
|
||||||
# 7. [Build OAI UE and eNodeB](BUILD.md) #
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 8. Initialize the NAS UE Layer #
|
|
||||||
|
|
||||||
Start the EPC on machine `A`.
|
Start the EPC on machine `A`.
|
||||||
|
|
||||||
@@ -239,61 +238,89 @@ $ ssh sudousername@machineA
|
|||||||
# Start the EPC
|
# Start the EPC
|
||||||
```
|
```
|
||||||
|
|
||||||
# 9. Start the eNB #
|
# 8. Start the eNB #
|
||||||
|
|
||||||
In the first terminal (the one you used to build the eNB):
|
In the first terminal (the one you used to build the eNB):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ ssh sudousername@machineB
|
$ ssh sudousername@machineB
|
||||||
$ cd enb_folder/cmake_targets
|
cd enb_folder/cmake_targets
|
||||||
$ sudo -E ./ran_build/build/lte-softmodem -O ../ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf > enb.log 2>&1
|
sudo -E ./ran_build/build/lte-softmodem -O ../ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf > enb.log 2>&1
|
||||||
```
|
```
|
||||||
|
|
||||||
If you don't use redirection, you can test but many logs are printed on the console and this may affect performance of the L2-nFAPI simulator.
|
If you don't use redirection, you can test but many logs are printed on the console and this may affect performance of the L2-nFAPI simulator.
|
||||||
|
|
||||||
We do recommend the redirection in steady mode once your setup is correct.
|
We do recommend the redirection in steady mode once your setup is correct.
|
||||||
|
|
||||||
# 10. Start the UE #
|
# 9. Start the UE #
|
||||||
|
|
||||||
In the second terminal (the one you used to build the UE):
|
In the second terminal (the one you used to build the UE):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ ssh sudousername@machineB
|
$ ssh sudousername@machineC
|
||||||
$ cd ue_folder/cmake_targets
|
cd ue_folder/cmake_targets
|
||||||
# Test 64 UEs, 64 threads in FDD mode
|
# Test 64 UEs, 1 thread in FDD mode
|
||||||
$ sudo -E ./ran_build/build/lte-uesoftmodem -O ../ci-scripts/conf_files/ue.nfapi.conf --L2-emul 3 --num-ues 64 --nums-ue-thread 64 > ue.log 2>&1
|
sudo -E ./ran_build/build/lte-uesoftmodem -O ../ci-scripts/conf_files/ue.nfapi.conf --L2-emul 3 --num-ues 64 --nums_ue_thread 1 --nokrnmod 1 > ue.log 2>&1
|
||||||
# Test 64 UEs, 64 threads in TDD mode
|
# Test 64 UEs, 1 thread in TDD mode
|
||||||
$ sudo -E ./ran_build/build/lte-uesoftmodem -O ../ci-scripts/conf_files/ue.nfapi.conf --L2-emul 3 --num-ues 64 --nums-ue-thread 64 -T 1 > ue.log 2>&1
|
sudo -E ./ran_build/build/lte-uesoftmodem -O ../ci-scripts/conf_files/ue.nfapi.conf --L2-emul 3 --num-ues 64 --nums_ue_thread 1 --nokrnmod 1 -T 1 > ue.log 2>&1
|
||||||
# The "-T 1" option means TDD config
|
# The "-T 1" option means TDD config
|
||||||
```
|
```
|
||||||
|
|
||||||
- The number of UEs can set by using `--num-ues` option and the maximum UE number is 255 (with the `--mu*` options, otherwise 16).
|
- The number of UEs can set by using `--num-ues` option and the maximum UE number is 255 (with the `--mu*` options, otherwise 16).
|
||||||
- The umber of threads can set with the `--nums-ue-thread`. This number **SHALL NOT** be greater than the number of UEs.
|
- The number of threads can set with the `--nums-ue-thread`. This number **SHALL NOT** be greater than the number of UEs.
|
||||||
|
* At the time of writing, it seems to be enough to run on a single thread.
|
||||||
|
- The `--nokrnmod 1` option makes use of the preferred and supported tunnel interface.
|
||||||
- How many UE that can be tested depends on hardware (server , PC, etc) performance in your environment.
|
- How many UE that can be tested depends on hardware (server , PC, etc) performance in your environment.
|
||||||
|
|
||||||
# 11. Test with ping #
|
For example, running with 4 UEs:
|
||||||
|
|
||||||
In a third terminal, after around 10 seconds, the UE(s) shall be connected to the eNB:
|
```bash
|
||||||
|
$ ssh sudousername@machineC
|
||||||
|
cd ue_folder/cmake_targets
|
||||||
|
sudo -E ./ran_build/build/lte-uesoftmodem -O ../ci-scripts/conf_files/ue.nfapi.conf --L2-emul 3 --num-ues 64 --nums_ue_thread 1 --nokrnmod 1 > ue.log 2>&1
|
||||||
|
sleep 10
|
||||||
|
ifconfig
|
||||||
|
ens3 Link encap:Ethernet HWaddr XX:XX:XX:XX:XX:XX
|
||||||
|
inet addr:192.168.122.169 Bcast:192.168.122.255 Mask:255.255.255.0
|
||||||
|
....
|
||||||
|
oaitun_ue1 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
|
||||||
|
inet addr:192.172.0.2 P-t-P:192.172.0.2 Mask:255.255.255.0
|
||||||
|
....
|
||||||
|
oaitun_ue2 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
|
||||||
|
inet addr:192.172.0.3 P-t-P:192.172.0.3 Mask:255.255.255.0
|
||||||
|
....
|
||||||
|
oaitun_ue3 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
|
||||||
|
inet addr:192.172.0.4 P-t-P:192.172.0.4 Mask:255.255.255.0
|
||||||
|
....
|
||||||
|
oaitun_ue4 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
|
||||||
|
inet addr:192.172.0.5 P-t-P:192.172.0.5 Mask:255.255.255.0
|
||||||
|
....
|
||||||
|
oaitun_uem1 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
|
||||||
|
inet addr:10.0.2.2 P-t-P:10.0.2.2 Mask:255.255.255.0
|
||||||
|
....
|
||||||
|
....
|
||||||
|
```
|
||||||
|
|
||||||
|
Having the 4 oaitun_ue tunnel interfaces up and with an allocated address means the connection with EPC went alright.
|
||||||
|
|
||||||
|
# 10. Test with ping #
|
||||||
|
|
||||||
|
In a third terminal, after around 10 seconds, the UE(s) shall be connected to the eNB: Check with ifconfig
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ ssh sudousername@machineA
|
$ ssh sudousername@machineA
|
||||||
# Ping UE0 IP address based on the EPC pool used: in this example:
|
|
||||||
$ ping -c 20 192.168.200.2
|
|
||||||
# Ping UE1 IP address based on the EPC pool used: in this example:
|
# Ping UE1 IP address based on the EPC pool used: in this example:
|
||||||
$ ping -c 20 192.168.200.4
|
$ ping -c 20 192.172.0.2
|
||||||
|
# Ping UE4 IP address based on the EPC pool used: in this example:
|
||||||
|
$ ping -c 20 192.172.0.5
|
||||||
```
|
```
|
||||||
|
|
||||||
# 12. Limitations #
|
iperf operations can also be performed.
|
||||||
|
|
||||||
Testing on the CI process is currently limited at time of writing. Improvements will be made soon.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 11. Limitations #
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
[oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
|
[oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,336 @@
|
|||||||
|
# OpenAirInterface for SystemX
|
||||||
|
|
||||||
|
# Terminology
|
||||||
|
|
||||||
|
****This document use the 5G terminology****
|
||||||
|
|
||||||
|
**Central Unit (CU):** It is a logical node that includes the gNB
|
||||||
|
functions like Transfer of user data, Mobility control, Radio access
|
||||||
|
network sharing, Positioning, Session Management etc., except those
|
||||||
|
functions allocated exclusively to the DU. CU controls the operation of
|
||||||
|
DUs over front-haul (Fs) interface. A central unit (CU) may also be
|
||||||
|
known as BBU/REC/RCC/C-RAN/V-RAN/VNF
|
||||||
|
|
||||||
|
**Distributed Unit (DU):** This logical node includes a subset of the
|
||||||
|
gNB functions, depending on the functional split option. Its operation
|
||||||
|
is controlled by the CU. Distributed Unit (DU) also known with other
|
||||||
|
names like RRH/RRU/RE/RU/PNF.
|
||||||
|
|
||||||
|
In OpenAir code, the terminology is often RU and BBU.
|
||||||
|
|
||||||
|
# OpenAirUsage
|
||||||
|
|
||||||
|
## EPC and general environment
|
||||||
|
|
||||||
|
### OAI EPC
|
||||||
|
|
||||||
|
Use the stable OAI EPC, that can run in one machine (VM or standalone)
|
||||||
|
|
||||||
|
Draft description:
|
||||||
|
<https://open-cells.com/index.php/2017/08/22/all-in-one-openairinterface-august-22nd/>
|
||||||
|
|
||||||
|
## Standalone 4G
|
||||||
|
|
||||||
|
EPC+eNB on one machine, the UE can be commercial or OAI UE.
|
||||||
|
|
||||||
|
### USRP B210
|
||||||
|
|
||||||
|
Main current issue: traffic is good only on coaxial link between UE and
|
||||||
|
eNB (probably power management issue).
|
||||||
|
|
||||||
|
### Simulated RF
|
||||||
|
|
||||||
|
Running eNB+UE both OAI can be done over a virtual RF link.
|
||||||
|
|
||||||
|
The UE current status is that threads synchronization is implicit in
|
||||||
|
some cases. As the RF simulator is very quick, a “sleep()” is required
|
||||||
|
in the UE main loop
|
||||||
|
|
||||||
|
(line 1744, targets/RT/USER/lte-ue.c).
|
||||||
|
|
||||||
|
Running also the UE in the same machine is possible with simulated RF.
|
||||||
|
|
||||||
|
Running in same machine is simpler, offers about infinite speed for
|
||||||
|
virtual RF samples transmission.
|
||||||
|
|
||||||
|
A specific configuration is required because the EPC Sgi interface has
|
||||||
|
the same IP tunnel end point as the UE.
|
||||||
|
|
||||||
|
So, we have to create a network namespace for the UE and to route data
|
||||||
|
in/out of the namespace.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ip netns delete aNameSpace 2> /dev/null
|
||||||
|
|
||||||
|
ip link delete v-eth1 2> /dev/null
|
||||||
|
|
||||||
|
ip netns add aNameSpace
|
||||||
|
|
||||||
|
ip link add v-eth1 type veth peer name v-peer1
|
||||||
|
|
||||||
|
ip link set v-peer1 netns aNameSpace
|
||||||
|
|
||||||
|
ip addr add 10.200.1.1/24 dev v-eth1
|
||||||
|
|
||||||
|
ip link set v-eth1 up
|
||||||
|
|
||||||
|
iptables -t nat -A POSTROUTING -s 10.200.1.0/255.255.255.0 -o enp0s31f6 \
|
||||||
|
-j MASQUERADE
|
||||||
|
|
||||||
|
iptables -A FORWARD -i enp0s31f6 -o v-eth1 -j ACCEPT
|
||||||
|
|
||||||
|
iptables -A FORWARD -o enp0s31f6 -i v-eth1 -j ACCEPT
|
||||||
|
|
||||||
|
ip netns exec aNameSpace ip link set dev lo up
|
||||||
|
|
||||||
|
ip netns exec aNameSpace ip addr add 10.200.1.2/24 dev v-peer1
|
||||||
|
|
||||||
|
ip netns exec aNameSpace ip link set v-peer1 up
|
||||||
|
|
||||||
|
ip netns exec aNameSpace bash
|
||||||
|
```
|
||||||
|
|
||||||
|
After the last command, the Linux shell is in the new namespace, ready
|
||||||
|
to run the UE.
|
||||||
|
|
||||||
|
To make user plan traffic, the traffic generator has to run in the same
|
||||||
|
namespace
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ip netns exec aNameSpace bash
|
||||||
|
```
|
||||||
|
|
||||||
|
The traffic genenrator has to specify the interface:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
route add default oaitun_ue1
|
||||||
|
```
|
||||||
|
|
||||||
|
or specify the outgoing route in the traffic generator (like option “-I”
|
||||||
|
in ping command).
|
||||||
|
|
||||||
|
## Split 6 DL 4G
|
||||||
|
|
||||||
|
The contract describes to reuse the uplink existing if4p5 and to develop
|
||||||
|
is this work the downlink “functional split 6”.
|
||||||
|
|
||||||
|
The customer required after signature to develop also the uplink
|
||||||
|
functional split 6. This is accepted, as long as the whole work is
|
||||||
|
research with no delivery completeness warranty.
|
||||||
|
|
||||||
|
### Simulation
|
||||||
|
|
||||||
|
To be able to verify the new features and to help in all future
|
||||||
|
developments, Open Cells added and improved the Rf board simulator
|
||||||
|
during this contract.
|
||||||
|
|
||||||
|
We added the channel modeling simulation, that offer to simulate various
|
||||||
|
3GPP defined channels.
|
||||||
|
|
||||||
|
### Main loop
|
||||||
|
|
||||||
|
The main log is in RF simulator is in
|
||||||
|
|
||||||
|
`targets/RT/USER/lte-ru.c and targets/RT/USER/lte-enb.c`
|
||||||
|
|
||||||
|
As this piece of SW is very complex and doesn’t meet our goals
|
||||||
|
(functional split 6), a cleaned version replaces these 2 files in
|
||||||
|
executables/ocp-main.c (openair1/SCHED/prach\_procedures.c is also
|
||||||
|
replaced by this new file as it only launching the RACH actual work in a
|
||||||
|
way not compatible with our FS6).
|
||||||
|
|
||||||
|
The main loop cadences the I/Q samples reception, signal processing and
|
||||||
|
I/Q samples sending.
|
||||||
|
|
||||||
|
The main loop uses extensively function pointers to call the right
|
||||||
|
processing function depending on the split case.
|
||||||
|
|
||||||
|
A lot of OAI reduntant global variables contains the same semantic data: time,frame, subframe.
|
||||||
|
The reworked main loop take care of a uniq variable that comes directly from harware: RF board sampling number.
|
||||||
|
|
||||||
|
To use OAI, we need to set all OAI variables that derivates from this timestamp value. The function setAllfromTS() implements this.
|
||||||
|
|
||||||
|
### Splitted main level
|
||||||
|
|
||||||
|
When FS6 is actived, a main loop for DU (du_fs6()) a main loop for CU case replaces the uniq eNB main loop.
|
||||||
|
|
||||||
|
Each of these main loops calls initialization of OAI LTE data and the FS6 transport layer initialization.
|
||||||
|
|
||||||
|
Then, it runs a infinite loop on: set time, call UL and DL. The time comes from the RF board, so the DU sends the time to the CU.
|
||||||
|
|
||||||
|
This is enough for RF board dialog, but the FS6 is higher in SW layers,
|
||||||
|
we need to cut higher functions inside downlink and uplink procedures.
|
||||||
|
|
||||||
|
As much as possible, the FS6 code is in the directory OPENAIR_DIR/executables. When a given OAI piece of code is small or need complex changes, it is reworked in the file fs6-main.c. The functions naming keeps the OAI function name, adding suffix _fromsplit() or _tosplit().
|
||||||
|
|
||||||
|
When this organization would lead to large code copy, it is better to insert modifications in OAI code. This is done in two files:
|
||||||
|
|
||||||
|
- openair1/SCHED/phy_procedures_lte_eNb.c: to send signaling channels computation results
|
||||||
|
- the function sendFs6Ulharq() centralizes all signaling channels forwarding to CU
|
||||||
|
- openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c: to deal with FS6 user plane split
|
||||||
|
- sendFs6Ul() is used once to forward user plane to CU
|
||||||
|
|
||||||
|
|
||||||
|
### DownLink
|
||||||
|
|
||||||
|
The main procedure is phy\_procedures\_eNB\_TX()
|
||||||
|
|
||||||
|
This is building the common channels (beacon, multi-UE signaling).
|
||||||
|
|
||||||
|
The FS6 split breaks this function into pieces:
|
||||||
|
|
||||||
|
* The multi-UE signals, built by common\_signal\_procedures(),
|
||||||
|
subframe2harq\_pid(), generate\_dci\_top(), subframe2harq\_pid()
|
||||||
|
* These functions run in the DU, nevertheless all context has to be sent
|
||||||
|
(it is also needed partially for UL spitting)
|
||||||
|
* Run in the DU also to meet the requirement of pushing
|
||||||
|
in DU the data encoded with large redundancy (>3 redundancy)
|
||||||
|
|
||||||
|
* the per UE data: pdsch\_procedures() needs further splitting:
|
||||||
|
|
||||||
|
* dlsch\_encoding\_all() that makes the encoding: turbo code
|
||||||
|
and lte\_rate\_matching\_turbo() that will be in the DU (some
|
||||||
|
unlikely cases can reach redundancy up to x3, when MCS is very
|
||||||
|
low (negative SINR cases)).
|
||||||
|
|
||||||
|
* dlsch\_encoding() output needs to be transmitted between the
|
||||||
|
DU and the CU for functional split 6.
|
||||||
|
* dlsch\_scrambling() that will go in the DU
|
||||||
|
* dlsch\_modulation() that will go in the DU
|
||||||
|
|
||||||
|
The du user plane data is made of expanded bit in OAI at FS6 split level. 1 pair of functions compact back these bits into 8bits/byte before sending data and expand it again in the DU data reception (functions: fs6Dl(un)pack()).
|
||||||
|
|
||||||
|
### Uplink
|
||||||
|
|
||||||
|
The uplink require configuration that is part of the DL transmission.
|
||||||
|
|
||||||
|
It interprets the signalling to extract the RACH and the per UE data
|
||||||
|
channels.
|
||||||
|
|
||||||
|
Ocp-main.c:rxtx() calls directly the entry procedure
|
||||||
|
phy\_procedures\_eNB\_uespec\_RX() calls:
|
||||||
|
|
||||||
|
* rx\_ulsch() that demodulate and extract soft bits per UE.
|
||||||
|
|
||||||
|
* This function runs in the DU
|
||||||
|
* the output data will be processes in the DU, so it needs to be
|
||||||
|
transmitted to the DU
|
||||||
|
* ulsch\_decoding() that do lte\_rate\_matching\_turbo\_rx()
|
||||||
|
sub\_block\_deinterleaving\_turbo()
|
||||||
|
then turbo decode that is in the CU
|
||||||
|
* fill\_ulsch\_cqi\_indication() fill\_crc\_indication() , fill\_rx\_indication()
|
||||||
|
* DU performs the signal processing of each channel data, prepare and sent to the CU the computed result
|
||||||
|
|
||||||
|
* Random access channel detection runs in the DU
|
||||||
|
* the DU reports to the CU only the detected temprary identifier for RACH response
|
||||||
|
|
||||||
|
|
||||||
|
### signaling data in each direction (UL and DL)
|
||||||
|
|
||||||
|
|
||||||
|
* each LTE channel needs to be propagated between CU and DU
|
||||||
|
* the simplest are the almost static data such as PSS/SSS, that need only static eNB parameters and primary information (frame numbering)
|
||||||
|
* all the other channels require data transmission CU to DU and DU to CU
|
||||||
|
* the general design push all the low level processing for these channels in the DU
|
||||||
|
* the CU interface transports only signal processing results (UL) or configuration to create the RF signal (DL case)
|
||||||
|
* HARQ is detected in the DU, then only the ACK or NACK is reported to CU
|
||||||
|
|
||||||
|
* the CU have to control the power and MCS (modulation and coding scheme)
|
||||||
|
* the DU performs the signal processing and report only the decoded data like the CQI
|
||||||
|
* as the DU performas the modulation, scrambling and puncturing, each data packet is associated with the LTE parameters required for these features
|
||||||
|
* in DL, the CU associates the control parameters and the user plane data
|
||||||
|
* in UL, the CU sends upfront the scheduled UL data to the DU. So, the DU have the required knowledge to decode the next subframes in time.
|
||||||
|
|
||||||
|
### UDP transport layer
|
||||||
|
|
||||||
|
A general UDP transport layer is in executables/transport\_split.c
|
||||||
|
|
||||||
|
Linux offers a UDP socket builtin timeout, that we use.
|
||||||
|
|
||||||
|
In and out buffers are memory zones that contains compacted
|
||||||
|
(concatenated) UDP chunks.
|
||||||
|
|
||||||
|
For output, sendSubFrame() sends each UDP chunk
|
||||||
|
|
||||||
|
For input, receiveSubFrame() collects all UDP chunks for a group (a
|
||||||
|
subframe in OAI LTE case). It returns in the following cases:
|
||||||
|
|
||||||
|
- all chunks are received
|
||||||
|
- a timeout expired
|
||||||
|
- a chunk from the next subframe already arrived
|
||||||
|
|
||||||
|
### Functional split 6 usage
|
||||||
|
|
||||||
|
The ocp cleaned main hale to be used: run ocp-softmodem instead of
|
||||||
|
lte-softmodem.
|
||||||
|
|
||||||
|
The functionality and parameters is the same, enhanced with FS6 mode.
|
||||||
|
|
||||||
|
The end line option “--split73” enables the fs6 (also called split 7.3) mode and decided to be cu or du.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./ocp-softmodem -O $OPENAIR_DIR/enb.fs6.example.conf --rfsim --log_config.phy_log_level debug --split73 cu:127.0.0.1
|
||||||
|
```
|
||||||
|
|
||||||
|
Run the CU init of the split 6 eNB, that will call du on 127.0.0.1 address
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./ocp-softmodem -O $OPENAIR_DIR/enb.fs6.example.conf --rfsim --log_config.phy_log_level debug --split73 du:127.0.0.1
|
||||||
|
```
|
||||||
|
|
||||||
|
will run the du, calling the cu on 127.0.0.1
|
||||||
|
|
||||||
|
If the CU and the DU are not on the same machine, the remote address of each side need to be specified as per this example
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./ocp-softmodem -O $OPENAIR_DIR/enb.fs6.example.conf --rfsim --log_config.phy_log_level debug --split73 du:192.168.1.55
|
||||||
|
```
|
||||||
|
|
||||||
|
runs the functional split 6 DU
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./lte-uesoftmodem -C 2685000000 -r 50 --rfsim --rfsimulator.serveraddr 192.168.1.1 -d
|
||||||
|
```
|
||||||
|
|
||||||
|
Runs the UE (to have the UE signal scope, compile it with make uescope)
|
||||||
|
|
||||||
|
CU+DU+UE can run with option `--noS1` to avoid to use a EPC and/or with `--rfsim` to simulate RF board
|
||||||
|
|
||||||
|
|
||||||
|
## 5G and F1
|
||||||
|
|
||||||
|
Today 5G achievement is limited to physical layer.
|
||||||
|
|
||||||
|
The available modulation is 40MHz, that require one X310 or N300 for the
|
||||||
|
gNB and a X310 or N300 for the nrUE.
|
||||||
|
|
||||||
|
### Usage with X310
|
||||||
|
|
||||||
|
Linux configuration:
|
||||||
|
<https://files.ettus.com/manual/page_usrp_x3x0_config.html>
|
||||||
|
|
||||||
|
We included most of this configuration included in OAI source code.
|
||||||
|
|
||||||
|
Remain to set the NIC (network interface card) MTU to 9000 (jumbo
|
||||||
|
frames).
|
||||||
|
|
||||||
|
### Running 5G
|
||||||
|
|
||||||
|
Usage with RFsimulator:
|
||||||
|
|
||||||
|
**gNB**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo RFSIMULATOR=server ./nr-softmodem -O \
|
||||||
|
../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf \
|
||||||
|
--parallel-config PARALLEL\_SINGLE\_THREAD
|
||||||
|
```
|
||||||
|
|
||||||
|
**nrUE**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --numerology 1 -r 106 -C \
|
||||||
|
3510000000 -d
|
||||||
|
```
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 87 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 56 KiB |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -185,8 +185,8 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
|
|||||||
wakeup_prach_gNB(gNB,NULL,proc->frame_rx,proc->slot_rx);
|
wakeup_prach_gNB(gNB,NULL,proc->frame_rx,proc->slot_rx);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Call the scheduler
|
// Call the scheduler
|
||||||
|
|
||||||
pthread_mutex_lock(&gNB->UL_INFO_mutex);
|
pthread_mutex_lock(&gNB->UL_INFO_mutex);
|
||||||
gNB->UL_INFO.frame = frame_rx;
|
gNB->UL_INFO.frame = frame_rx;
|
||||||
gNB->UL_INFO.slot = slot_rx;
|
gNB->UL_INFO.slot = slot_rx;
|
||||||
@@ -324,7 +324,7 @@ static void *gNB_L1_thread( void *param ) {
|
|||||||
gNB_L1_rxtx_proc_t *L1_proc = &gNB_proc->L1_proc;
|
gNB_L1_rxtx_proc_t *L1_proc = &gNB_proc->L1_proc;
|
||||||
//PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id];
|
//PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id];
|
||||||
char thread_name[100];
|
char thread_name[100];
|
||||||
|
// set default return value
|
||||||
// set default return value
|
// set default return value
|
||||||
gNB_thread_rxtx_status = 0;
|
gNB_thread_rxtx_status = 0;
|
||||||
|
|
||||||
@@ -421,7 +421,7 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot
|
|||||||
|
|
||||||
int waitret = 0, ret = 0, time_ns = 1000*1000;
|
int waitret = 0, ret = 0, time_ns = 1000*1000;
|
||||||
struct timespec now, abstime;
|
struct timespec now, abstime;
|
||||||
|
// note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time
|
||||||
// note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time
|
// note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time
|
||||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,1);
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,1);
|
||||||
time_ns = time_ns/gNB->frame_parms.slots_per_subframe;
|
time_ns = time_ns/gNB->frame_parms.slots_per_subframe;
|
||||||
@@ -521,7 +521,7 @@ int wakeup_tx(PHY_VARS_gNB *gNB,int frame_rx,int slot_rx,int frame_tx,int slot_t
|
|||||||
|
|
||||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_UE,1);
|
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_UE,1);
|
||||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_UE,0);
|
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_UE,0);
|
||||||
|
// the thread can now be woken up
|
||||||
// the thread can now be woken up
|
// the thread can now be woken up
|
||||||
AssertFatal(pthread_cond_signal(&L1_proc_tx->cond) == 0, "ERROR pthread_cond_signal for gNB L1 thread\n");
|
AssertFatal(pthread_cond_signal(&L1_proc_tx->cond) == 0, "ERROR pthread_cond_signal for gNB L1 thread\n");
|
||||||
|
|
||||||
@@ -578,10 +578,10 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
++L1_proc->instance_cnt;
|
++L1_proc->instance_cnt;
|
||||||
|
|
||||||
// We have just received and processed the common part of a subframe, say n.
|
// We have just received and processed the common part of a subframe, say n.
|
||||||
// TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired
|
// TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired
|
||||||
// transmitted timestamp of the next TX slot (first).
|
// transmitted timestamp of the next TX slot (first).
|
||||||
|
|
||||||
// The last (TS_rx mod samples_per_frame) was n*samples_per_tti,
|
// The last (TS_rx mod samples_per_frame) was n*samples_per_tti,
|
||||||
// we want to generate subframe (n+sf_ahead), so TS_tx = TX_rx+sf_ahead*samples_per_tti,
|
// we want to generate subframe (n+sf_ahead), so TS_tx = TX_rx+sf_ahead*samples_per_tti,
|
||||||
// and proc->slot_tx = proc->slot_rx+sf_ahead
|
// and proc->slot_tx = proc->slot_rx+sf_ahead
|
||||||
|
|||||||
+20
-37
@@ -1,41 +1,24 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
OpenAirInterface
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||||
Copyright(c) 1999 - 2014 Eurecom
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||||
it under the terms of the GNU General Public License as published by
|
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
* except in compliance with the License.
|
||||||
(at your option) any later version.
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
OpenAirInterface is distributed in the hope that it will be useful,
|
* http://www.openairinterface.org/?page_id=698
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
*
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
GNU General Public License for more details.
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
You should have received a copy of the GNU General Public License
|
* See the License for the specific language governing permissions and
|
||||||
along with OpenAirInterface.The full GNU General Public License is
|
* limitations under the License.
|
||||||
included in this distribution in the file called "COPYING". If not,
|
*-------------------------------------------------------------------------------
|
||||||
see <http://www.gnu.org/licenses/>.
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||||
|
* contact@openairinterface.org
|
||||||
Contact Information
|
|
||||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
|
||||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
|
||||||
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
|
|
||||||
|
|
||||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
/*! \file lte-enb.c
|
|
||||||
* \brief Top-level threads for eNodeB
|
|
||||||
* \author R. Knopp, F. Kaltenberger, Navid Nikaein
|
|
||||||
* \date 2012
|
|
||||||
* \version 0.1
|
|
||||||
* \company Eurecom
|
|
||||||
* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr
|
|
||||||
* \note
|
|
||||||
* \warning
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ static int wait_for_sync = 0;
|
|||||||
unsigned int mmapped_dma=0;
|
unsigned int mmapped_dma=0;
|
||||||
int single_thread_flag=1;
|
int single_thread_flag=1;
|
||||||
|
|
||||||
static int8_t threequarter_fs=0;
|
int8_t threequarter_fs=0;
|
||||||
|
|
||||||
uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||||
@@ -169,6 +169,10 @@ uint32_t target_ul_mcs = 20;
|
|||||||
uint32_t timing_advance = 0;
|
uint32_t timing_advance = 0;
|
||||||
uint64_t num_missed_slots=0; // counter for the number of missed slots
|
uint64_t num_missed_slots=0; // counter for the number of missed slots
|
||||||
|
|
||||||
|
int split73=0;
|
||||||
|
void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset) {
|
||||||
|
AssertFatal(false, "Must not be called in this context\n");
|
||||||
|
}
|
||||||
|
|
||||||
extern void reset_opp_meas(void);
|
extern void reset_opp_meas(void);
|
||||||
extern void print_opp_meas(void);
|
extern void print_opp_meas(void);
|
||||||
@@ -719,13 +723,9 @@ int restart_L1L2(module_id_t gnb_id) {
|
|||||||
memcpy(&ru->nr_frame_parms, &RC.gNB[gnb_id]->frame_parms, sizeof(NR_DL_FRAME_PARMS));
|
memcpy(&ru->nr_frame_parms, &RC.gNB[gnb_id]->frame_parms, sizeof(NR_DL_FRAME_PARMS));
|
||||||
set_function_spec_param(RC.ru[gnb_id]);
|
set_function_spec_param(RC.ru[gnb_id]);
|
||||||
LOG_I(GNB_APP, "attempting to create ITTI tasks\n");
|
LOG_I(GNB_APP, "attempting to create ITTI tasks\n");
|
||||||
|
// No more rrc thread, as many race conditions are hidden behind
|
||||||
if (itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL) < 0) {
|
rrc_enb_init();
|
||||||
LOG_E(RRC, "Create task for RRC eNB failed\n");
|
itti_mark_task_ready(TASK_RRC_ENB);
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
LOG_I(RRC, "Re-created task for RRC gNB successfully\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) {
|
if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) {
|
||||||
LOG_E(PDCP, "Create task for L2L1 failed\n");
|
LOG_E(PDCP, "Create task for L2L1 failed\n");
|
||||||
|
|||||||
+4
-4
@@ -146,7 +146,7 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue,
|
|||||||
|
|
||||||
ue->Mod_id = UE_id;
|
ue->Mod_id = UE_id;
|
||||||
ue->mac_enabled = 1;
|
ue->mac_enabled = 1;
|
||||||
|
// initialize all signal buffers
|
||||||
// initialize all signal buffers
|
// initialize all signal buffers
|
||||||
init_nr_ue_signal(ue,1,abstraction_flag);
|
init_nr_ue_signal(ue,1,abstraction_flag);
|
||||||
// intialize transport
|
// intialize transport
|
||||||
@@ -471,7 +471,7 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// no UL for now
|
||||||
// no UL for now
|
// no UL for now
|
||||||
/*
|
/*
|
||||||
if (UE->mac_enabled==1) {
|
if (UE->mac_enabled==1) {
|
||||||
@@ -508,7 +508,7 @@ void UE_processing(void *arg) {
|
|||||||
PHY_VARS_NR_UE *UE = rxtxD->UE;
|
PHY_VARS_NR_UE *UE = rxtxD->UE;
|
||||||
|
|
||||||
uint8_t gNB_id = 0;
|
uint8_t gNB_id = 0;
|
||||||
|
// params for UL time alignment procedure
|
||||||
// params for UL time alignment procedure
|
// params for UL time alignment procedure
|
||||||
NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &UE->ul_time_alignment[gNB_id];
|
NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &UE->ul_time_alignment[gNB_id];
|
||||||
uint8_t numerology = UE->frame_parms.numerology_index;
|
uint8_t numerology = UE->frame_parms.numerology_index;
|
||||||
@@ -523,7 +523,7 @@ void UE_processing(void *arg) {
|
|||||||
|
|
||||||
if (frame_tx == ul_time_alignment->ta_frame && slot_tx == ul_time_alignment->ta_slot) {
|
if (frame_tx == ul_time_alignment->ta_frame && slot_tx == ul_time_alignment->ta_slot) {
|
||||||
LOG_D(PHY,"Applying timing advance -- frame %d -- slot %d\n", frame_tx, slot_tx);
|
LOG_D(PHY,"Applying timing advance -- frame %d -- slot %d\n", frame_tx, slot_tx);
|
||||||
|
//if (nfapi_mode!=3){
|
||||||
//if (nfapi_mode!=3){
|
//if (nfapi_mode!=3){
|
||||||
nr_process_timing_advance(UE->Mod_id, UE->CC_id, ul_time_alignment->ta_command, numerology, bwp_ul_NB_RB);
|
nr_process_timing_advance(UE->Mod_id, UE->CC_id, ul_time_alignment->ta_command, numerology, bwp_ul_NB_RB);
|
||||||
ul_time_alignment->ta_frame = -1;
|
ul_time_alignment->ta_frame = -1;
|
||||||
|
|||||||
@@ -381,9 +381,9 @@ static void get_options(void) {
|
|||||||
int tddflag=0, nonbiotflag, vcdflag=0;
|
int tddflag=0, nonbiotflag, vcdflag=0;
|
||||||
char *loopfile=NULL;
|
char *loopfile=NULL;
|
||||||
int dumpframe=0;
|
int dumpframe=0;
|
||||||
|
|
||||||
//uint32_t noS1;
|
//uint32_t noS1;
|
||||||
//uint32_t nokrnmod;
|
//uint32_t nokrnmod;
|
||||||
|
//uint32_t nokrnmod;
|
||||||
paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC_UE ;
|
paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC_UE ;
|
||||||
config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL);
|
config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL);
|
||||||
|
|
||||||
@@ -648,6 +648,11 @@ void init_pdcp(void) {
|
|||||||
LOG_I(PDCP, "Before getting out from init_pdcp() \n");
|
LOG_I(PDCP, "Before getting out from init_pdcp() \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stupid function addition because UE itti messages queues definition is common with eNB
|
||||||
|
void *rrc_enb_process_msg(void *notUsed) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main( int argc, char **argv ) {
|
int main( int argc, char **argv ) {
|
||||||
//uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
|
//uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
|
||||||
|
|||||||
@@ -81,8 +81,8 @@ char *get_softmodem_function(uint64_t *sofmodemfunc_mask_ptr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void get_common_options(uint32_t execmask) {
|
void get_common_options(uint32_t execmask) {
|
||||||
uint32_t online_log_messages;
|
uint32_t online_log_messages=0;
|
||||||
uint32_t glog_level ;
|
uint32_t glog_level=0 ;
|
||||||
uint32_t start_telnetsrv = 0;
|
uint32_t start_telnetsrv = 0;
|
||||||
uint32_t noS1 = 0, nokrnmod = 0, nonbiot = 0;
|
uint32_t noS1 = 0, nokrnmod = 0, nonbiot = 0;
|
||||||
uint32_t rfsim = 0, basicsim = 0, do_forms = 0;
|
uint32_t rfsim = 0, basicsim = 0, do_forms = 0;
|
||||||
|
|||||||
@@ -38,6 +38,11 @@ extern "C"
|
|||||||
#endif
|
#endif
|
||||||
/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */
|
/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */
|
||||||
#define CONFIG_HLP_RFCFGF "Configuration file for front-end (e.g. LMS7002M)\n"
|
#define CONFIG_HLP_RFCFGF "Configuration file for front-end (e.g. LMS7002M)\n"
|
||||||
|
#define CONFIG_HLP_SPLIT73 "Split 7.3 (below rate matching) option: <cu|du>:<remote ip address>:<remote port>"
|
||||||
|
#define CONFIG_HLP_TPOOL "Thread pool configuration: \n\
|
||||||
|
default no pool (runs in calling thread),\n\
|
||||||
|
list of cores, comma separated (negative value is no core affinity)\n\
|
||||||
|
example: -1,3 launches two working threads one floating, the second set on core 3"
|
||||||
#define CONFIG_HLP_ULMAXE "set the eNodeB max ULSCH erros\n"
|
#define CONFIG_HLP_ULMAXE "set the eNodeB max ULSCH erros\n"
|
||||||
#define CONFIG_HLP_CALUER "set UE RX calibration\n"
|
#define CONFIG_HLP_CALUER "set UE RX calibration\n"
|
||||||
#define CONFIG_HLP_CALUERM ""
|
#define CONFIG_HLP_CALUERM ""
|
||||||
@@ -89,6 +94,8 @@ extern "C"
|
|||||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||||
/*-----------------------------------------------------------------------------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||||
#define RF_CONFIG_FILE softmodem_params.rf_config_file
|
#define RF_CONFIG_FILE softmodem_params.rf_config_file
|
||||||
|
#define SPLIT73 softmodem_params.split73
|
||||||
|
#define TP_CONFIG softmodem_params.threadPoolConfig
|
||||||
#define PHY_TEST softmodem_params.phy_test
|
#define PHY_TEST softmodem_params.phy_test
|
||||||
#define WAIT_FOR_SYNC softmodem_params.wait_for_sync
|
#define WAIT_FOR_SYNC softmodem_params.wait_for_sync
|
||||||
#define SINGLE_THREAD_FLAG softmodem_params.single_thread_flag
|
#define SINGLE_THREAD_FLAG softmodem_params.single_thread_flag
|
||||||
@@ -104,6 +111,8 @@ extern "C"
|
|||||||
|
|
||||||
#define CMDLINE_PARAMS_DESC { \
|
#define CMDLINE_PARAMS_DESC { \
|
||||||
{"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&RF_CONFIG_FILE, defstrval:NULL, TYPE_STRING, sizeof(RF_CONFIG_FILE)},\
|
{"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&RF_CONFIG_FILE, defstrval:NULL, TYPE_STRING, sizeof(RF_CONFIG_FILE)},\
|
||||||
|
{"split73", CONFIG_HLP_SPLIT73, 0, strptr:(char **)&SPLIT73, defstrval:NULL, TYPE_STRING, sizeof(SPLIT73)},\
|
||||||
|
{"thread-pool", CONFIG_HLP_TPOOL, 0, strptr:(char **)&TP_CONFIG, defstrval:"n", TYPE_STRING, sizeof(TP_CONFIG)}, \
|
||||||
{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&PHY_TEST, defintval:0, TYPE_INT, 0}, \
|
{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&PHY_TEST, defintval:0, TYPE_INT, 0}, \
|
||||||
{"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&USIM_TEST, defintval:0, TYPE_UINT8, 0}, \
|
{"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&USIM_TEST, defintval:0, TYPE_UINT8, 0}, \
|
||||||
{"clock-source", CONFIG_HLP_CLK, 0, uptr:&CLOCK_SOURCE, defintval:0, TYPE_UINT, 0}, \
|
{"clock-source", CONFIG_HLP_CLK, 0, uptr:&CLOCK_SOURCE, defintval:0, TYPE_UINT, 0}, \
|
||||||
@@ -193,6 +202,8 @@ typedef struct {
|
|||||||
uint64_t optmask;
|
uint64_t optmask;
|
||||||
//THREAD_STRUCT thread_struct;
|
//THREAD_STRUCT thread_struct;
|
||||||
char rf_config_file[1024];
|
char rf_config_file[1024];
|
||||||
|
char split73[1024];
|
||||||
|
char threadPoolConfig[1024];
|
||||||
int phy_test;
|
int phy_test;
|
||||||
uint8_t usim_test;
|
uint8_t usim_test;
|
||||||
int emulate_rf;
|
int emulate_rf;
|
||||||
|
|||||||
@@ -0,0 +1,329 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||||
|
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||||
|
* except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.openairinterface.org/?page_id=698
|
||||||
|
*
|
||||||
|
* Author and copyright: Laurent Thomas, open-cells.com
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*-------------------------------------------------------------------------------
|
||||||
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||||
|
* contact@openairinterface.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __SPLIT_HEADERS_H
|
||||||
|
#define __SPLIT_HEADERS_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <openair1/PHY/defs_eNB.h>
|
||||||
|
|
||||||
|
#define CU_PORT "7878"
|
||||||
|
#define DU_PORT "8787"
|
||||||
|
#define SPLIT73_CU 1
|
||||||
|
#define SPLIT73_DU 2
|
||||||
|
extern int split73;
|
||||||
|
|
||||||
|
#define MTU 65536
|
||||||
|
#define UDP_TIMEOUT 900000L // in micro second (struct timeval, NOT struct timespec)
|
||||||
|
// linux may timeout for a much longer time (up to 10ms)
|
||||||
|
#define blockAlign 32 //bytes to align memory for SIMD copy (256 bits vectors)
|
||||||
|
|
||||||
|
// FS6 transport configuration and handler
|
||||||
|
typedef struct {
|
||||||
|
char *sourceIP;
|
||||||
|
char *sourcePort;
|
||||||
|
char *destIP;
|
||||||
|
char *destPort;
|
||||||
|
struct addrinfo *destAddr;
|
||||||
|
int sockHandler;
|
||||||
|
} UDPsock_t;
|
||||||
|
|
||||||
|
#define CTsentCUv0 0xA500
|
||||||
|
#define CTsentDUv0 0x5A00
|
||||||
|
|
||||||
|
// Main FS6 transport layer header
|
||||||
|
// All packets starts with this header
|
||||||
|
typedef struct commonUDP_s {
|
||||||
|
uint64_t timestamp; // id of the group (subframe for LTE)
|
||||||
|
uint16_t nbBlocks; // total number of blocks for this timestamp
|
||||||
|
uint16_t blockID; // id: 0..nbBocks-1
|
||||||
|
uint16_t contentType; // defines the content format
|
||||||
|
uint16_t contentBytes; // will be sent in a UDP packet, so must be < 2^16 bytes
|
||||||
|
uint64_t senderClock;
|
||||||
|
} commonUDP_t;
|
||||||
|
|
||||||
|
// FS6 UL common header (DU to CU)
|
||||||
|
// gives the RACH detection data and is always sent to inform the CU that a subframe arrived
|
||||||
|
typedef struct {
|
||||||
|
uint16_t max_preamble[4];
|
||||||
|
uint16_t max_preamble_energy[4];
|
||||||
|
uint16_t max_preamble_delay[4];
|
||||||
|
uint16_t avg_preamble_energy[4];
|
||||||
|
} fs6_ul_t;
|
||||||
|
|
||||||
|
// FS6 DL common header (CU to DU)
|
||||||
|
// gives the DCI configuration from each subframe
|
||||||
|
typedef struct {
|
||||||
|
uint8_t pbch_pdu[4];
|
||||||
|
int num_pdcch_symbols;
|
||||||
|
int num_dci;
|
||||||
|
DCI_ALLOC_t dci_alloc[8];
|
||||||
|
int num_mdci;
|
||||||
|
int amp;
|
||||||
|
LTE_eNB_PHICH phich_vars;
|
||||||
|
uint64_t DuClock;
|
||||||
|
uint64_t CuSpentMicroSec;
|
||||||
|
} fs6_dl_t;
|
||||||
|
|
||||||
|
// a value to type all sub packets,
|
||||||
|
// to detect errors, and to be able to extend to other versions
|
||||||
|
// the first byte of each sub structure should match one of these values
|
||||||
|
enum pckType {
|
||||||
|
fs6UlConfig=25,
|
||||||
|
fs6DlConfig=26,
|
||||||
|
fs6ULConfigCCH=27,
|
||||||
|
fs6ULsch=28,
|
||||||
|
fs6ULcch=29,
|
||||||
|
fs6ULindicationHarq=40,
|
||||||
|
fs6ULindicationSr=41,
|
||||||
|
};
|
||||||
|
|
||||||
|
// CU to DU definition of a future UL subframe decode
|
||||||
|
// defines a UE future data plane
|
||||||
|
typedef struct {
|
||||||
|
enum pckType type:8;
|
||||||
|
uint16_t UE_id;
|
||||||
|
int8_t harq_pid;
|
||||||
|
UE_type_t ue_type;
|
||||||
|
|
||||||
|
uint8_t dci_alloc;
|
||||||
|
uint8_t rar_alloc;
|
||||||
|
SCH_status_t status;
|
||||||
|
uint8_t Msg3_flag;
|
||||||
|
uint8_t subframe;
|
||||||
|
uint32_t frame;
|
||||||
|
uint8_t handled;
|
||||||
|
uint8_t phich_active;
|
||||||
|
uint8_t phich_ACK;
|
||||||
|
uint16_t previous_first_rb;
|
||||||
|
uint32_t B;
|
||||||
|
uint32_t G;
|
||||||
|
UCI_format_t uci_format;
|
||||||
|
uint8_t Or2;
|
||||||
|
uint8_t o_RI[2];
|
||||||
|
uint8_t o_ACK[4];
|
||||||
|
uint8_t O_ACK;
|
||||||
|
uint8_t o_RCC;
|
||||||
|
int16_t q_ACK[MAX_ACK_PAYLOAD];
|
||||||
|
int16_t q_RI[MAX_RI_PAYLOAD];
|
||||||
|
uint32_t RTC[MAX_NUM_ULSCH_SEGMENTS];
|
||||||
|
uint8_t ndi;
|
||||||
|
uint8_t round;
|
||||||
|
uint8_t rvidx;
|
||||||
|
uint8_t Nl;
|
||||||
|
uint8_t n_DMRS;
|
||||||
|
uint8_t previous_n_DMRS;
|
||||||
|
uint8_t n_DMRS2;
|
||||||
|
int32_t delta_TF;
|
||||||
|
uint32_t repetition_number ;
|
||||||
|
uint32_t total_number_of_repetitions;
|
||||||
|
|
||||||
|
uint16_t harq_mask;
|
||||||
|
uint16_t nb_rb;
|
||||||
|
uint8_t Qm;
|
||||||
|
uint16_t first_rb;
|
||||||
|
uint8_t O_RI;
|
||||||
|
uint8_t Or1;
|
||||||
|
uint16_t Msc_initial;
|
||||||
|
uint8_t Nsymb_initial;
|
||||||
|
uint8_t V_UL_DAI;
|
||||||
|
uint8_t srs_active;
|
||||||
|
uint32_t TBS;
|
||||||
|
uint8_t Nsymb_pusch;
|
||||||
|
uint8_t Mlimit;
|
||||||
|
uint8_t max_turbo_iterations;
|
||||||
|
uint8_t bundling;
|
||||||
|
uint16_t beta_offset_cqi_times8;
|
||||||
|
uint16_t beta_offset_ri_times8;
|
||||||
|
uint16_t beta_offset_harqack_times8;
|
||||||
|
uint8_t Msg3_active;
|
||||||
|
uint16_t rnti;
|
||||||
|
uint8_t cyclicShift;
|
||||||
|
uint8_t cooperation_flag;
|
||||||
|
uint8_t num_active_cba_groups;
|
||||||
|
uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP];
|
||||||
|
} fs6_dl_ulsched_t;
|
||||||
|
|
||||||
|
// CU to DU defintion of a DL packet for a given UE
|
||||||
|
// The data itself is padded at the end of this structure
|
||||||
|
typedef struct {
|
||||||
|
enum pckType type:8;
|
||||||
|
int UE_id;
|
||||||
|
int8_t harq_pid;
|
||||||
|
uint16_t rnti;
|
||||||
|
int16_t sqrt_rho_a;
|
||||||
|
int16_t sqrt_rho_b;
|
||||||
|
CEmode_t CEmode:8;
|
||||||
|
uint16_t nb_rb;
|
||||||
|
uint8_t Qm;
|
||||||
|
int8_t Nl;
|
||||||
|
uint8_t pdsch_start;
|
||||||
|
uint8_t sib1_br_flag;
|
||||||
|
uint16_t i0;
|
||||||
|
uint32_t rb_alloc[4];
|
||||||
|
int dataLen;
|
||||||
|
} fs6_dl_uespec_t;
|
||||||
|
|
||||||
|
// CU to DU definition of CCH channel
|
||||||
|
typedef struct {
|
||||||
|
int16_t UE_id;
|
||||||
|
LTE_eNB_UCI cch_vars;
|
||||||
|
} fs6_dl_uespec_ulcch_element_t;
|
||||||
|
|
||||||
|
// header to group all UE CCH channels definitions in one UDP packet
|
||||||
|
typedef struct {
|
||||||
|
enum pckType type:8;
|
||||||
|
int16_t nb_active_ue;
|
||||||
|
} fs6_dl_uespec_ulcch_t;
|
||||||
|
|
||||||
|
// code internal, not transmitted as this
|
||||||
|
typedef struct {
|
||||||
|
int ta;
|
||||||
|
} ul_propagation_t;
|
||||||
|
|
||||||
|
// One UE UL data, data plane, UE data appended after the header
|
||||||
|
typedef struct {
|
||||||
|
enum pckType type:8;
|
||||||
|
short UE_id;
|
||||||
|
uint8_t harq_id;
|
||||||
|
uint8_t segment;
|
||||||
|
int segLen;
|
||||||
|
int r_offset;
|
||||||
|
int G;
|
||||||
|
int ulsch_power[2];
|
||||||
|
uint8_t o_ACK[4];
|
||||||
|
uint8_t O_ACK;
|
||||||
|
int ta;
|
||||||
|
uint8_t o[MAX_CQI_BYTES];
|
||||||
|
uint8_t cqi_crc_status;
|
||||||
|
} fs6_ul_uespec_t;
|
||||||
|
|
||||||
|
// UL UCI (control plane), per UE
|
||||||
|
typedef struct {
|
||||||
|
enum pckType type:8;
|
||||||
|
int UEid;
|
||||||
|
int frame;
|
||||||
|
int subframe;
|
||||||
|
LTE_eNB_UCI uci;
|
||||||
|
uint8_t harq_ack[4];
|
||||||
|
uint8_t tdd_mapping_mode;
|
||||||
|
uint16_t tdd_multiplexing_mask;
|
||||||
|
unsigned short n0_subband_power_dB;
|
||||||
|
uint16_t rnti;
|
||||||
|
int32_t stat;
|
||||||
|
} fs6_ul_uespec_uci_element_t;
|
||||||
|
|
||||||
|
// all segments UCI grouped in one UDP packet
|
||||||
|
typedef struct {
|
||||||
|
enum pckType type:8;
|
||||||
|
int16_t nb_active_ue;
|
||||||
|
} fs6_ul_uespec_uci_t;
|
||||||
|
|
||||||
|
|
||||||
|
bool createUDPsock (char *sourceIP, char *sourcePort, char *destIP, char *destPort, UDPsock_t *result);
|
||||||
|
int receiveSubFrame(UDPsock_t *sock, void *bufferZone, int bufferSize, uint16_t contentType);
|
||||||
|
int sendSubFrame(UDPsock_t *sock, void *bufferZone, ssize_t secondHeaderSize, uint16_t contentType);
|
||||||
|
|
||||||
|
#define initBufferZone(xBuf) \
|
||||||
|
uint8_t xBuf[FS6_BUF_SIZE]; \
|
||||||
|
((commonUDP_t *)xBuf)->nbBlocks=0;
|
||||||
|
|
||||||
|
#define hUDP(xBuf) ((commonUDP_t *)xBuf)
|
||||||
|
#define hDL(xBuf) ((fs6_dl_t*)(((commonUDP_t *)xBuf)+1))
|
||||||
|
#define hUL(xBuf) ((fs6_ul_t*)(((commonUDP_t *)xBuf)+1))
|
||||||
|
#define hDLUE(xBuf) ((fs6_dl_uespec_t*) (((fs6_dl_t*)(((commonUDP_t *)xBuf)+1))+1))
|
||||||
|
#define hTxULUE(xBuf) ((fs6_dl_ulsched_t*) (((fs6_dl_t*)(((commonUDP_t *)xBuf)+1))+1))
|
||||||
|
#define hTxULcch(xBuf) ((fs6_dl_uespec_ulcch_t*) (((fs6_dl_t*)(((commonUDP_t *)xBuf)+1))+1))
|
||||||
|
#define hULUE(xBuf) ((fs6_ul_uespec_t*) (((fs6_ul_t*)(((commonUDP_t *)xBuf)+1))+1))
|
||||||
|
#define hULUEuci(xBuf) ((fs6_ul_uespec_uci_t*) (((fs6_ul_t*)(((commonUDP_t *)xBuf)+1))+1))
|
||||||
|
|
||||||
|
static inline size_t alignedSize(uint8_t *ptr) {
|
||||||
|
commonUDP_t *header=(commonUDP_t *) ptr;
|
||||||
|
return ((header->contentBytes+sizeof(commonUDP_t)+blockAlign-1)/blockAlign)*blockAlign;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *commonUDPdata(uint8_t *ptr) {
|
||||||
|
return (void *) (((commonUDP_t *)ptr)+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAllfromTS(uint64_t TS, L1_rxtx_proc_t *proc);
|
||||||
|
void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB,LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask,
|
||||||
|
uint16_t rnti, int32_t stat);
|
||||||
|
void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset);
|
||||||
|
void *cu_fs6(void *arg);
|
||||||
|
void *du_fs6(void *arg);
|
||||||
|
void fill_rf_config(RU_t *ru, char *rf_config_file);
|
||||||
|
int init_rf(RU_t *ru);
|
||||||
|
void rx_rf(RU_t *ru, L1_rxtx_proc_t *proc);
|
||||||
|
void tx_rf(RU_t *ru, L1_rxtx_proc_t *proc);
|
||||||
|
void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe);
|
||||||
|
void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc);
|
||||||
|
bool dlsch_procedures(PHY_VARS_eNB *eNB,
|
||||||
|
L1_rxtx_proc_t *proc,
|
||||||
|
int harq_pid,
|
||||||
|
LTE_eNB_DLSCH_t *dlsch,
|
||||||
|
LTE_eNB_UE_stats *ue_stats) ;
|
||||||
|
void postDecode(L1_rxtx_proc_t *proc, notifiedFIFO_elt_t *req);
|
||||||
|
void pdsch_procedures(PHY_VARS_eNB *eNB,
|
||||||
|
L1_rxtx_proc_t *proc,
|
||||||
|
int harq_pid,
|
||||||
|
LTE_eNB_DLSCH_t *dlsch,
|
||||||
|
LTE_eNB_DLSCH_t *dlsch1);
|
||||||
|
void srs_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc);
|
||||||
|
void uci_procedures(PHY_VARS_eNB *eNB,
|
||||||
|
L1_rxtx_proc_t *proc);
|
||||||
|
void ocp_rx_prach(PHY_VARS_eNB *eNB,
|
||||||
|
L1_rxtx_proc_t *proc,
|
||||||
|
RU_t *ru,
|
||||||
|
uint16_t *max_preamble,
|
||||||
|
uint16_t *max_preamble_energy,
|
||||||
|
uint16_t *max_preamble_delay,
|
||||||
|
uint16_t *avg_preamble_energy,
|
||||||
|
uint16_t Nf,
|
||||||
|
uint8_t tdd_mapindex,
|
||||||
|
uint8_t br_flag);
|
||||||
|
void rx_prach0(PHY_VARS_eNB *eNB,
|
||||||
|
RU_t *ru,
|
||||||
|
int frame_prach,
|
||||||
|
int subframe,
|
||||||
|
uint16_t *max_preamble,
|
||||||
|
uint16_t *max_preamble_energy,
|
||||||
|
uint16_t *max_preamble_delay,
|
||||||
|
uint16_t *avg_preamble_energy,
|
||||||
|
uint16_t Nf,
|
||||||
|
uint8_t tdd_mapindex,
|
||||||
|
uint8_t br_flag,
|
||||||
|
uint8_t ce_level
|
||||||
|
);
|
||||||
|
void ocp_tx_rf(RU_t *ru, L1_rxtx_proc_t *proc);
|
||||||
|
|
||||||
|
// mistakes in main OAI
|
||||||
|
void phy_init_RU(RU_t *);
|
||||||
|
void fep_full(RU_t *ru, int subframe);
|
||||||
|
void feptx_prec(RU_t *ru,int frame,int subframe);
|
||||||
|
void feptx_ofdm(RU_t *ru, int frame, int subframe);
|
||||||
|
void oai_subframe_ind(uint16_t sfn, uint16_t sf);
|
||||||
|
extern uint16_t sf_ahead;
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,195 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||||
|
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||||
|
* except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.openairinterface.org/?page_id=698
|
||||||
|
*
|
||||||
|
* Author and copyright: Laurent Thomas, open-cells.com
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*-------------------------------------------------------------------------------
|
||||||
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||||
|
* contact@openairinterface.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <executables/split_headers.h>
|
||||||
|
#include <sys/types.h> /* See NOTES */
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/udp.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <targets/RT/USER/lte-softmodem.h>
|
||||||
|
|
||||||
|
bool createUDPsock (char *sourceIP, char *sourcePort, char *destIP, char *destPort, UDPsock_t *result) {
|
||||||
|
struct addrinfo hints= {0}, *servinfo, *p;
|
||||||
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
hints.ai_socktype = SOCK_DGRAM;
|
||||||
|
hints.ai_flags = AI_PASSIVE;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if ((status = getaddrinfo(sourceIP, sourcePort, &hints, &servinfo)) != 0) {
|
||||||
|
LOG_E(GTPU,"getaddrinfo error: %s\n", gai_strerror(status));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop through all the results and bind to the first we can
|
||||||
|
for(p = servinfo; p != NULL; p = p->ai_next) {
|
||||||
|
if ((result->sockHandler = socket(p->ai_family, p->ai_socktype,
|
||||||
|
p->ai_protocol)) == -1) {
|
||||||
|
LOG_W(GTPU,"socket: %s\n", strerror(errno));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bind(result->sockHandler, p->ai_addr, p->ai_addrlen) == -1) {
|
||||||
|
close(result->sockHandler);
|
||||||
|
LOG_W(GTPU,"bind: %s\n", strerror(errno));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break; // if we get here, we must have connected successfully
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p == NULL) {
|
||||||
|
// looped off the end of the list with no successful bind
|
||||||
|
LOG_E(GTPU,"failed to bind socket: %s %s \n",sourceIP,sourcePort);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
freeaddrinfo(servinfo); // all done with this structure
|
||||||
|
|
||||||
|
if ((status = getaddrinfo(destIP, destPort, &hints, &servinfo)) != 0) {
|
||||||
|
LOG_E(GTPU,"getaddrinfo error: %s\n", gai_strerror(status));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (servinfo) {
|
||||||
|
result->destAddr=servinfo;
|
||||||
|
} else {
|
||||||
|
LOG_E(PHY,"No valid UDP addr: %s:%s\n",destIP, destPort);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int enable=1;
|
||||||
|
AssertFatal(setsockopt(result->sockHandler, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable))==0,"");
|
||||||
|
struct timeval tv= {0,UDP_TIMEOUT};
|
||||||
|
|
||||||
|
if (IS_SOFTMODEM_RFSIM)
|
||||||
|
tv.tv_sec=2; //debug: wait 2 seconds for human understanding
|
||||||
|
|
||||||
|
AssertFatal(setsockopt(result->sockHandler, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) ==0,"");
|
||||||
|
// Make a send/recv buffer larger than a a couple of subframe
|
||||||
|
// so the kernel will store for us in and out paquets
|
||||||
|
int buff=1000*1000*10;
|
||||||
|
AssertFatal ( setsockopt(result->sockHandler, SOL_SOCKET, SO_SNDBUF, &buff, sizeof(buff)) == 0, "");
|
||||||
|
AssertFatal ( setsockopt(result->sockHandler, SOL_SOCKET, SO_RCVBUF, &buff, sizeof(buff)) == 0, "");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sock: udp socket
|
||||||
|
// bufferZone: a reception area of bufferSize
|
||||||
|
int receiveSubFrame(UDPsock_t *sock, void *bufferZone, int bufferSize, uint16_t contentType) {
|
||||||
|
int rcved=0;
|
||||||
|
commonUDP_t *bufOrigin=(commonUDP_t *)bufferZone;
|
||||||
|
static uint8_t crossData[65536];
|
||||||
|
static int crossDataSize=0;
|
||||||
|
|
||||||
|
if (crossDataSize) {
|
||||||
|
LOG_D(HW,"copy a block received in previous subframe\n");
|
||||||
|
memcpy(bufferZone, crossData, crossDataSize);
|
||||||
|
rcved=1;
|
||||||
|
bufferZone+=crossDataSize;
|
||||||
|
crossDataSize=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
//read all subframe data from the control unit
|
||||||
|
int ret=recv(sock->sockHandler, bufferZone, bufferSize, 0);
|
||||||
|
|
||||||
|
if ( ret==-1) {
|
||||||
|
if ( errno == EWOULDBLOCK || errno== EINTR ) {
|
||||||
|
LOG_I(HW,"Received: Timeout, subframe incomplete\n");
|
||||||
|
return rcved;
|
||||||
|
} else {
|
||||||
|
LOG_E(HW,"Critical issue in socket: %s\n", strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (hUDP(bufferZone)->contentType != contentType)
|
||||||
|
abort();
|
||||||
|
|
||||||
|
if (rcved && bufOrigin->timestamp != hUDP(bufferZone)->timestamp ) {
|
||||||
|
if ( hUDP(bufferZone)->timestamp > bufOrigin->timestamp ) {
|
||||||
|
LOG_W(HW,"Received data for TS: %lu before end of TS : %lu completion\n",
|
||||||
|
hUDP(bufferZone)->timestamp,
|
||||||
|
bufOrigin->timestamp);
|
||||||
|
memcpy(crossData, bufferZone, ret );
|
||||||
|
crossDataSize=ret;
|
||||||
|
return rcved;
|
||||||
|
} else {
|
||||||
|
LOG_W(HW,"Dropping late packet\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rcved++;
|
||||||
|
bufferZone+=ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_D(HW,"Received: blocks: %d/%d, size %d, TS: %lu\n",
|
||||||
|
rcved, bufOrigin->nbBlocks, ret, bufOrigin->timestamp);
|
||||||
|
} while ( rcved == 0 || rcved < bufOrigin->nbBlocks );
|
||||||
|
|
||||||
|
return rcved;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sendSubFrame(UDPsock_t *sock, void *bufferZone, ssize_t secondHeaderSize, uint16_t contentType) {
|
||||||
|
commonUDP_t *UDPheader=(commonUDP_t *)bufferZone ;
|
||||||
|
UDPheader->contentType=contentType;
|
||||||
|
UDPheader->senderClock=rdtsc();
|
||||||
|
int nbBlocks=UDPheader->nbBlocks;
|
||||||
|
int blockId=0;
|
||||||
|
|
||||||
|
if (nbBlocks <= 0 ) {
|
||||||
|
LOG_E(PHY,"FS6: can't send blocks: %d\n", nbBlocks);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (blockId > 0 ) {
|
||||||
|
commonUDP_t *currentHeader=(commonUDP_t *)bufferZone;
|
||||||
|
currentHeader->timestamp=UDPheader->timestamp;
|
||||||
|
currentHeader->nbBlocks=UDPheader->nbBlocks;
|
||||||
|
currentHeader->blockID=blockId;
|
||||||
|
currentHeader->contentType=UDPheader->contentType;
|
||||||
|
memcpy(commonUDPdata((void *)currentHeader), commonUDPdata(bufferZone), secondHeaderSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
blockId++;
|
||||||
|
int sz=alignedSize(bufferZone);
|
||||||
|
// Let's use the first address returned by getaddrinfo()
|
||||||
|
int ret=sendto(sock->sockHandler, bufferZone, sz, 0,
|
||||||
|
sock->destAddr->ai_addr, sock->destAddr->ai_addrlen);
|
||||||
|
|
||||||
|
if ( ret != sz )
|
||||||
|
LOG_W(HW,"Wrote socket doesn't return size %d (val: %d, errno:%d, %s)\n",
|
||||||
|
sz, ret, errno, strerror(errno));
|
||||||
|
|
||||||
|
LOG_D(HW,"Sent: TS: %lu, blocks %d/%d, block size : %d \n",
|
||||||
|
UDPheader->timestamp, UDPheader->nbBlocks-nbBlocks, UDPheader->nbBlocks, sz);
|
||||||
|
bufferZone+=sz;
|
||||||
|
nbBlocks--;
|
||||||
|
} while (nbBlocks);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -29,7 +29,7 @@ typedef struct {
|
|||||||
nfapi_mode_t nfapi_mode;
|
nfapi_mode_t nfapi_mode;
|
||||||
} nfapi_params_t;
|
} nfapi_params_t;
|
||||||
|
|
||||||
static nfapi_params_t nfapi_params;
|
static nfapi_params_t nfapi_params = {0};
|
||||||
|
|
||||||
void set_thread_priority(int priority) {
|
void set_thread_priority(int priority) {
|
||||||
//printf("%s(priority:%d)\n", __FUNCTION__, priority);
|
//printf("%s(priority:%d)\n", __FUNCTION__, priority);
|
||||||
|
|||||||
@@ -691,13 +691,14 @@ void pnf_phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t *header) {
|
|||||||
free(header);
|
free(header);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pnf_phy_hi_dci0_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_hi_dci0_request_t *req) {
|
int pnf_phy_hi_dci0_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_hi_dci0_request_t *req) {
|
||||||
if (req->hi_dci0_request_body.number_of_dci == 0 && req->hi_dci0_request_body.number_of_hi == 0)
|
if (req->hi_dci0_request_body.number_of_dci == 0 && req->hi_dci0_request_body.number_of_hi == 0)
|
||||||
LOG_D(PHY,"[PNF] HI_DCI0_REQUEST SFN/SF:%05d dci:%d hi:%d\n", NFAPI_SFNSF2DEC(req->sfn_sf), req->hi_dci0_request_body.number_of_dci, req->hi_dci0_request_body.number_of_hi);
|
LOG_D(PHY,"[PNF] HI_DCI0_REQUEST SFN/SF:%05d dci:%d hi:%d\n", NFAPI_SFNSF2DEC(req->sfn_sf), req->hi_dci0_request_body.number_of_dci, req->hi_dci0_request_body.number_of_hi);
|
||||||
|
|
||||||
//phy_info* phy = (phy_info*)(pnf_p7->user_data);
|
//phy_info* phy = (phy_info*)(pnf_p7->user_data);
|
||||||
struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
|
struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
|
||||||
L1_rxtx_proc_t *proc = &eNB->proc.L1_proc;
|
if (proc ==NULL)
|
||||||
|
proc = &eNB->proc.L1_proc;
|
||||||
|
|
||||||
for (int i=0; i<req->hi_dci0_request_body.number_of_dci + req->hi_dci0_request_body.number_of_hi; i++) {
|
for (int i=0; i<req->hi_dci0_request_body.number_of_dci + req->hi_dci0_request_body.number_of_hi; i++) {
|
||||||
//LOG_D(PHY,"[PNF] HI_DCI0_REQ sfn_sf:%d PDU[%d]\n", NFAPI_SFNSF2DEC(req->sfn_sf), i);
|
//LOG_D(PHY,"[PNF] HI_DCI0_REQ sfn_sf:%d PDU[%d]\n", NFAPI_SFNSF2DEC(req->sfn_sf), i);
|
||||||
@@ -718,7 +719,7 @@ int pnf_phy_hi_dci0_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_hi_dci0_request_t *
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pnf_phy_dl_config_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_dl_config_request_t *req) {
|
int pnf_phy_dl_config_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_dl_config_request_t *req) {
|
||||||
if (RC.ru == 0) {
|
if (RC.ru == 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -739,7 +740,8 @@ int pnf_phy_dl_config_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_dl_config_request
|
|||||||
int sfn = NFAPI_SFNSF2SFN(req->sfn_sf);
|
int sfn = NFAPI_SFNSF2SFN(req->sfn_sf);
|
||||||
int sf = NFAPI_SFNSF2SF(req->sfn_sf);
|
int sf = NFAPI_SFNSF2SF(req->sfn_sf);
|
||||||
struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
|
struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
|
||||||
L1_rxtx_proc_t *proc = &eNB->proc.L1_proc;
|
if (proc==NULL)
|
||||||
|
proc = &eNB->proc.L1_proc;
|
||||||
nfapi_dl_config_request_pdu_t *dl_config_pdu_list = req->dl_config_request_body.dl_config_pdu_list;
|
nfapi_dl_config_request_pdu_t *dl_config_pdu_list = req->dl_config_request_body.dl_config_pdu_list;
|
||||||
LTE_eNB_PDCCH *pdcch_vars = &eNB->pdcch_vars[sf&1];
|
LTE_eNB_PDCCH *pdcch_vars = &eNB->pdcch_vars[sf&1];
|
||||||
pdcch_vars->num_pdcch_symbols = req->dl_config_request_body.number_pdcch_ofdm_symbols;
|
pdcch_vars->num_pdcch_symbols = req->dl_config_request_body.number_pdcch_ofdm_symbols;
|
||||||
@@ -796,7 +798,7 @@ int pnf_phy_dl_config_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_dl_config_request
|
|||||||
uint8_t *dlsch_sdu = tx_pdus[UE_id][harq_pid];
|
uint8_t *dlsch_sdu = tx_pdus[UE_id][harq_pid];
|
||||||
memcpy(dlsch_sdu, tx_pdu->segments[0].segment_data, tx_pdu->segments[0].segment_length);
|
memcpy(dlsch_sdu, tx_pdu->segments[0].segment_data, tx_pdu->segments[0].segment_length);
|
||||||
//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() DLSCH:pdu_index:%d handle_nfapi_dlsch_pdu(eNB, proc_rxtx, dlsch_pdu, transport_blocks:%d sdu:%p) eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols:%d\n", __FUNCTION__, rel8_pdu->pdu_index, rel8_pdu->transport_blocks, dlsch_sdu, eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols);
|
//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() DLSCH:pdu_index:%d handle_nfapi_dlsch_pdu(eNB, proc_rxtx, dlsch_pdu, transport_blocks:%d sdu:%p) eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols:%d\n", __FUNCTION__, rel8_pdu->pdu_index, rel8_pdu->transport_blocks, dlsch_sdu, eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols);
|
||||||
handle_nfapi_dlsch_pdu( eNB, sfn,sf, &eNB->proc.L1_proc, &dl_config_pdu_list[i], rel8_pdu->transport_blocks-1, dlsch_sdu);
|
handle_nfapi_dlsch_pdu( eNB, sfn,sf, proc, &dl_config_pdu_list[i], rel8_pdu->transport_blocks-1, dlsch_sdu);
|
||||||
} else {
|
} else {
|
||||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() DLSCH NULL TX PDU SFN/SF:%d PDU_INDEX:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), rel8_pdu->pdu_index);
|
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() DLSCH NULL TX PDU SFN/SF:%d PDU_INDEX:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), rel8_pdu->pdu_index);
|
||||||
}
|
}
|
||||||
@@ -836,7 +838,7 @@ int pnf_phy_tx_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_tx_request_t *req) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pnf_phy_ul_config_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_ul_config_request_t *req) {
|
int pnf_phy_ul_config_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_ul_config_request_t *req) {
|
||||||
if (0)LOG_D(PHY,"[PNF] UL_CONFIG_REQ %s() sfn_sf:%d pdu:%d rach_prach_frequency_resources:%d srs_present:%u\n",
|
if (0)LOG_D(PHY,"[PNF] UL_CONFIG_REQ %s() sfn_sf:%d pdu:%d rach_prach_frequency_resources:%d srs_present:%u\n",
|
||||||
__FUNCTION__,
|
__FUNCTION__,
|
||||||
NFAPI_SFNSF2DEC(req->sfn_sf),
|
NFAPI_SFNSF2DEC(req->sfn_sf),
|
||||||
@@ -865,7 +867,8 @@ int pnf_phy_ul_config_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_ul_config_request
|
|||||||
uint16_t curr_sfn = NFAPI_SFNSF2SFN(req->sfn_sf);
|
uint16_t curr_sfn = NFAPI_SFNSF2SFN(req->sfn_sf);
|
||||||
uint16_t curr_sf = NFAPI_SFNSF2SF(req->sfn_sf);
|
uint16_t curr_sf = NFAPI_SFNSF2SF(req->sfn_sf);
|
||||||
struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
|
struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
|
||||||
L1_rxtx_proc_t *proc = &eNB->proc.L1_proc;
|
if (proc==NULL)
|
||||||
|
proc = &eNB->proc.L1_proc;
|
||||||
nfapi_ul_config_request_pdu_t *ul_config_pdu_list = req->ul_config_request_body.ul_config_pdu_list;
|
nfapi_ul_config_request_pdu_t *ul_config_pdu_list = req->ul_config_request_body.ul_config_pdu_list;
|
||||||
|
|
||||||
for (int i=0; i<req->ul_config_request_body.number_of_pdus; i++) {
|
for (int i=0; i<req->ul_config_request_body.number_of_pdus; i++) {
|
||||||
|
|||||||
@@ -23,5 +23,5 @@
|
|||||||
#define NFAPI_PNF_H__
|
#define NFAPI_PNF_H__
|
||||||
int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind);
|
int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind);
|
||||||
void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);
|
void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);
|
||||||
|
void oai_subframe_ind(uint16_t sfn, uint16_t sf);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#define _NFAPI_NR_INTERFACE_H_
|
#define _NFAPI_NR_INTERFACE_H_
|
||||||
|
|
||||||
#include "nfapi_interface.h"
|
#include "nfapi_interface.h"
|
||||||
|
#include <nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h>
|
||||||
|
|
||||||
#define NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS 5
|
#define NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS 5
|
||||||
#define NFAPI_NR_MAX_NB_TCI_STATES_PDCCH 64
|
#define NFAPI_NR_MAX_NB_TCI_STATES_PDCCH 64
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ extern "C" {
|
|||||||
|
|
||||||
#include "nfapi_interface.h"
|
#include "nfapi_interface.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
#include <openair2/PHY_INTERFACE/IF_Module.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
@@ -619,21 +620,21 @@ typedef struct nfapi_pnf_p7_config
|
|||||||
* \param req A pointer to the dl config request message structure
|
* \param req A pointer to the dl config request message structure
|
||||||
* \return not currently used
|
* \return not currently used
|
||||||
*/
|
*/
|
||||||
int (*dl_config_req)(nfapi_pnf_p7_config_t* config, nfapi_dl_config_request_t* req);
|
int (*dl_config_req)(L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_dl_config_request_t* req);
|
||||||
|
|
||||||
/*! A callback for the UL_CONFIG.request
|
/*! A callback for the UL_CONFIG.request
|
||||||
* \param config A poiner to the PNF P7 config
|
* \param config A poiner to the PNF P7 config
|
||||||
* \param req A pointer to the ul config request message structure
|
* \param req A pointer to the ul config request message structure
|
||||||
* \return not currently used
|
* \return not currently used
|
||||||
*/
|
*/
|
||||||
int (*ul_config_req)(nfapi_pnf_p7_config_t* config, nfapi_ul_config_request_t* req);
|
int (*ul_config_req)(L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_ul_config_request_t* req);
|
||||||
|
|
||||||
/*! A callback for the HI_DCI0.request
|
/*! A callback for the HI_DCI0.request
|
||||||
* \param config A poiner to the PNF P7 config
|
* \param config A poiner to the PNF P7 config
|
||||||
* \param req A pointer to the hi dci0 request message structure
|
* \param req A pointer to the hi dci0 request message structure
|
||||||
* \return not currently used
|
* \return not currently used
|
||||||
*/
|
*/
|
||||||
int (*hi_dci0_req)(nfapi_pnf_p7_config_t* config, nfapi_hi_dci0_request_t* req);
|
int (*hi_dci0_req)(L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_hi_dci0_request_t* req);
|
||||||
|
|
||||||
/*! A callback for the TX_REQ.request
|
/*! A callback for the TX_REQ.request
|
||||||
* \param config A poiner to the PNF P7 config
|
* \param config A poiner to the PNF P7 config
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ nfapi_pnf_config_t* nfapi_pnf_config_create()
|
|||||||
_this->_public.codec_config.allocate = &malloc;
|
_this->_public.codec_config.allocate = &malloc;
|
||||||
_this->_public.codec_config.deallocate = &free;
|
_this->_public.codec_config.deallocate = &free;
|
||||||
|
|
||||||
return &(_this->_public);
|
return (nfapi_pnf_config_t* )_this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nfapi_pnf_config_destory(nfapi_pnf_config_t* config)
|
void nfapi_pnf_config_destory(nfapi_pnf_config_t* config)
|
||||||
|
|||||||
@@ -576,20 +576,20 @@ void send_dummy_subframe(pnf_p7_t* pnf_p7, uint16_t sfn_sf)
|
|||||||
{
|
{
|
||||||
pnf_p7->_public.dummy_subframe.dl_config_req->sfn_sf = sfn_sf;
|
pnf_p7->_public.dummy_subframe.dl_config_req->sfn_sf = sfn_sf;
|
||||||
//NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy dl_config_req - enter\n");
|
//NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy dl_config_req - enter\n");
|
||||||
(pnf_p7->_public.dl_config_req)(&(pnf_p7->_public), pnf_p7->_public.dummy_subframe.dl_config_req);
|
(pnf_p7->_public.dl_config_req)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_subframe.dl_config_req);
|
||||||
//NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy dl_config_req - exit\n");
|
//NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy dl_config_req - exit\n");
|
||||||
}
|
}
|
||||||
if(pnf_p7->_public.ul_config_req && pnf_p7->_public.dummy_subframe.ul_config_req)
|
if(pnf_p7->_public.ul_config_req && pnf_p7->_public.dummy_subframe.ul_config_req)
|
||||||
{
|
{
|
||||||
pnf_p7->_public.dummy_subframe.ul_config_req->sfn_sf = sfn_sf;
|
pnf_p7->_public.dummy_subframe.ul_config_req->sfn_sf = sfn_sf;
|
||||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy ul_config_req - enter\n");
|
NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy ul_config_req - enter\n");
|
||||||
(pnf_p7->_public.ul_config_req)(&pnf_p7->_public, pnf_p7->_public.dummy_subframe.ul_config_req);
|
(pnf_p7->_public.ul_config_req)(NULL, &pnf_p7->_public, pnf_p7->_public.dummy_subframe.ul_config_req);
|
||||||
}
|
}
|
||||||
if(pnf_p7->_public.hi_dci0_req && pnf_p7->_public.dummy_subframe.hi_dci0_req)
|
if(pnf_p7->_public.hi_dci0_req && pnf_p7->_public.dummy_subframe.hi_dci0_req)
|
||||||
{
|
{
|
||||||
pnf_p7->_public.dummy_subframe.hi_dci0_req->sfn_sf = sfn_sf;
|
pnf_p7->_public.dummy_subframe.hi_dci0_req->sfn_sf = sfn_sf;
|
||||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy hi_dci0 - enter\n");
|
NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy hi_dci0 - enter\n");
|
||||||
(pnf_p7->_public.hi_dci0_req)(&pnf_p7->_public, pnf_p7->_public.dummy_subframe.hi_dci0_req);
|
(pnf_p7->_public.hi_dci0_req)(NULL, &pnf_p7->_public, pnf_p7->_public.dummy_subframe.hi_dci0_req);
|
||||||
}
|
}
|
||||||
if(pnf_p7->_public.lbt_dl_config_req && pnf_p7->_public.dummy_subframe.lbt_dl_config_req)
|
if(pnf_p7->_public.lbt_dl_config_req && pnf_p7->_public.dummy_subframe.lbt_dl_config_req)
|
||||||
{
|
{
|
||||||
@@ -699,7 +699,7 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf)
|
|||||||
if(tx_subframe_buffer->dl_config_req != 0)
|
if(tx_subframe_buffer->dl_config_req != 0)
|
||||||
{
|
{
|
||||||
if(pnf_p7->_public.dl_config_req)
|
if(pnf_p7->_public.dl_config_req)
|
||||||
(pnf_p7->_public.dl_config_req)(&(pnf_p7->_public), tx_subframe_buffer->dl_config_req);
|
(pnf_p7->_public.dl_config_req)(NULL, &(pnf_p7->_public), tx_subframe_buffer->dl_config_req);
|
||||||
|
|
||||||
//deallocate_nfapi_dl_config_request(subframe_buffer->dl_config_req, pnf_p7);
|
//deallocate_nfapi_dl_config_request(subframe_buffer->dl_config_req, pnf_p7);
|
||||||
}
|
}
|
||||||
@@ -709,14 +709,14 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf)
|
|||||||
if(pnf_p7->_public.dl_config_req && pnf_p7->_public.dummy_subframe.dl_config_req)
|
if(pnf_p7->_public.dl_config_req && pnf_p7->_public.dummy_subframe.dl_config_req)
|
||||||
{
|
{
|
||||||
pnf_p7->_public.dummy_subframe.dl_config_req->sfn_sf = sfn_sf_tx;
|
pnf_p7->_public.dummy_subframe.dl_config_req->sfn_sf = sfn_sf_tx;
|
||||||
(pnf_p7->_public.dl_config_req)(&(pnf_p7->_public), pnf_p7->_public.dummy_subframe.dl_config_req);
|
(pnf_p7->_public.dl_config_req)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_subframe.dl_config_req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tx_subframe_buffer->hi_dci0_req != 0)
|
if(tx_subframe_buffer->hi_dci0_req != 0)
|
||||||
{
|
{
|
||||||
if(pnf_p7->_public.hi_dci0_req)
|
if(pnf_p7->_public.hi_dci0_req)
|
||||||
(pnf_p7->_public.hi_dci0_req)(&(pnf_p7->_public), tx_subframe_buffer->hi_dci0_req);
|
(pnf_p7->_public.hi_dci0_req)(NULL, &(pnf_p7->_public), tx_subframe_buffer->hi_dci0_req);
|
||||||
|
|
||||||
//deallocate_nfapi_hi_dci0_request(subframe_buffer->hi_dci0_req, pnf_p7);
|
//deallocate_nfapi_hi_dci0_request(subframe_buffer->hi_dci0_req, pnf_p7);
|
||||||
}
|
}
|
||||||
@@ -726,7 +726,7 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf)
|
|||||||
if(pnf_p7->_public.hi_dci0_req && pnf_p7->_public.dummy_subframe.hi_dci0_req)
|
if(pnf_p7->_public.hi_dci0_req && pnf_p7->_public.dummy_subframe.hi_dci0_req)
|
||||||
{
|
{
|
||||||
pnf_p7->_public.dummy_subframe.hi_dci0_req->sfn_sf = sfn_sf_tx;
|
pnf_p7->_public.dummy_subframe.hi_dci0_req->sfn_sf = sfn_sf_tx;
|
||||||
(pnf_p7->_public.hi_dci0_req)(&(pnf_p7->_public), pnf_p7->_public.dummy_subframe.hi_dci0_req);
|
(pnf_p7->_public.hi_dci0_req)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_subframe.hi_dci0_req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -777,7 +777,7 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf)
|
|||||||
if(subframe_buffer->ul_config_req != 0)
|
if(subframe_buffer->ul_config_req != 0)
|
||||||
{
|
{
|
||||||
if(pnf_p7->_public.ul_config_req)
|
if(pnf_p7->_public.ul_config_req)
|
||||||
(pnf_p7->_public.ul_config_req)(&(pnf_p7->_public), subframe_buffer->ul_config_req);
|
(pnf_p7->_public.ul_config_req)(NULL, &(pnf_p7->_public), subframe_buffer->ul_config_req);
|
||||||
|
|
||||||
//deallocate_nfapi_ul_config_request(subframe_buffer->ul_config_req, pnf_p7);
|
//deallocate_nfapi_ul_config_request(subframe_buffer->ul_config_req, pnf_p7);
|
||||||
}
|
}
|
||||||
@@ -787,7 +787,7 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf)
|
|||||||
if(pnf_p7->_public.ul_config_req && pnf_p7->_public.dummy_subframe.ul_config_req)
|
if(pnf_p7->_public.ul_config_req && pnf_p7->_public.dummy_subframe.ul_config_req)
|
||||||
{
|
{
|
||||||
pnf_p7->_public.dummy_subframe.ul_config_req->sfn_sf = sfn_sf;
|
pnf_p7->_public.dummy_subframe.ul_config_req->sfn_sf = sfn_sf;
|
||||||
(pnf_p7->_public.ul_config_req)(&(pnf_p7->_public), pnf_p7->_public.dummy_subframe.ul_config_req);
|
(pnf_p7->_public.ul_config_req)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_subframe.ul_config_req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ nfapi_vnf_config_t* nfapi_vnf_config_create()
|
|||||||
_this->_public.codec_config.deallocate = &free;
|
_this->_public.codec_config.deallocate = &free;
|
||||||
|
|
||||||
|
|
||||||
return &(_this->_public);
|
return (nfapi_vnf_config_t* )_this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nfapi_vnf_config_destory(nfapi_vnf_config_t* config)
|
void nfapi_vnf_config_destory(nfapi_vnf_config_t* config)
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ nfapi_vnf_p7_config_t* nfapi_vnf_p7_config_create()
|
|||||||
_this->_public.codec_config.deallocate = &free;
|
_this->_public.codec_config.deallocate = &free;
|
||||||
|
|
||||||
|
|
||||||
return &(_this->_public);
|
return (nfapi_vnf_p7_config_t*)_this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nfapi_vnf_p7_config_destory(nfapi_vnf_p7_config_t* config)
|
void nfapi_vnf_p7_config_destory(nfapi_vnf_p7_config_t* config)
|
||||||
|
|||||||
@@ -529,7 +529,7 @@ int main(int argc, char *argv[])
|
|||||||
time_stats_t time_optim[10], time_decoder[10];
|
time_stats_t time_optim[10], time_decoder[10];
|
||||||
n_iter_stats_t dec_iter[3];
|
n_iter_stats_t dec_iter[3];
|
||||||
|
|
||||||
short BG=0,Zc,Kb;
|
short BG=0,Zc,Kb=0;
|
||||||
|
|
||||||
while ((c = getopt (argc, argv, "q:r:s:S:l:n:d:i:t:u:h")) != -1)
|
while ((c = getopt (argc, argv, "q:r:s:S:l:n:d:i:t:u:h")) != -1)
|
||||||
switch (c)
|
switch (c)
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue,
|
|||||||
uint8_t pilot0,pilot1,pilot2,pilot3;
|
uint8_t pilot0,pilot1,pilot2,pilot3;
|
||||||
|
|
||||||
short ch[2], *pil, *rxF, *dl_bf_ch, *dl_bf_ch_prev;
|
short ch[2], *pil, *rxF, *dl_bf_ch, *dl_bf_ch_prev;
|
||||||
short *fl, *fm, *fr, *fl_dc, *fm_dc, *fr_dc, *f1, *f2l, *f2r;
|
short *fl=NULL, *fm=NULL, *fr=NULL, *fl_dc=NULL, *fm_dc=NULL, *fr_dc=NULL, *f1, *f2l=NULL, *f2r=NULL;
|
||||||
|
|
||||||
unsigned int *rballoc;
|
unsigned int *rballoc;
|
||||||
int **rxdataF;
|
int **rxdataF;
|
||||||
|
|||||||
@@ -1029,7 +1029,7 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
|
|||||||
int N_RB_DL = frame_parms->N_RB_DL;
|
int N_RB_DL = frame_parms->N_RB_DL;
|
||||||
|
|
||||||
|
|
||||||
int rank_tm3_tm4;
|
int rank_tm3_tm4=-1;
|
||||||
|
|
||||||
|
|
||||||
ue->measurements.nb_antennas_rx = frame_parms->nb_antennas_rx;
|
ue->measurements.nb_antennas_rx = frame_parms->nb_antennas_rx;
|
||||||
|
|||||||
@@ -50,8 +50,11 @@ int32_t lte_ul_channel_estimation(PHY_VARS_eNB *eNB,
|
|||||||
int32_t **ul_ch_estimates_time = (eNB!=NULL) ? pusch_vars->drs_ch_estimates_time : calibration->drs_ch_estimates_time;
|
int32_t **ul_ch_estimates_time = (eNB!=NULL) ? pusch_vars->drs_ch_estimates_time : calibration->drs_ch_estimates_time;
|
||||||
AssertFatal(ul_ch_estimates_time != NULL, "ul_ch_estimates_time is null\n");
|
AssertFatal(ul_ch_estimates_time != NULL, "ul_ch_estimates_time is null\n");
|
||||||
int32_t **rxdataF_ext = (eNB!=NULL) ? pusch_vars->rxdataF_ext : calibration->rxdataF_ext;
|
int32_t **rxdataF_ext = (eNB!=NULL) ? pusch_vars->rxdataF_ext : calibration->rxdataF_ext;
|
||||||
int subframe = (eNB!=NULL) ? proc->subframe_rx : ru->proc.tti_rx;
|
|
||||||
|
int subframe = proc->subframe_rx;
|
||||||
|
|
||||||
uint8_t harq_pid;
|
uint8_t harq_pid;
|
||||||
|
|
||||||
int16_t delta_phase = 0;
|
int16_t delta_phase = 0;
|
||||||
int16_t *ru1 = ru_90;
|
int16_t *ru1 = ru_90;
|
||||||
int16_t *ru2 = ru_90;
|
int16_t *ru2 = ru_90;
|
||||||
|
|||||||
@@ -42,7 +42,8 @@
|
|||||||
#include "common/utils/LOG/log.h"
|
#include "common/utils/LOG/log.h"
|
||||||
#include "targets/RT/USER/lte-softmodem.h"
|
#include "targets/RT/USER/lte-softmodem.h"
|
||||||
#include <syscall.h>
|
#include <syscall.h>
|
||||||
#include "executables/thread-common.h"
|
#include "targets/RT/USER/rt_wrapper.h"
|
||||||
|
#include <common/utils/threadPool/thread-pool.h>
|
||||||
|
|
||||||
//#define DEBUG_DLSCH_CODING
|
//#define DEBUG_DLSCH_CODING
|
||||||
//#define DEBUG_DLSCH_FREE 1
|
//#define DEBUG_DLSCH_FREE 1
|
||||||
@@ -83,11 +84,6 @@ void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch) {
|
|||||||
free16(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768);
|
free16(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768);
|
||||||
dlsch->harq_processes[i]->c[r] = NULL;
|
dlsch->harq_processes[i]->c[r] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dlsch->harq_processes[i]->d[r]) {
|
|
||||||
free16(dlsch->harq_processes[i]->d[r],(96+12+3+(3*6144)));
|
|
||||||
dlsch->harq_processes[i]->d[r] = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free16(dlsch->harq_processes[i],sizeof(LTE_DL_eNB_HARQ_t));
|
free16(dlsch->harq_processes[i],sizeof(LTE_DL_eNB_HARQ_t));
|
||||||
@@ -108,7 +104,7 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,
|
|||||||
LTE_DL_FRAME_PARMS *frame_parms)
|
LTE_DL_FRAME_PARMS *frame_parms)
|
||||||
{
|
{
|
||||||
LTE_eNB_DLSCH_t *dlsch;
|
LTE_eNB_DLSCH_t *dlsch;
|
||||||
unsigned char exit_flag = 0,i,j,r,aa,layer;
|
unsigned char exit_flag = 0,i,r,aa,layer;
|
||||||
int re;
|
int re;
|
||||||
unsigned char bw_scaling =1;
|
unsigned char bw_scaling =1;
|
||||||
|
|
||||||
@@ -183,7 +179,6 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,
|
|||||||
for (r=0; r<MAX_NUM_DLSCH_SEGMENTS/bw_scaling; r++) {
|
for (r=0; r<MAX_NUM_DLSCH_SEGMENTS/bw_scaling; r++) {
|
||||||
// account for filler in first segment and CRCs for multiple segment case
|
// account for filler in first segment and CRCs for multiple segment case
|
||||||
dlsch->harq_processes[i]->c[r] = (uint8_t *)malloc16(((r==0)?8:0) + 3+ 768);
|
dlsch->harq_processes[i]->c[r] = (uint8_t *)malloc16(((r==0)?8:0) + 3+ 768);
|
||||||
dlsch->harq_processes[i]->d[r] = (uint8_t *)malloc16((96+12+3+(3*6144)));
|
|
||||||
|
|
||||||
if (dlsch->harq_processes[i]->c[r]) {
|
if (dlsch->harq_processes[i]->c[r]) {
|
||||||
bzero(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+ 768);
|
bzero(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+ 768);
|
||||||
@@ -191,13 +186,6 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,
|
|||||||
printf("Can't get c\n");
|
printf("Can't get c\n");
|
||||||
exit_flag=2;
|
exit_flag=2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dlsch->harq_processes[i]->d[r]) {
|
|
||||||
bzero(dlsch->harq_processes[i]->d[r],(96+12+3+(3*6144)));
|
|
||||||
} else {
|
|
||||||
printf("Can't get d\n");
|
|
||||||
exit_flag=2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -209,13 +197,6 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,
|
|||||||
if (exit_flag==0) {
|
if (exit_flag==0) {
|
||||||
for (i=0; i<Mdlharq; i++) {
|
for (i=0; i<Mdlharq; i++) {
|
||||||
dlsch->harq_processes[i]->round=0;
|
dlsch->harq_processes[i]->round=0;
|
||||||
|
|
||||||
for (j=0; j<96; j++)
|
|
||||||
for (r=0; r<MAX_NUM_DLSCH_SEGMENTS/bw_scaling; r++) {
|
|
||||||
// printf("dlsch->harq_processes[%d]->d[%d] %p\n",i,r,dlsch->harq_processes[i]->d[r]);
|
|
||||||
if (dlsch->harq_processes[i]->d[r])
|
|
||||||
dlsch->harq_processes[i]->d[r][j] = LTE_NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return(dlsch);
|
return(dlsch);
|
||||||
@@ -231,7 +212,7 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,
|
|||||||
|
|
||||||
void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch) {
|
void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch) {
|
||||||
unsigned char Mdlharq;
|
unsigned char Mdlharq;
|
||||||
unsigned char i,j,r;
|
unsigned char i;
|
||||||
|
|
||||||
if (dlsch) {
|
if (dlsch) {
|
||||||
Mdlharq = dlsch->Mdlharq;
|
Mdlharq = dlsch->Mdlharq;
|
||||||
@@ -255,307 +236,17 @@ void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch) {
|
|||||||
dlsch->harq_processes[i]->status = 0;
|
dlsch->harq_processes[i]->status = 0;
|
||||||
dlsch->harq_processes[i]->round = 0;
|
dlsch->harq_processes[i]->round = 0;
|
||||||
|
|
||||||
for (j=0; j<96; j++)
|
|
||||||
for (r=0; r<MAX_NUM_DLSCH_SEGMENTS; r++)
|
|
||||||
if (dlsch->harq_processes[i]->d[r])
|
|
||||||
dlsch->harq_processes[i]->d[r][j] = LTE_NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int dlsch_encoding_2threads0(te_params *tep) {
|
|
||||||
LTE_eNB_DLSCH_t *dlsch = tep->dlsch;
|
|
||||||
unsigned int G = tep->G;
|
|
||||||
unsigned char harq_pid = tep->harq_pid;
|
|
||||||
unsigned int total_worker = tep->total_worker;
|
|
||||||
unsigned int current_worker = tep->current_worker;
|
|
||||||
unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb;
|
|
||||||
unsigned int Kr=0,Kr_bytes,r,r_offset=0;
|
|
||||||
// unsigned short m=dlsch->harq_processes[harq_pid]->mcs;
|
|
||||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING_W, VCD_FUNCTION_IN);
|
|
||||||
|
|
||||||
if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet
|
|
||||||
for (r=(dlsch->harq_processes[harq_pid]->C/(total_worker+1))*current_worker; r<(dlsch->harq_processes[harq_pid]->C/(total_worker+1))*(current_worker+1); r++) {
|
|
||||||
if (r<dlsch->harq_processes[harq_pid]->Cminus)
|
|
||||||
Kr = dlsch->harq_processes[harq_pid]->Kminus;
|
|
||||||
else
|
|
||||||
Kr = dlsch->harq_processes[harq_pid]->Kplus;
|
|
||||||
|
|
||||||
Kr_bytes = Kr>>3;
|
|
||||||
encoder(dlsch->harq_processes[harq_pid]->c[r],
|
|
||||||
Kr>>3,
|
|
||||||
&dlsch->harq_processes[harq_pid]->d[r][96],
|
|
||||||
(r==0) ? dlsch->harq_processes[harq_pid]->F : 0
|
|
||||||
);
|
|
||||||
dlsch->harq_processes[harq_pid]->RTC[r] =
|
|
||||||
sub_block_interleaving_turbo(4+(Kr_bytes*8),
|
|
||||||
&dlsch->harq_processes[harq_pid]->d[r][96],
|
|
||||||
dlsch->harq_processes[harq_pid]->w[r]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
|
|
||||||
// outputs for each code segment, see Section 5.1.5 p.20
|
|
||||||
|
|
||||||
for (r=0,r_offset=0; r<(dlsch->harq_processes[harq_pid]->C/(total_worker+1))*(current_worker+1); r++) {
|
|
||||||
if(r<(dlsch->harq_processes[harq_pid]->C/(total_worker+1))*(current_worker)) {
|
|
||||||
int Nl=dlsch->harq_processes[harq_pid]->Nl;
|
|
||||||
int Qm=dlsch->harq_processes[harq_pid]->Qm;
|
|
||||||
int C = dlsch->harq_processes[harq_pid]->C;
|
|
||||||
int Gp = G/Nl/Qm;
|
|
||||||
int GpmodC = Gp%C;
|
|
||||||
|
|
||||||
if (r < (C-(GpmodC)))
|
|
||||||
r_offset += Nl*Qm * (Gp/C);
|
|
||||||
else
|
|
||||||
r_offset += Nl*Qm * ((GpmodC==0?0:1) + (Gp/C));
|
|
||||||
} else {
|
|
||||||
r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
|
|
||||||
G, //G
|
|
||||||
dlsch->harq_processes[harq_pid]->w[r],
|
|
||||||
dlsch->harq_processes[harq_pid]->e+r_offset,
|
|
||||||
dlsch->harq_processes[harq_pid]->C, // C
|
|
||||||
dlsch->Nsoft, // Nsoft,
|
|
||||||
dlsch->Mdlharq,
|
|
||||||
dlsch->Kmimo,
|
|
||||||
dlsch->harq_processes[harq_pid]->rvidx,
|
|
||||||
dlsch->harq_processes[harq_pid]->Qm,
|
|
||||||
dlsch->harq_processes[harq_pid]->Nl,
|
|
||||||
r,
|
|
||||||
nb_rb);
|
|
||||||
// m); // r
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING_W, VCD_FUNCTION_OUT);
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void *te_thread(void *param) {
|
void *te_thread(void *param) {
|
||||||
te_params *tep = (te_params *)param;
|
|
||||||
|
|
||||||
//wait_sync("te_thread");
|
|
||||||
|
|
||||||
while (!oai_exit) {
|
|
||||||
if (wait_on_condition(&tep->mutex_te,&tep->cond_te,&tep->instance_cnt_te,"te thread")<0) break;
|
|
||||||
|
|
||||||
if(oai_exit) break;
|
|
||||||
|
|
||||||
dlsch_encoding_2threads0(tep);
|
|
||||||
|
|
||||||
if (release_thread(&tep->mutex_te,&tep->instance_cnt_te,"te thread")<0) break;
|
|
||||||
|
|
||||||
if (pthread_cond_signal(&tep->cond_te) != 0) {
|
|
||||||
printf("[eNB] ERROR pthread_cond_signal for te thread exit\n");
|
|
||||||
exit_fun( "ERROR pthread_cond_signal" );
|
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if(opp_enabled == 1 && te_wakeup_stats0->p_time>50*3000){
|
|
||||||
print_meas_now(te_wakeup_stats0,"coding_wakeup",stderr);
|
|
||||||
printf("te_thread0 delay for waking up in frame_rx: %d subframe_rx: %d \n",proc->frame_rx,proc->subframe_rx);
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
|
|
||||||
unsigned char *a,
|
|
||||||
uint8_t num_pdcch_symbols,
|
|
||||||
LTE_eNB_DLSCH_t *dlsch,
|
|
||||||
int frame,
|
|
||||||
uint8_t subframe,
|
|
||||||
time_stats_t *rm_stats,
|
|
||||||
time_stats_t *te_stats,
|
|
||||||
time_stats_t *te_wait_stats,
|
|
||||||
time_stats_t *te_main_stats,
|
|
||||||
time_stats_t *te_wakeup_stats0,
|
|
||||||
time_stats_t *te_wakeup_stats1,
|
|
||||||
time_stats_t *i_stats,
|
|
||||||
int worker_num) {
|
|
||||||
//start_meas(&eNB->dlsch_turbo_encoding_preperation_stats);
|
|
||||||
LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
|
|
||||||
L1_proc_t *proc = &eNB->proc;
|
|
||||||
unsigned int G;
|
|
||||||
unsigned int crc=1;
|
|
||||||
unsigned char harq_pid = dlsch->harq_ids[frame%2][subframe];
|
|
||||||
if((harq_pid < 0) || (harq_pid >= dlsch->Mdlharq)) {
|
|
||||||
LOG_E(PHY,"dlsch_encoding_2threads illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__);
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb;
|
|
||||||
unsigned int A;
|
|
||||||
unsigned char mod_order;
|
|
||||||
unsigned int Kr=0,Kr_bytes,r,r_offset=0;
|
|
||||||
// unsigned short m=dlsch->harq_processes[harq_pid]->mcs;
|
|
||||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN);
|
|
||||||
A = dlsch->harq_processes[harq_pid]->TBS; //6228
|
|
||||||
mod_order = dlsch->harq_processes[harq_pid]->Qm;
|
|
||||||
G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe,
|
|
||||||
dlsch->harq_processes[harq_pid]->mimo_mode==TM7?7:0);
|
|
||||||
|
|
||||||
if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet
|
|
||||||
start_meas(&eNB->dlsch_turbo_encoding_preperation_stats);
|
|
||||||
// Add 24-bit crc (polynomial A) to payload
|
|
||||||
crc = crc24a(a,
|
|
||||||
A)>>8;
|
|
||||||
stop_meas(&eNB->dlsch_turbo_encoding_preperation_stats);
|
|
||||||
a[A>>3] = ((uint8_t *)&crc)[2];
|
|
||||||
a[1+(A>>3)] = ((uint8_t *)&crc)[1];
|
|
||||||
a[2+(A>>3)] = ((uint8_t *)&crc)[0];
|
|
||||||
dlsch->harq_processes[harq_pid]->B = A+24;
|
|
||||||
memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4);
|
|
||||||
//stop_meas(&eNB->dlsch_turbo_encoding_preperation_stats);
|
|
||||||
start_meas(&eNB->dlsch_turbo_encoding_segmentation_stats);
|
|
||||||
|
|
||||||
if (lte_segmentation(dlsch->harq_processes[harq_pid]->b,
|
|
||||||
dlsch->harq_processes[harq_pid]->c,
|
|
||||||
dlsch->harq_processes[harq_pid]->B,
|
|
||||||
&dlsch->harq_processes[harq_pid]->C,
|
|
||||||
&dlsch->harq_processes[harq_pid]->Cplus,
|
|
||||||
&dlsch->harq_processes[harq_pid]->Cminus,
|
|
||||||
&dlsch->harq_processes[harq_pid]->Kplus,
|
|
||||||
&dlsch->harq_processes[harq_pid]->Kminus,
|
|
||||||
&dlsch->harq_processes[harq_pid]->F)<0)
|
|
||||||
return(-1);
|
|
||||||
|
|
||||||
stop_meas(&eNB->dlsch_turbo_encoding_segmentation_stats);
|
|
||||||
start_meas(&eNB->dlsch_turbo_encoding_signal_stats);
|
|
||||||
|
|
||||||
for(int i=0; i<worker_num; i++) {
|
|
||||||
proc->tep[i].eNB = eNB;
|
|
||||||
proc->tep[i].dlsch = dlsch;
|
|
||||||
proc->tep[i].G = G;
|
|
||||||
proc->tep[i].harq_pid = harq_pid;
|
|
||||||
proc->tep[i].total_worker = worker_num;
|
|
||||||
proc->tep[i].current_worker = i;
|
|
||||||
pthread_mutex_lock( &proc->tep[i].mutex_te );
|
|
||||||
|
|
||||||
if (proc->tep[i].instance_cnt_te==0) {
|
|
||||||
printf("[eNB] TE thread busy\n");
|
|
||||||
exit_fun("TE thread busy");
|
|
||||||
pthread_mutex_unlock( &proc->tep[i].mutex_te );
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
++proc->tep[i].instance_cnt_te;
|
|
||||||
|
|
||||||
// wakeup worker to do segments
|
|
||||||
if (pthread_cond_signal(&proc->tep[i].cond_te) != 0) {
|
|
||||||
printf("[eNB] ERROR pthread_cond_signal for te thread %d exit\n",i);
|
|
||||||
exit_fun( "ERROR pthread_cond_signal" );
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_unlock( &proc->tep[i].mutex_te );
|
|
||||||
}
|
|
||||||
|
|
||||||
stop_meas(&eNB->dlsch_turbo_encoding_signal_stats);
|
|
||||||
start_meas(te_main_stats);
|
|
||||||
|
|
||||||
for (r=(dlsch->harq_processes[harq_pid]->C/(worker_num+1))*worker_num; r<dlsch->harq_processes[harq_pid]->C; r++) {
|
|
||||||
if (r<dlsch->harq_processes[harq_pid]->Cminus)
|
|
||||||
Kr = dlsch->harq_processes[harq_pid]->Kminus;
|
|
||||||
else
|
|
||||||
Kr = dlsch->harq_processes[harq_pid]->Kplus;
|
|
||||||
|
|
||||||
Kr_bytes = Kr>>3;
|
|
||||||
start_meas(te_stats);
|
|
||||||
encoder(dlsch->harq_processes[harq_pid]->c[r],
|
|
||||||
Kr>>3,
|
|
||||||
&dlsch->harq_processes[harq_pid]->d[r][96],
|
|
||||||
(r==0) ? dlsch->harq_processes[harq_pid]->F : 0
|
|
||||||
);
|
|
||||||
stop_meas(te_stats);
|
|
||||||
start_meas(i_stats);
|
|
||||||
dlsch->harq_processes[harq_pid]->RTC[r] =
|
|
||||||
sub_block_interleaving_turbo(4+(Kr_bytes*8),
|
|
||||||
&dlsch->harq_processes[harq_pid]->d[r][96],
|
|
||||||
dlsch->harq_processes[harq_pid]->w[r]);
|
|
||||||
stop_meas(i_stats);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for(int i=0; i<worker_num; i++) {
|
|
||||||
proc->tep[i].eNB = eNB;
|
|
||||||
proc->tep[i].dlsch = dlsch;
|
|
||||||
proc->tep[i].G = G;
|
|
||||||
proc->tep[i].total_worker = worker_num;
|
|
||||||
proc->tep[i].current_worker = i;
|
|
||||||
|
|
||||||
if (pthread_cond_signal(&proc->tep[i].cond_te) != 0) {
|
|
||||||
printf("[eNB] ERROR pthread_cond_signal for te thread exit\n");
|
|
||||||
exit_fun( "ERROR pthread_cond_signal" );
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
|
|
||||||
// outputs for each code segment, see Section 5.1.5 p.20
|
|
||||||
for (r=0,r_offset=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
|
|
||||||
// get information for E for the segments that are handled by the worker thread
|
|
||||||
if (r<(dlsch->harq_processes[harq_pid]->C/(worker_num+1))*worker_num) {
|
|
||||||
int Nl=dlsch->harq_processes[harq_pid]->Nl;
|
|
||||||
int Qm=dlsch->harq_processes[harq_pid]->Qm;
|
|
||||||
int C = dlsch->harq_processes[harq_pid]->C;
|
|
||||||
int Gp = G/Nl/Qm;
|
|
||||||
int GpmodC = Gp%C;
|
|
||||||
|
|
||||||
if (r < (C-(GpmodC)))
|
|
||||||
r_offset += Nl*Qm * (Gp/C);
|
|
||||||
else
|
|
||||||
r_offset += Nl*Qm * ((GpmodC==0?0:1) + (Gp/C));
|
|
||||||
} else {
|
|
||||||
start_meas(rm_stats);
|
|
||||||
r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
|
|
||||||
G, //G
|
|
||||||
dlsch->harq_processes[harq_pid]->w[r],
|
|
||||||
dlsch->harq_processes[harq_pid]->e+r_offset,
|
|
||||||
dlsch->harq_processes[harq_pid]->C, // C
|
|
||||||
dlsch->Nsoft, // Nsoft,
|
|
||||||
dlsch->Mdlharq,
|
|
||||||
dlsch->Kmimo,
|
|
||||||
dlsch->harq_processes[harq_pid]->rvidx,
|
|
||||||
dlsch->harq_processes[harq_pid]->Qm,
|
|
||||||
dlsch->harq_processes[harq_pid]->Nl,
|
|
||||||
r,
|
|
||||||
nb_rb);
|
|
||||||
// m); // r
|
|
||||||
stop_meas(rm_stats);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stop_meas(te_main_stats);
|
|
||||||
start_meas(te_wait_stats);
|
|
||||||
|
|
||||||
if(worker_num == 1) {
|
|
||||||
wait_on_busy_condition(&proc->tep[0].mutex_te,&proc->tep[0].cond_te,&proc->tep[0].instance_cnt_te,"te thread 0");
|
|
||||||
} else if(worker_num == 2) {
|
|
||||||
wait_on_busy_condition(&proc->tep[0].mutex_te,&proc->tep[0].cond_te,&proc->tep[0].instance_cnt_te,"te thread 0");
|
|
||||||
wait_on_busy_condition(&proc->tep[1].mutex_te,&proc->tep[1].cond_te,&proc->tep[1].instance_cnt_te,"te thread 1");
|
|
||||||
} else {
|
|
||||||
wait_on_busy_condition(&proc->tep[0].mutex_te,&proc->tep[0].cond_te,&proc->tep[0].instance_cnt_te,"te thread 0");
|
|
||||||
wait_on_busy_condition(&proc->tep[1].mutex_te,&proc->tep[1].cond_te,&proc->tep[1].instance_cnt_te,"te thread 1");
|
|
||||||
wait_on_busy_condition(&proc->tep[2].mutex_te,&proc->tep[2].cond_te,&proc->tep[2].instance_cnt_te,"te thread 2");
|
|
||||||
}
|
|
||||||
|
|
||||||
stop_meas(te_wait_stats);
|
|
||||||
/*if(opp_enabled == 1 && te_wait_stats->p_time>100*3000){
|
|
||||||
print_meas_now(te_wait_stats,"coding_wait",stderr);
|
|
||||||
printf("coding delay in wait on codition in frame_rx: %d \n",proc->frame_rx);
|
|
||||||
}*/
|
|
||||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int dlsch_encoding_all(PHY_VARS_eNB *eNB,
|
int dlsch_encoding_all(PHY_VARS_eNB *eNB,
|
||||||
|
L1_rxtx_proc_t *proc,
|
||||||
unsigned char *a,
|
unsigned char *a,
|
||||||
uint8_t num_pdcch_symbols,
|
uint8_t num_pdcch_symbols,
|
||||||
LTE_eNB_DLSCH_t *dlsch,
|
LTE_eNB_DLSCH_t *dlsch,
|
||||||
@@ -568,93 +259,18 @@ int dlsch_encoding_all(PHY_VARS_eNB *eNB,
|
|||||||
time_stats_t *te_wakeup_stats0,
|
time_stats_t *te_wakeup_stats0,
|
||||||
time_stats_t *te_wakeup_stats1,
|
time_stats_t *te_wakeup_stats1,
|
||||||
time_stats_t *i_stats) {
|
time_stats_t *i_stats) {
|
||||||
int encoding_return = 0;
|
|
||||||
unsigned int L,C,B;
|
|
||||||
uint8_t harq_pid = dlsch->harq_ids[frame%2][subframe];
|
uint8_t harq_pid = dlsch->harq_ids[frame%2][subframe];
|
||||||
if(harq_pid >= dlsch->Mdlharq) {
|
if(harq_pid >= dlsch->Mdlharq) {
|
||||||
LOG_E(PHY,"dlsch_encoding_all illegal harq_pid %d\n", harq_pid);
|
LOG_E(PHY,"dlsch_encoding_all illegal harq_pid %d\n", harq_pid);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
B = dlsch->harq_processes[harq_pid]->B;
|
|
||||||
|
|
||||||
LOG_D(PHY,"B %d, harq_pid %d\n",B,dlsch->harq_ids[frame%2][subframe]);
|
LOG_D(PHY,"B %d, harq_pid %d\n",
|
||||||
|
dlsch->harq_processes[harq_pid]->B,
|
||||||
|
dlsch->harq_ids[frame%2][subframe]);
|
||||||
|
|
||||||
if(B<=6144) {
|
return dlsch_encoding(eNB,
|
||||||
L=0;
|
proc,
|
||||||
C=1;
|
|
||||||
} else {
|
|
||||||
L=24;
|
|
||||||
C = B/(6144-L);
|
|
||||||
|
|
||||||
if((6144-L)*C < B) {
|
|
||||||
C = C+1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(get_thread_worker_conf() == WORKER_ENABLE) {
|
|
||||||
if(C >= 8) { //one main three worker
|
|
||||||
encoding_return =
|
|
||||||
dlsch_encoding_2threads(eNB,
|
|
||||||
a,
|
|
||||||
num_pdcch_symbols,
|
|
||||||
dlsch,
|
|
||||||
frame,
|
|
||||||
subframe,
|
|
||||||
rm_stats,
|
|
||||||
te_stats,
|
|
||||||
te_wait_stats,
|
|
||||||
te_main_stats,
|
|
||||||
te_wakeup_stats0,
|
|
||||||
te_wakeup_stats1,
|
|
||||||
i_stats,
|
|
||||||
3);
|
|
||||||
} else if(C >= 6) { //one main two worker
|
|
||||||
encoding_return =
|
|
||||||
dlsch_encoding_2threads(eNB,
|
|
||||||
a,
|
|
||||||
num_pdcch_symbols,
|
|
||||||
dlsch,
|
|
||||||
frame,
|
|
||||||
subframe,
|
|
||||||
rm_stats,
|
|
||||||
te_stats,
|
|
||||||
te_wait_stats,
|
|
||||||
te_main_stats,
|
|
||||||
te_wakeup_stats0,
|
|
||||||
te_wakeup_stats1,
|
|
||||||
i_stats,
|
|
||||||
2);
|
|
||||||
} else if(C >= 4) { //one main one worker
|
|
||||||
encoding_return =
|
|
||||||
dlsch_encoding_2threads(eNB,
|
|
||||||
a,
|
|
||||||
num_pdcch_symbols,
|
|
||||||
dlsch,
|
|
||||||
frame,
|
|
||||||
subframe,
|
|
||||||
rm_stats,
|
|
||||||
te_stats,
|
|
||||||
te_wait_stats,
|
|
||||||
te_main_stats,
|
|
||||||
te_wakeup_stats0,
|
|
||||||
te_wakeup_stats1,
|
|
||||||
i_stats,
|
|
||||||
1);
|
|
||||||
} else {
|
|
||||||
encoding_return =
|
|
||||||
dlsch_encoding(eNB,
|
|
||||||
a,
|
|
||||||
num_pdcch_symbols,
|
|
||||||
dlsch,
|
|
||||||
frame,
|
|
||||||
subframe,
|
|
||||||
rm_stats,
|
|
||||||
te_stats,
|
|
||||||
i_stats);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
encoding_return =
|
|
||||||
dlsch_encoding(eNB,
|
|
||||||
a,
|
a,
|
||||||
num_pdcch_symbols,
|
num_pdcch_symbols,
|
||||||
dlsch,
|
dlsch,
|
||||||
@@ -663,13 +279,52 @@ int dlsch_encoding_all(PHY_VARS_eNB *eNB,
|
|||||||
rm_stats,
|
rm_stats,
|
||||||
te_stats,
|
te_stats,
|
||||||
i_stats);
|
i_stats);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return encoding_return;
|
static void TPencode(void * arg) {
|
||||||
|
turboEncode_t * rdata=(turboEncode_t *) arg;
|
||||||
|
unsigned char harq_pid = rdata->harq_pid;
|
||||||
|
LTE_DL_eNB_HARQ_t *hadlsch=rdata->dlsch->harq_processes[harq_pid];
|
||||||
|
|
||||||
|
if ( rdata-> round == 0) {
|
||||||
|
uint8_t tmp[96+12+3+3*6144];
|
||||||
|
memset(tmp,LTE_NULL, TURBO_SIMD_SOFTBITS);
|
||||||
|
start_meas(rdata->te_stats);
|
||||||
|
encoder(rdata->input,
|
||||||
|
rdata->Kr_bytes,
|
||||||
|
tmp+96,//&dlsch->harq_processes[harq_pid]->d[r][96],
|
||||||
|
rdata->filler);
|
||||||
|
stop_meas(rdata->te_stats);
|
||||||
|
start_meas(rdata->i_stats);
|
||||||
|
hadlsch->RTC[rdata->r] =
|
||||||
|
sub_block_interleaving_turbo(4+(rdata->Kr_bytes*8),
|
||||||
|
tmp+96,
|
||||||
|
hadlsch->w[rdata->r]);
|
||||||
|
stop_meas(rdata->i_stats);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
|
||||||
|
// outputs for each code segment, see Section 5.1.5 p.20
|
||||||
|
start_meas(rdata->rm_stats);
|
||||||
|
lte_rate_matching_turbo(hadlsch->RTC[rdata->r],
|
||||||
|
rdata->G, //G
|
||||||
|
hadlsch->w[rdata->r],
|
||||||
|
hadlsch->eDL+rdata->r_offset,
|
||||||
|
hadlsch->C, // C
|
||||||
|
rdata->dlsch->Nsoft, // Nsoft,
|
||||||
|
rdata->dlsch->Mdlharq,
|
||||||
|
rdata->dlsch->Kmimo,
|
||||||
|
hadlsch->rvidx,
|
||||||
|
hadlsch->Qm,
|
||||||
|
hadlsch->Nl,
|
||||||
|
rdata->r,
|
||||||
|
hadlsch->nb_rb);
|
||||||
|
stop_meas(rdata->rm_stats);
|
||||||
|
}
|
||||||
|
|
||||||
int dlsch_encoding(PHY_VARS_eNB *eNB,
|
int dlsch_encoding(PHY_VARS_eNB *eNB,
|
||||||
|
L1_rxtx_proc_t *proc,
|
||||||
unsigned char *a,
|
unsigned char *a,
|
||||||
uint8_t num_pdcch_symbols,
|
uint8_t num_pdcch_symbols,
|
||||||
LTE_eNB_DLSCH_t *dlsch,
|
LTE_eNB_DLSCH_t *dlsch,
|
||||||
@@ -678,8 +333,6 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
|
|||||||
time_stats_t *rm_stats,
|
time_stats_t *rm_stats,
|
||||||
time_stats_t *te_stats,
|
time_stats_t *te_stats,
|
||||||
time_stats_t *i_stats) {
|
time_stats_t *i_stats) {
|
||||||
unsigned int G;
|
|
||||||
unsigned int crc=1;
|
|
||||||
LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
|
LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
|
||||||
unsigned char harq_pid = dlsch->harq_ids[frame%2][subframe];
|
unsigned char harq_pid = dlsch->harq_ids[frame%2][subframe];
|
||||||
if((harq_pid < 0) || (harq_pid >= dlsch->Mdlharq)) {
|
if((harq_pid < 0) || (harq_pid >= dlsch->Mdlharq)) {
|
||||||
@@ -687,135 +340,88 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
|
|||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb;
|
LTE_DL_eNB_HARQ_t *hadlsch=dlsch->harq_processes[harq_pid];
|
||||||
unsigned int A;
|
|
||||||
unsigned char mod_order;
|
|
||||||
unsigned int Kr=0,Kr_bytes,r,r_offset=0;
|
|
||||||
// unsigned short m=dlsch->harq_processes[harq_pid]->mcs;
|
|
||||||
uint8_t beamforming_mode=0;
|
uint8_t beamforming_mode=0;
|
||||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN);
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN);
|
||||||
A = dlsch->harq_processes[harq_pid]->TBS; //6228
|
|
||||||
// printf("Encoder: A: %d\n",A);
|
|
||||||
mod_order = dlsch->harq_processes[harq_pid]->Qm;
|
|
||||||
|
|
||||||
if(dlsch->harq_processes[harq_pid]->mimo_mode == TM7)
|
if(hadlsch->mimo_mode == TM7)
|
||||||
beamforming_mode = 7;
|
beamforming_mode = 7;
|
||||||
else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM8)
|
else if(hadlsch->mimo_mode == TM8)
|
||||||
beamforming_mode = 8;
|
beamforming_mode = 8;
|
||||||
else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM9_10)
|
else if(hadlsch->mimo_mode == TM9_10)
|
||||||
beamforming_mode = 9;
|
beamforming_mode = 9;
|
||||||
|
|
||||||
G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe,beamforming_mode);
|
unsigned int G = get_G(frame_parms,hadlsch->nb_rb,
|
||||||
|
hadlsch->rb_alloc,
|
||||||
|
hadlsch->Qm, // mod order
|
||||||
|
hadlsch->Nl,
|
||||||
|
num_pdcch_symbols,
|
||||||
|
frame,subframe,beamforming_mode);
|
||||||
|
|
||||||
// if (dlsch->harq_processes[harq_pid]->Ndi == 1) { // this is a new packet
|
proc->nbEncode=0;
|
||||||
if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet
|
|
||||||
#ifdef DEBUG_DLSCH_CODING
|
// if (hadlsch->Ndi == 1) { // this is a new packet
|
||||||
printf("encoding thinks this is a new packet for harq_pid %d (%p), A %u \n",harq_pid,dlsch,A);
|
if (hadlsch->round == 0) { // this is a new packet
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
int i;
|
|
||||||
printf("dlsch (tx): \n");
|
|
||||||
for (i=0;i<(A>>3);i++)
|
|
||||||
printf("%02x.",a[i]);
|
|
||||||
printf("\n");
|
|
||||||
*/
|
|
||||||
// Add 24-bit crc (polynomial A) to payload
|
// Add 24-bit crc (polynomial A) to payload
|
||||||
crc = crc24a(a,
|
unsigned int A=hadlsch->TBS; //6228;
|
||||||
|
unsigned int crc = crc24a(a,
|
||||||
A)>>8;
|
A)>>8;
|
||||||
a[A>>3] = ((uint8_t *)&crc)[2];
|
a[A>>3] = ((uint8_t *)&crc)[2];
|
||||||
a[1+(A>>3)] = ((uint8_t *)&crc)[1];
|
a[1+(A>>3)] = ((uint8_t *)&crc)[1];
|
||||||
a[2+(A>>3)] = ((uint8_t *)&crc)[0];
|
a[2+(A>>3)] = ((uint8_t *)&crc)[0];
|
||||||
// printf("CRC %x (A %d)\n",crc,A);
|
// printf("CRC %x (A %d)\n",crc,A);
|
||||||
dlsch->harq_processes[harq_pid]->B = A+24;
|
hadlsch->B = A+24;
|
||||||
// dlsch->harq_processes[harq_pid]->b = a;
|
// hadlsch->b = a;
|
||||||
memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4);
|
memcpy(hadlsch->b,a,(A/8)+4);
|
||||||
|
|
||||||
if (lte_segmentation(dlsch->harq_processes[harq_pid]->b,
|
if (lte_segmentation(hadlsch->b,
|
||||||
dlsch->harq_processes[harq_pid]->c,
|
hadlsch->c,
|
||||||
dlsch->harq_processes[harq_pid]->B,
|
hadlsch->B,
|
||||||
&dlsch->harq_processes[harq_pid]->C,
|
&hadlsch->C,
|
||||||
&dlsch->harq_processes[harq_pid]->Cplus,
|
&hadlsch->Cplus,
|
||||||
&dlsch->harq_processes[harq_pid]->Cminus,
|
&hadlsch->Cminus,
|
||||||
&dlsch->harq_processes[harq_pid]->Kplus,
|
&hadlsch->Kplus,
|
||||||
&dlsch->harq_processes[harq_pid]->Kminus,
|
&hadlsch->Kminus,
|
||||||
&dlsch->harq_processes[harq_pid]->F)<0)
|
&hadlsch->F)<0)
|
||||||
return(-1);
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
|
for (int r=0, r_offset=0; r<hadlsch->C; r++) {
|
||||||
if (r<dlsch->harq_processes[harq_pid]->Cminus)
|
|
||||||
Kr = dlsch->harq_processes[harq_pid]->Kminus;
|
union turboReqUnion id= {.s={dlsch->rnti,frame,subframe,r,0}};
|
||||||
|
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(turboEncode_t), id.p, proc->respEncode, TPencode);
|
||||||
|
turboEncode_t * rdata=(turboEncode_t *) NotifiedFifoData(req);
|
||||||
|
rdata->input=hadlsch->c[r];
|
||||||
|
rdata->Kr_bytes= ( r<hadlsch->Cminus ? hadlsch->Kminus : hadlsch->Kplus) >>3;
|
||||||
|
rdata->filler=(r==0) ? hadlsch->F : 0;
|
||||||
|
rdata->r=r;
|
||||||
|
rdata->harq_pid=harq_pid;
|
||||||
|
rdata->dlsch=dlsch;
|
||||||
|
rdata->rm_stats=rm_stats;
|
||||||
|
rdata->te_stats=te_stats;
|
||||||
|
rdata->i_stats=i_stats;
|
||||||
|
rdata->round=hadlsch->round;
|
||||||
|
rdata->r_offset=r_offset;
|
||||||
|
rdata->G=G;
|
||||||
|
|
||||||
|
if ( proc->threadPool->activated ) {
|
||||||
|
pushTpool(proc->threadPool,req);
|
||||||
|
proc->nbEncode++;
|
||||||
|
} else {
|
||||||
|
TPencode(rdata);
|
||||||
|
delNotifiedFIFO_elt(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Qm=hadlsch->Qm;
|
||||||
|
int C=hadlsch->C;
|
||||||
|
int Nl=hadlsch->Nl;
|
||||||
|
int Gp = G/Nl/Qm;
|
||||||
|
int GpmodC = Gp%C;
|
||||||
|
if (r < (C-(GpmodC)))
|
||||||
|
r_offset += Nl*Qm * (Gp/C);
|
||||||
else
|
else
|
||||||
Kr = dlsch->harq_processes[harq_pid]->Kplus;
|
r_offset += Nl*Qm * ((GpmodC==0?0:1) + (Gp/C));
|
||||||
|
|
||||||
Kr_bytes = Kr>>3;
|
|
||||||
#ifdef DEBUG_DLSCH_CODING
|
|
||||||
printf("Generating Code Segment %u (%u bits)\n",r,Kr);
|
|
||||||
// generate codewords
|
|
||||||
printf("bits_per_codeword (Kr)= %u, A %u\n",Kr,A);
|
|
||||||
printf("N_RB = %d\n",nb_rb);
|
|
||||||
printf("Ncp %d\n",frame_parms->Ncp);
|
|
||||||
printf("mod_order %d\n",mod_order);
|
|
||||||
#endif
|
|
||||||
start_meas(te_stats);
|
|
||||||
encoder(dlsch->harq_processes[harq_pid]->c[r],
|
|
||||||
Kr>>3,
|
|
||||||
&dlsch->harq_processes[harq_pid]->d[r][96],
|
|
||||||
(r==0) ? dlsch->harq_processes[harq_pid]->F : 0
|
|
||||||
);
|
|
||||||
stop_meas(te_stats);
|
|
||||||
#ifdef DEBUG_DLSCH_CODING
|
|
||||||
|
|
||||||
if (r==0)
|
|
||||||
LOG_M("enc_output0.m","enc0",&dlsch->harq_processes[harq_pid]->d[r][96],(3*8*Kr_bytes)+12,1,4);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
start_meas(i_stats);
|
|
||||||
dlsch->harq_processes[harq_pid]->RTC[r] =
|
|
||||||
sub_block_interleaving_turbo(4+(Kr_bytes*8),
|
|
||||||
&dlsch->harq_processes[harq_pid]->d[r][96],
|
|
||||||
dlsch->harq_processes[harq_pid]->w[r]);
|
|
||||||
stop_meas(i_stats);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
|
|
||||||
// outputs for each code segment, see Section 5.1.5 p.20
|
|
||||||
|
|
||||||
for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
|
|
||||||
#ifdef DEBUG_DLSCH_CODING
|
|
||||||
printf("Rate Matching, Code segment %u (coded bits (G) %u,unpunctured/repeated bits per code segment %u,mod_order %d, nb_rb %d)...\n",
|
|
||||||
r,
|
|
||||||
G,
|
|
||||||
Kr*3,
|
|
||||||
mod_order,nb_rb);
|
|
||||||
#endif
|
|
||||||
start_meas(rm_stats);
|
|
||||||
#ifdef DEBUG_DLSCH_CODING
|
|
||||||
printf("rvidx in encoding = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
|
|
||||||
#endif
|
|
||||||
r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
|
|
||||||
G, //G
|
|
||||||
dlsch->harq_processes[harq_pid]->w[r],
|
|
||||||
dlsch->harq_processes[harq_pid]->e+r_offset,
|
|
||||||
dlsch->harq_processes[harq_pid]->C, // C
|
|
||||||
dlsch->Nsoft, // Nsoft,
|
|
||||||
dlsch->Mdlharq,
|
|
||||||
dlsch->Kmimo,
|
|
||||||
dlsch->harq_processes[harq_pid]->rvidx,
|
|
||||||
dlsch->harq_processes[harq_pid]->Qm,
|
|
||||||
dlsch->harq_processes[harq_pid]->Nl,
|
|
||||||
r,
|
|
||||||
nb_rb);
|
|
||||||
// m); // r
|
|
||||||
stop_meas(rm_stats);
|
|
||||||
#ifdef DEBUG_DLSCH_CODING
|
|
||||||
|
|
||||||
if (r==dlsch->harq_processes[harq_pid]->C-1)
|
|
||||||
LOG_M("enc_output.m","enc",dlsch->harq_processes[harq_pid]->e,r_offset,1,4);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ int allocate_REs_in_RB_no_pilots_QPSK_siso(PHY_VARS_eNB* phy_vars_eNB,
|
|||||||
{
|
{
|
||||||
|
|
||||||
LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms;
|
LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms;
|
||||||
uint8_t *x0 = dlsch0_harq->e;
|
uint8_t *x0 = dlsch0_harq->eDL;
|
||||||
uint32_t qpsk_table_offset_re = 0;
|
uint32_t qpsk_table_offset_re = 0;
|
||||||
uint32_t qpsk_table_offset_im = 0;
|
uint32_t qpsk_table_offset_im = 0;
|
||||||
|
|
||||||
@@ -248,7 +248,7 @@ int allocate_REs_in_RB_pilots_QPSK_siso(PHY_VARS_eNB* phy_vars_eNB,
|
|||||||
|
|
||||||
LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->frame_parms;
|
LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->frame_parms;
|
||||||
|
|
||||||
uint8_t *x0 = dlsch0_harq->e;
|
uint8_t *x0 = dlsch0_harq->eDL;
|
||||||
uint32_t qpsk_table_offset_re = 0;
|
uint32_t qpsk_table_offset_re = 0;
|
||||||
uint32_t qpsk_table_offset_im = 0;
|
uint32_t qpsk_table_offset_im = 0;
|
||||||
|
|
||||||
@@ -343,7 +343,7 @@ int allocate_REs_in_RB_no_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
|
|||||||
{
|
{
|
||||||
|
|
||||||
LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms;
|
LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms;
|
||||||
uint8_t *x0 = dlsch0_harq->e;
|
uint8_t *x0 = dlsch0_harq->eDL;
|
||||||
uint32_t qam16_table_offset_re = 0;
|
uint32_t qam16_table_offset_re = 0;
|
||||||
uint32_t qam16_table_offset_im = 0;
|
uint32_t qam16_table_offset_im = 0;
|
||||||
|
|
||||||
@@ -439,7 +439,7 @@ int allocate_REs_in_RB_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
|
|||||||
|
|
||||||
LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->frame_parms;
|
LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->frame_parms;
|
||||||
|
|
||||||
uint8_t *x0 = dlsch0_harq->e;
|
uint8_t *x0 = dlsch0_harq->eDL;
|
||||||
uint32_t qam16_table_offset_re = 0;
|
uint32_t qam16_table_offset_re = 0;
|
||||||
uint32_t qam16_table_offset_im = 0;
|
uint32_t qam16_table_offset_im = 0;
|
||||||
|
|
||||||
@@ -542,7 +542,7 @@ int allocate_REs_in_RB_no_pilots_64QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
|
|||||||
|
|
||||||
LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms;
|
LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms;
|
||||||
|
|
||||||
uint8_t *x0 = dlsch0_harq->e;
|
uint8_t *x0 = dlsch0_harq->eDL;
|
||||||
uint32_t qam64_table_offset_re = 0;
|
uint32_t qam64_table_offset_re = 0;
|
||||||
uint32_t qam64_table_offset_im = 0;
|
uint32_t qam64_table_offset_im = 0;
|
||||||
|
|
||||||
@@ -699,7 +699,7 @@ int allocate_REs_in_RB_pilots_64QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
|
|||||||
|
|
||||||
LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->frame_parms;
|
LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->frame_parms;
|
||||||
|
|
||||||
uint8_t *x0 = dlsch0_harq->e;
|
uint8_t *x0 = dlsch0_harq->eDL;
|
||||||
uint32_t qam64_table_offset_re = 0;
|
uint32_t qam64_table_offset_re = 0;
|
||||||
uint32_t qam64_table_offset_im = 0;
|
uint32_t qam64_table_offset_im = 0;
|
||||||
|
|
||||||
@@ -866,12 +866,12 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB,
|
|||||||
|
|
||||||
if ((dlsch0_harq != NULL) && (dlsch1_harq != NULL)) { //this is for TM3, TM4
|
if ((dlsch0_harq != NULL) && (dlsch1_harq != NULL)) { //this is for TM3, TM4
|
||||||
|
|
||||||
x0 = dlsch0_harq->e;
|
x0 = dlsch0_harq->eDL;
|
||||||
mimo_mode = dlsch0_harq->mimo_mode;
|
mimo_mode = dlsch0_harq->mimo_mode;
|
||||||
first_layer0 = dlsch0_harq->first_layer;
|
first_layer0 = dlsch0_harq->first_layer;
|
||||||
Nlayers0 = dlsch0_harq->Nlayers;
|
Nlayers0 = dlsch0_harq->Nlayers;
|
||||||
mod_order0 = dlsch0_harq->Qm;
|
mod_order0 = dlsch0_harq->Qm;
|
||||||
x1 = dlsch1_harq->e;
|
x1 = dlsch1_harq->eDL;
|
||||||
// Fill these in later for TM8-10
|
// Fill these in later for TM8-10
|
||||||
// Nlayers1 = dlsch1_harq->Nlayers;
|
// Nlayers1 = dlsch1_harq->Nlayers;
|
||||||
// first_layer1 = dlsch1_harq->first_layer;
|
// first_layer1 = dlsch1_harq->first_layer;
|
||||||
@@ -879,7 +879,7 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB,
|
|||||||
|
|
||||||
} else if ((dlsch0_harq != NULL) && (dlsch1_harq == NULL)){ //This is for SIS0 TM1, TM6, etc
|
} else if ((dlsch0_harq != NULL) && (dlsch1_harq == NULL)){ //This is for SIS0 TM1, TM6, etc
|
||||||
|
|
||||||
x0 = dlsch0_harq->e;
|
x0 = dlsch0_harq->eDL;
|
||||||
mimo_mode = dlsch0_harq->mimo_mode;
|
mimo_mode = dlsch0_harq->mimo_mode;
|
||||||
first_layer0 = dlsch0_harq->first_layer;
|
first_layer0 = dlsch0_harq->first_layer;
|
||||||
Nlayers0 = dlsch0_harq->Nlayers;
|
Nlayers0 = dlsch0_harq->Nlayers;
|
||||||
@@ -887,7 +887,7 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB,
|
|||||||
|
|
||||||
} else if ((dlsch0_harq == NULL) && (dlsch1_harq != NULL)){ // This is for TM4 retransmission
|
} else if ((dlsch0_harq == NULL) && (dlsch1_harq != NULL)){ // This is for TM4 retransmission
|
||||||
|
|
||||||
x0 = dlsch1_harq->e;
|
x0 = dlsch1_harq->eDL;
|
||||||
mimo_mode = dlsch1_harq->mimo_mode;
|
mimo_mode = dlsch1_harq->mimo_mode;
|
||||||
first_layer0 = dlsch1_harq->first_layer;
|
first_layer0 = dlsch1_harq->first_layer;
|
||||||
Nlayers0 = dlsch1_harq->Nlayers;
|
Nlayers0 = dlsch1_harq->Nlayers;
|
||||||
@@ -2692,7 +2692,7 @@ int dlsch_modulation_SIC(int32_t **sic_buffer,
|
|||||||
LTE_DL_eNB_HARQ_t *dlsch0_harq = dlsch0->harq_processes[harq_pid];
|
LTE_DL_eNB_HARQ_t *dlsch0_harq = dlsch0->harq_processes[harq_pid];
|
||||||
uint32_t i,jj,re_allocated=0;
|
uint32_t i,jj,re_allocated=0;
|
||||||
uint8_t mod_order0 = dlsch0_harq->Qm;
|
uint8_t mod_order0 = dlsch0_harq->Qm;
|
||||||
uint8_t *x0 = dlsch0_harq->e;
|
uint8_t *x0 = dlsch0_harq->eDL;
|
||||||
uint8_t qam64_table_offset_re = 0;
|
uint8_t qam64_table_offset_re = 0;
|
||||||
uint8_t qam64_table_offset_im = 0;
|
uint8_t qam64_table_offset_im = 0;
|
||||||
uint8_t qam16_table_offset_re = 0;
|
uint8_t qam16_table_offset_re = 0;
|
||||||
@@ -2883,7 +2883,7 @@ int mch_modulation(int32_t **txdataF,
|
|||||||
&jj,
|
&jj,
|
||||||
re_offset,
|
re_offset,
|
||||||
symbol_offset,
|
symbol_offset,
|
||||||
dlsch->harq_processes[0]->e,
|
dlsch->harq_processes[0]->eDL,
|
||||||
l,
|
l,
|
||||||
mod_order,
|
mod_order,
|
||||||
amp,
|
amp,
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
|
|||||||
int n;
|
int n;
|
||||||
// uint8_t reset;
|
// uint8_t reset;
|
||||||
uint32_t x1, x2, s=0;
|
uint32_t x1, x2, s=0;
|
||||||
uint8_t *dlsch_e=dlsch->harq_processes[harq_pid]->e;
|
uint8_t *dlsch_e=dlsch->harq_processes[harq_pid]->eDL;
|
||||||
uint8_t *e=dlsch_e;
|
uint8_t *e=dlsch_e;
|
||||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_SCRAMBLING, VCD_FUNCTION_IN);
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_SCRAMBLING, VCD_FUNCTION_IN);
|
||||||
// Rule for accumulation of subframes for BL/CE UEs
|
// Rule for accumulation of subframes for BL/CE UEs
|
||||||
|
|||||||
@@ -61,7 +61,8 @@ typedef struct IF5_mobipass_header IF5_mobipass_header_t;
|
|||||||
|
|
||||||
void send_IF5(RU_t *, openair0_timestamp, int, uint8_t*, uint16_t);
|
void send_IF5(RU_t *, openair0_timestamp, int, uint8_t*, uint16_t);
|
||||||
|
|
||||||
void recv_IF5(RU_t *, openair0_timestamp*, int, uint16_t);
|
void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16_t packet_type);
|
||||||
|
|
||||||
|
|
||||||
void malloc_IF5_buffer(RU_t *ru);
|
void malloc_IF5_buffer(RU_t *ru);
|
||||||
|
|
||||||
|
|||||||
@@ -714,7 +714,7 @@ void generate_phich_top(PHY_VARS_eNB *eNB,
|
|||||||
int32_t **txdataF = eNB->common_vars.txdataF;
|
int32_t **txdataF = eNB->common_vars.txdataF;
|
||||||
uint8_t Ngroup_PHICH,ngroup_PHICH,nseq_PHICH;
|
uint8_t Ngroup_PHICH,ngroup_PHICH,nseq_PHICH;
|
||||||
uint8_t NSF_PHICH = 4;
|
uint8_t NSF_PHICH = 4;
|
||||||
uint8_t pusch_subframe;
|
uint8_t pusch_subframe=-1;
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
int subframe = proc->subframe_tx;
|
int subframe = proc->subframe_tx;
|
||||||
phich_config_t *phich;
|
phich_config_t *phich;
|
||||||
|
|||||||
@@ -105,6 +105,7 @@ void generate_mch(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,uint8_t *a)
|
|||||||
AssertFatal(eNB->dlsch_MCH->harq_processes[0]->pdu != NULL, "attempt to encode a NULL harq PDU\n");
|
AssertFatal(eNB->dlsch_MCH->harq_processes[0]->pdu != NULL, "attempt to encode a NULL harq PDU\n");
|
||||||
|
|
||||||
AssertFatal(dlsch_encoding(eNB,
|
AssertFatal(dlsch_encoding(eNB,
|
||||||
|
proc,
|
||||||
// a,
|
// a,
|
||||||
eNB->dlsch_MCH->harq_processes[0]->pdu,
|
eNB->dlsch_MCH->harq_processes[0]->pdu,
|
||||||
1,
|
1,
|
||||||
|
|||||||
@@ -38,9 +38,13 @@
|
|||||||
#include "SCHED/sched_eNB.h"
|
#include "SCHED/sched_eNB.h"
|
||||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||||
#include "prach_extern.h"
|
#include "prach_extern.h"
|
||||||
|
#include <openair1/PHY/LTE_TRANSPORT/transport_proto.h>
|
||||||
|
#include <executables/split_headers.h>
|
||||||
|
|
||||||
void rx_prach0(PHY_VARS_eNB *eNB,
|
void rx_prach0(PHY_VARS_eNB *eNB,
|
||||||
RU_t *ru,
|
RU_t *ru,
|
||||||
|
int frame_prach,
|
||||||
|
int subframe,
|
||||||
uint16_t *max_preamble,
|
uint16_t *max_preamble,
|
||||||
uint16_t *max_preamble_energy,
|
uint16_t *max_preamble_energy,
|
||||||
uint16_t *max_preamble_delay,
|
uint16_t *max_preamble_delay,
|
||||||
@@ -51,17 +55,14 @@ void rx_prach0(PHY_VARS_eNB *eNB,
|
|||||||
uint8_t ce_level
|
uint8_t ce_level
|
||||||
) {
|
) {
|
||||||
int i;
|
int i;
|
||||||
LTE_DL_FRAME_PARMS *fp=NULL;
|
|
||||||
lte_frame_type_t frame_type;
|
lte_frame_type_t frame_type;
|
||||||
uint16_t rootSequenceIndex;
|
uint16_t rootSequenceIndex;
|
||||||
uint8_t prach_ConfigIndex;
|
uint8_t prach_ConfigIndex;
|
||||||
uint8_t Ncs_config;
|
uint8_t Ncs_config;
|
||||||
uint8_t restricted_set;
|
uint8_t restricted_set;
|
||||||
uint8_t n_ra_prb;
|
uint8_t n_ra_prb;
|
||||||
int subframe;
|
|
||||||
int16_t *prachF=NULL;
|
int16_t *prachF=NULL;
|
||||||
int16_t **rxsigF=NULL;
|
int16_t **rxsigF=NULL;
|
||||||
int nb_rx=0;
|
|
||||||
int16_t *prach2;
|
int16_t *prach2;
|
||||||
uint8_t preamble_index;
|
uint8_t preamble_index;
|
||||||
uint16_t NCS,NCS2;
|
uint16_t NCS,NCS2;
|
||||||
@@ -89,6 +90,8 @@ void rx_prach0(PHY_VARS_eNB *eNB,
|
|||||||
int32_t **prach_ifftp=(int32_t **)NULL;
|
int32_t **prach_ifftp=(int32_t **)NULL;
|
||||||
int prach_ifft_cnt=0;
|
int prach_ifft_cnt=0;
|
||||||
|
|
||||||
|
LTE_DL_FRAME_PARMS *fp;
|
||||||
|
int nb_rx;
|
||||||
if(eNB) {
|
if(eNB) {
|
||||||
fp = &(eNB->frame_parms);
|
fp = &(eNB->frame_parms);
|
||||||
nb_rx = fp->nb_antennas_rx;
|
nb_rx = fp->nb_antennas_rx;
|
||||||
@@ -133,14 +136,13 @@ void rx_prach0(PHY_VARS_eNB *eNB,
|
|||||||
if (eNB) {
|
if (eNB) {
|
||||||
if (br_flag == 1) {
|
if (br_flag == 1) {
|
||||||
prach_ifftp = eNB->prach_vars_br.prach_ifft[ce_level];
|
prach_ifftp = eNB->prach_vars_br.prach_ifft[ce_level];
|
||||||
subframe = eNB->proc.subframe_prach_br;
|
|
||||||
prachF = eNB->prach_vars_br.prachF;
|
prachF = eNB->prach_vars_br.prachF;
|
||||||
rxsigF = eNB->prach_vars_br.rxsigF[ce_level];
|
rxsigF = eNB->prach_vars_br.rxsigF[ce_level];
|
||||||
|
|
||||||
if (LOG_DEBUGFLAG(PRACH)) {
|
if (LOG_DEBUGFLAG(PRACH)) {
|
||||||
if (((eNB->proc.frame_prach)&1023) < 20) LOG_I(PHY,
|
if (((frame_prach)&1023) < 20) LOG_I(PHY,
|
||||||
"PRACH (eNB) : running rx_prach (br_flag %d, ce_level %d) for frame %d subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d, rootSequenceIndex %d, repetition number %d,numRepetitionsPrePreambleAttempt %d\n",
|
"PRACH (eNB) : running rx_prach (br_flag %d, ce_level %d) for frame %d subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d, rootSequenceIndex %d, repetition number %d,numRepetitionsPrePreambleAttempt %d\n",
|
||||||
br_flag,ce_level,eNB->proc.frame_prach,subframe,
|
br_flag,ce_level,frame_prach,subframe,
|
||||||
fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level],
|
fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level],
|
||||||
prach_ConfigIndex,rootSequenceIndex,
|
prach_ConfigIndex,rootSequenceIndex,
|
||||||
eNB->prach_vars_br.repetition_number[ce_level],
|
eNB->prach_vars_br.repetition_number[ce_level],
|
||||||
@@ -148,30 +150,27 @@ void rx_prach0(PHY_VARS_eNB *eNB,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
prach_ifftp = eNB->prach_vars.prach_ifft[0];
|
prach_ifftp = eNB->prach_vars.prach_ifft[0];
|
||||||
subframe = eNB->proc.subframe_prach;
|
|
||||||
prachF = eNB->prach_vars.prachF;
|
prachF = eNB->prach_vars.prachF;
|
||||||
rxsigF = eNB->prach_vars.rxsigF[0];
|
rxsigF = eNB->prach_vars.rxsigF[0];
|
||||||
|
|
||||||
if (LOG_DEBUGFLAG(PRACH)) {
|
if (LOG_DEBUGFLAG(PRACH)) {
|
||||||
if (((eNB->proc.frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (eNB) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d , rootSequenceIndex %d\n", subframe,
|
if (((frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (eNB) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d , rootSequenceIndex %d\n", subframe,
|
||||||
fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset,prach_ConfigIndex,rootSequenceIndex);
|
fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset,prach_ConfigIndex,rootSequenceIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (br_flag == 1) {
|
if (br_flag == 1) {
|
||||||
subframe = ru->proc.subframe_prach_br;
|
|
||||||
rxsigF = ru->prach_rxsigF_br[ce_level];
|
rxsigF = ru->prach_rxsigF_br[ce_level];
|
||||||
|
|
||||||
if (LOG_DEBUGFLAG(PRACH)) {
|
if (LOG_DEBUGFLAG(PRACH)) {
|
||||||
if (((ru->proc.frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (RU) : running rx_prach (br_flag %d, ce_level %d) for frame %d subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n",
|
if (((frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (RU) : running rx_prach (br_flag %d, ce_level %d) for frame %d subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n",
|
||||||
br_flag,ce_level,ru->proc.frame_prach,subframe,fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level],prach_ConfigIndex);
|
br_flag,ce_level,frame_prach,subframe,fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level],prach_ConfigIndex);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
subframe = ru->proc.subframe_prach;
|
|
||||||
rxsigF = ru->prach_rxsigF;
|
rxsigF = ru->prach_rxsigF;
|
||||||
|
|
||||||
if (LOG_DEBUGFLAG(PRACH)) {
|
if (LOG_DEBUGFLAG(PRACH)) {
|
||||||
if (((ru->proc.frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (RU) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n",
|
if (((frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (RU) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n",
|
||||||
subframe,fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset,prach_ConfigIndex);
|
subframe,fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset,prach_ConfigIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -202,7 +201,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
|
|||||||
if (prach[0]!= NULL) LOG_M("prach_rx","prach_rx",prach[0],fp->samples_per_tti,1,1);
|
if (prach[0]!= NULL) LOG_M("prach_rx","prach_rx",prach[0],fp->samples_per_tti,1,1);
|
||||||
|
|
||||||
LOG_I(PHY,"RU %d, br_flag %d ce_level %d frame %d subframe %d per_tti:%d prach:%p (energy %d) TA:%d %s rxdata:%p index:%d\n",
|
LOG_I(PHY,"RU %d, br_flag %d ce_level %d frame %d subframe %d per_tti:%d prach:%p (energy %d) TA:%d %s rxdata:%p index:%d\n",
|
||||||
ru->idx,br_flag,ce_level,ru->proc.frame_prach,subframe,fp->samples_per_tti,
|
ru->idx,br_flag,ce_level,frame_prach,subframe,fp->samples_per_tti,
|
||||||
prach[aa],dbEn0,ru->N_TA_offset,buffer,ru->common.rxdata[aa],
|
prach[aa],dbEn0,ru->N_TA_offset,buffer,ru->common.rxdata[aa],
|
||||||
(subframe*fp->samples_per_tti)-ru->N_TA_offset);
|
(subframe*fp->samples_per_tti)-ru->N_TA_offset);
|
||||||
}
|
}
|
||||||
@@ -407,16 +406,16 @@ void rx_prach0(PHY_VARS_eNB *eNB,
|
|||||||
if ((eNB==NULL) && ru->function == NGFI_RRU_IF4p5) {
|
if ((eNB==NULL) && ru->function == NGFI_RRU_IF4p5) {
|
||||||
/// **** send_IF4 of rxsigF to RAU **** ///
|
/// **** send_IF4 of rxsigF to RAU **** ///
|
||||||
if (br_flag == 1)
|
if (br_flag == 1)
|
||||||
send_IF4p5(ru, ru->proc.frame_prach, ru->proc.subframe_prach, IF4p5_PRACH+1+ce_level);
|
send_IF4p5(ru, frame_prach, subframe, IF4p5_PRACH+1+ce_level);
|
||||||
else
|
else
|
||||||
send_IF4p5(ru, ru->proc.frame_prach, ru->proc.subframe_prach, IF4p5_PRACH);
|
send_IF4p5(ru, frame_prach, subframe, IF4p5_PRACH);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} else if (eNB!=NULL) {
|
} else if (eNB!=NULL) {
|
||||||
if ( LOG_DEBUGFLAG(PRACH)) {
|
if ( LOG_DEBUGFLAG(PRACH)) {
|
||||||
int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
|
int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
|
||||||
|
|
||||||
if ((en > 60)&&(br_flag==1)) LOG_I(PHY,"PRACH (br_flag %d,ce_level %d, n_ra_prb %d, k %d): Frame %d, Subframe %d => %d dB\n",br_flag,ce_level,n_ra_prb,k,eNB->proc.frame_rx,eNB->proc.subframe_rx,en);
|
if ((en > 60)&&(br_flag==1)) LOG_I(PHY,"PRACH (br_flag %d,ce_level %d, n_ra_prb %d, k %d): Frame %d, Subframe %d => %d dB\n",br_flag,ce_level,n_ra_prb,k,frame_prach,subframe,en);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -457,7 +456,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
|
|||||||
if (LOG_DEBUGFLAG(PRACH)) {
|
if (LOG_DEBUGFLAG(PRACH)) {
|
||||||
int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
|
int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
|
||||||
|
|
||||||
if (en>60) LOG_I(PHY,"frame %d, subframe %d : Trying preamble %d (br_flag %d)\n",ru->proc.frame_prach,subframe,preamble_index,br_flag);
|
if (en>60) LOG_I(PHY,"frame %d, subframe %d : Trying preamble %d (br_flag %d)\n",frame_prach,subframe,preamble_index,br_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (restricted_set == 0) {
|
if (restricted_set == 0) {
|
||||||
@@ -543,7 +542,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
|
|||||||
int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
|
int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
|
||||||
|
|
||||||
if (en>60) LOG_I(PHY,"frame %d, subframe %d : preamble index %d: offset %d, preamble shift %d (br_flag %d, en %d)\n",
|
if (en>60) LOG_I(PHY,"frame %d, subframe %d : preamble index %d: offset %d, preamble shift %d (br_flag %d, en %d)\n",
|
||||||
ru->proc.frame_prach,subframe,preamble_index,preamble_offset,preamble_shift,br_flag,en);
|
frame_prach,subframe,preamble_index,preamble_offset,preamble_shift,br_flag,en);
|
||||||
}
|
}
|
||||||
|
|
||||||
log2_ifft_size = 10;
|
log2_ifft_size = 10;
|
||||||
@@ -618,7 +617,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
|
|||||||
if (LOG_DEBUGFLAG(PRACH)) {
|
if (LOG_DEBUGFLAG(PRACH)) {
|
||||||
int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
|
int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
|
||||||
|
|
||||||
if (en>60) LOG_I(PHY,"frame %d, subframe %d: Checking for peak in time-domain (br_flag %d, en %d)\n",ru->proc.frame_prach,subframe,br_flag,en);
|
if (en>60) LOG_I(PHY,"frame %d, subframe %d: Checking for peak in time-domain (br_flag %d, en %d)\n",frame_prach,subframe,br_flag,en);
|
||||||
}
|
}
|
||||||
|
|
||||||
preamble_shift2 = ((preamble_shift==0) ? 0 : ((preamble_shift<<log2_ifft_size)/N_ZC));
|
preamble_shift2 = ((preamble_shift==0) ? 0 : ((preamble_shift<<log2_ifft_size)/N_ZC));
|
||||||
@@ -638,7 +637,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
|
|||||||
|
|
||||||
if ((en>60) && (br_flag==1))
|
if ((en>60) && (br_flag==1))
|
||||||
LOG_D(PHY,"frame %d, subframe %d : max_preamble_energy %d, max_preamble_delay %d, max_preamble %d (br_flag %d,ce_level %d, levdB %d, lev %d)\n",
|
LOG_D(PHY,"frame %d, subframe %d : max_preamble_energy %d, max_preamble_delay %d, max_preamble %d (br_flag %d,ce_level %d, levdB %d, lev %d)\n",
|
||||||
ru->proc.frame_prach,subframe,
|
frame_prach,subframe,
|
||||||
*max_preamble_energy,*max_preamble_delay,
|
*max_preamble_energy,*max_preamble_delay,
|
||||||
*max_preamble,br_flag,ce_level,levdB,lev);
|
*max_preamble,br_flag,ce_level,levdB,lev);
|
||||||
}
|
}
|
||||||
@@ -694,8 +693,16 @@ void rx_prach(PHY_VARS_eNB *eNB,
|
|||||||
int i;
|
int i;
|
||||||
int prach_mask=0;
|
int prach_mask=0;
|
||||||
|
|
||||||
|
int subframe;
|
||||||
|
if (eNB)
|
||||||
|
subframe= br_flag?eNB->proc.subframe_prach_br:eNB->proc.subframe_prach;
|
||||||
|
else
|
||||||
|
subframe= br_flag?ru->proc.subframe_prach_br:ru->proc.subframe_prach;
|
||||||
|
|
||||||
|
int frame_prach=eNB?eNB->proc.frame_prach: ru->proc.frame_prach;
|
||||||
|
|
||||||
if (br_flag == 0) {
|
if (br_flag == 0) {
|
||||||
rx_prach0(eNB,ru,max_preamble,max_preamble_energy,max_preamble_delay,avg_preamble_energy,Nf,tdd_mapindex,0,0);
|
rx_prach0(eNB,ru,frame_prach,subframe,max_preamble,max_preamble_energy,max_preamble_delay,avg_preamble_energy,Nf,tdd_mapindex,0,0);
|
||||||
} else { // This is procedure for eMTC, basically handling the repetitions
|
} else { // This is procedure for eMTC, basically handling the repetitions
|
||||||
prach_mask = is_prach_subframe(&eNB->frame_parms,eNB->proc.frame_prach_br,eNB->proc.subframe_prach_br);
|
prach_mask = is_prach_subframe(&eNB->frame_parms,eNB->proc.frame_prach_br,eNB->proc.subframe_prach_br);
|
||||||
|
|
||||||
@@ -709,7 +716,7 @@ void rx_prach(PHY_VARS_eNB *eNB,
|
|||||||
// increment repetition number
|
// increment repetition number
|
||||||
eNB->prach_vars_br.repetition_number[i]++;
|
eNB->prach_vars_br.repetition_number[i]++;
|
||||||
// do basic PRACH reception
|
// do basic PRACH reception
|
||||||
rx_prach0(eNB,ru,max_preamble,max_preamble_energy,max_preamble_delay,avg_preamble_energy,Nf,tdd_mapindex,1,i);
|
rx_prach0(eNB,ru,frame_prach,subframe,max_preamble,max_preamble_energy,max_preamble_delay,avg_preamble_energy,Nf,tdd_mapindex,1,i);
|
||||||
|
|
||||||
// if last repetition, clear counter
|
// if last repetition, clear counter
|
||||||
if (eNB->prach_vars_br.repetition_number[i] == eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[i]) {
|
if (eNB->prach_vars_br.repetition_number[i] == eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[i]) {
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ uint16_t pucchfmt3_ChannelEstimation( int16_t SubCarrierDeMapData[NB_ANTENNAS_RX
|
|||||||
uint16_t n3_pucch_array[NUMBER_OF_UE_MAX],
|
uint16_t n3_pucch_array[NUMBER_OF_UE_MAX],
|
||||||
uint8_t ncs_cell[20][7] ) {
|
uint8_t ncs_cell[20][7] ) {
|
||||||
uint32_t aa, symNo, k, slotNo, sym, i, j;
|
uint32_t aa, symNo, k, slotNo, sym, i, j;
|
||||||
int16_t np, np_n, ip_ind;
|
int16_t np, np_n, ip_ind=-1;
|
||||||
//int16_t npucch_sf;
|
//int16_t npucch_sf;
|
||||||
int16_t calctmp[2];
|
int16_t calctmp[2];
|
||||||
int16_t BsCshData[NB_ANTENNAS_RX][D_NSYM1SF][D_NSC1RB][2];
|
int16_t BsCshData[NB_ANTENNAS_RX][D_NSYM1SF][D_NSC1RB][2];
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ typedef struct {
|
|||||||
/// start symbold of pdsch
|
/// start symbold of pdsch
|
||||||
uint8_t pdsch_start;
|
uint8_t pdsch_start;
|
||||||
/// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
|
/// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
|
||||||
uint8_t e[MAX_NUM_CHANNEL_BITS] __attribute__((aligned(32)));
|
uint8_t eDL[MAX_NUM_CHANNEL_BITS] __attribute__((aligned(32)));
|
||||||
/// Turbo-code outputs (36-212 V8.6 2009-03, p.12
|
/// Turbo-code outputs (36-212 V8.6 2009-03, p.12
|
||||||
uint8_t *d[MAX_NUM_DLSCH_SEGMENTS];//[(96+3+(3*6144))];
|
uint8_t *d[MAX_NUM_DLSCH_SEGMENTS];//[(96+3+(3*6144))];
|
||||||
/// Sub-block interleaver outputs (36-212 V8.6 2009-03, p.16-17)
|
/// Sub-block interleaver outputs (36-212 V8.6 2009-03, p.16-17)
|
||||||
@@ -261,12 +261,13 @@ typedef struct {
|
|||||||
/// coded RI bits
|
/// coded RI bits
|
||||||
int16_t q_RI[MAX_RI_PAYLOAD];
|
int16_t q_RI[MAX_RI_PAYLOAD];
|
||||||
/// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
|
/// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
|
||||||
int16_t e[MAX_NUM_CHANNEL_BITS] __attribute__((aligned(32)));
|
int16_t eUL[MAX_NUM_CHANNEL_BITS] __attribute__((aligned(32)));
|
||||||
/// Temporary h sequence to flag PUSCH_x/PUSCH_y symbols which are not scrambled
|
/// Temporary h sequence to flag PUSCH_x/PUSCH_y symbols which are not scrambled
|
||||||
uint8_t h[MAX_NUM_CHANNEL_BITS];
|
uint8_t h[MAX_NUM_CHANNEL_BITS];
|
||||||
/// Pointer to the payload
|
/// Pointer to the payload
|
||||||
uint8_t *b;
|
uint8_t *decodedBytes;
|
||||||
/// Pointers to transport block segments
|
/// Pointers to transport block segments
|
||||||
|
//TBD
|
||||||
uint8_t *c[MAX_NUM_ULSCH_SEGMENTS];
|
uint8_t *c[MAX_NUM_ULSCH_SEGMENTS];
|
||||||
/// RTC values for each segment (for definition see 36-212 V8.6 2009-03, p.15)
|
/// RTC values for each segment (for definition see 36-212 V8.6 2009-03, p.15)
|
||||||
uint32_t RTC[MAX_NUM_ULSCH_SEGMENTS];
|
uint32_t RTC[MAX_NUM_ULSCH_SEGMENTS];
|
||||||
@@ -282,8 +283,12 @@ typedef struct {
|
|||||||
uint8_t rvidx;
|
uint8_t rvidx;
|
||||||
/// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
|
/// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
|
||||||
int16_t w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)];
|
int16_t w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)];
|
||||||
|
int16_t pusch_rep_buffer[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)];
|
||||||
/// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
|
/// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
|
||||||
|
//TBD
|
||||||
int16_t *d[MAX_NUM_ULSCH_SEGMENTS];
|
int16_t *d[MAX_NUM_ULSCH_SEGMENTS];
|
||||||
|
uint32_t processedSegments;
|
||||||
|
uint32_t processedBadSegment;
|
||||||
/// Number of code segments (for definition see 36-212 V8.6 2009-03, p.9)
|
/// Number of code segments (for definition see 36-212 V8.6 2009-03, p.9)
|
||||||
uint32_t C;
|
uint32_t C;
|
||||||
/// Number of "small" code segments (for definition see 36-212 V8.6 2009-03, p.10)
|
/// Number of "small" code segments (for definition see 36-212 V8.6 2009-03, p.10)
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ void free_eNB_ulsch(LTE_eNB_ULSCH_t *ulsch);
|
|||||||
LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag);
|
LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag);
|
||||||
|
|
||||||
int dlsch_encoding_all(PHY_VARS_eNB *eNB,
|
int dlsch_encoding_all(PHY_VARS_eNB *eNB,
|
||||||
|
L1_rxtx_proc_t *proc,
|
||||||
unsigned char *a,
|
unsigned char *a,
|
||||||
uint8_t num_pdcch_symbols,
|
uint8_t num_pdcch_symbols,
|
||||||
LTE_eNB_DLSCH_t *dlsch,
|
LTE_eNB_DLSCH_t *dlsch,
|
||||||
@@ -112,6 +113,7 @@ int dlsch_encoding_all(PHY_VARS_eNB *eNB,
|
|||||||
@returns status
|
@returns status
|
||||||
*/
|
*/
|
||||||
int32_t dlsch_encoding(PHY_VARS_eNB *eNB,
|
int32_t dlsch_encoding(PHY_VARS_eNB *eNB,
|
||||||
|
L1_rxtx_proc_t *proc,
|
||||||
uint8_t *a,
|
uint8_t *a,
|
||||||
uint8_t num_pdcch_symbols,
|
uint8_t num_pdcch_symbols,
|
||||||
LTE_eNB_DLSCH_t *dlsch,
|
LTE_eNB_DLSCH_t *dlsch,
|
||||||
@@ -467,10 +469,13 @@ void rx_ulsch(PHY_VARS_eNB *eNB,
|
|||||||
|
|
||||||
|
|
||||||
int ulsch_decoding_data_all(PHY_VARS_eNB *eNB,
|
int ulsch_decoding_data_all(PHY_VARS_eNB *eNB,
|
||||||
|
|
||||||
|
L1_rxtx_proc_t *proc,
|
||||||
int UE_id,
|
int UE_id,
|
||||||
int harq_pid,
|
int harq_pid,
|
||||||
int llr8_flag);
|
int llr8_flag);
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Decoding of PUSCH/ACK/RI/ACK from 36-212.
|
\brief Decoding of PUSCH/ACK/RI/ACK from 36-212.
|
||||||
@param phy_vars_eNB Pointer to eNB top-level descriptor
|
@param phy_vars_eNB Pointer to eNB top-level descriptor
|
||||||
@@ -511,6 +516,7 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,
|
|||||||
@returns 0 on success
|
@returns 0 on success
|
||||||
*/
|
*/
|
||||||
int ulsch_decoding_data(PHY_VARS_eNB *eNB,
|
int ulsch_decoding_data(PHY_VARS_eNB *eNB,
|
||||||
|
L1_rxtx_proc_t *proc,
|
||||||
int UE_id,
|
int UE_id,
|
||||||
int harq_pid,
|
int harq_pid,
|
||||||
int llr8_flag);
|
int llr8_flag);
|
||||||
|
|||||||
@@ -41,22 +41,22 @@
|
|||||||
#include "RRC/LTE/rrc_extern.h"
|
#include "RRC/LTE/rrc_extern.h"
|
||||||
#include "PHY_INTERFACE/phy_interface.h"
|
#include "PHY_INTERFACE/phy_interface.h"
|
||||||
#include "transport_proto.h"
|
#include "transport_proto.h"
|
||||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
#include <executables/split_headers.h>
|
||||||
|
|
||||||
|
|
||||||
extern WORKER_CONF_t get_thread_worker_conf(void);
|
extern WORKER_CONF_t get_thread_worker_conf(void);
|
||||||
extern volatile int oai_exit;
|
extern volatile int oai_exit;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void free_eNB_ulsch(LTE_eNB_ULSCH_t *ulsch) {
|
void free_eNB_ulsch(LTE_eNB_ULSCH_t *ulsch) {
|
||||||
int i,r;
|
int i,r;
|
||||||
|
|
||||||
if (ulsch) {
|
if (ulsch) {
|
||||||
for (i=0; i<8; i++) {
|
for (i=0; i<8; i++) {
|
||||||
if (ulsch->harq_processes[i]) {
|
if (ulsch->harq_processes[i]) {
|
||||||
if (ulsch->harq_processes[i]->b) {
|
if (ulsch->harq_processes[i]->decodedBytes) {
|
||||||
free16(ulsch->harq_processes[i]->b,MAX_ULSCH_PAYLOAD_BYTES);
|
free16(ulsch->harq_processes[i]->decodedBytes,MAX_ULSCH_PAYLOAD_BYTES);
|
||||||
ulsch->harq_processes[i]->b = NULL;
|
ulsch->harq_processes[i]->decodedBytes = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++) {
|
for (r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++) {
|
||||||
@@ -115,10 +115,10 @@ LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uin
|
|||||||
|
|
||||||
if (ulsch->harq_processes[i]) {
|
if (ulsch->harq_processes[i]) {
|
||||||
memset(ulsch->harq_processes[i],0,sizeof(LTE_UL_eNB_HARQ_t));
|
memset(ulsch->harq_processes[i],0,sizeof(LTE_UL_eNB_HARQ_t));
|
||||||
ulsch->harq_processes[i]->b = (uint8_t *)malloc16(MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
|
ulsch->harq_processes[i]->decodedBytes = (uint8_t *)malloc16(MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
|
||||||
|
|
||||||
if (ulsch->harq_processes[i]->b)
|
if (ulsch->harq_processes[i]->decodedBytes)
|
||||||
memset(ulsch->harq_processes[i]->b,0,MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
|
memset(ulsch->harq_processes[i]->decodedBytes,0,MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
|
||||||
else
|
else
|
||||||
exit_flag=3;
|
exit_flag=3;
|
||||||
|
|
||||||
@@ -210,388 +210,26 @@ uint8_t extract_cqi_crc(uint8_t *cqi,uint8_t CQI_LENGTH) {
|
|||||||
return(crc);
|
return(crc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void processULSegment(void * arg) {
|
||||||
|
turboDecode_t* rdata=(turboDecode_t*) arg;
|
||||||
|
PHY_VARS_eNB *eNB=rdata->eNB;
|
||||||
int ulsch_decoding_data_2thread0(td_params *tdp) {
|
LTE_UL_eNB_HARQ_t *ulsch_harq=rdata->ulsch_harq;
|
||||||
PHY_VARS_eNB *eNB = tdp->eNB;
|
int r=rdata->segment_r;
|
||||||
int UE_id = tdp->UE_id;
|
|
||||||
int harq_pid = tdp->harq_pid;
|
|
||||||
int llr8_flag = tdp->llr8_flag;
|
|
||||||
unsigned int r,r_offset=0,Kr,Kr_bytes;
|
|
||||||
uint8_t crc_type;
|
|
||||||
int offset = 0;
|
|
||||||
int ret = 1;
|
|
||||||
int16_t dummy_w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)];
|
|
||||||
LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id];
|
|
||||||
LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
|
|
||||||
int Q_m = ulsch_harq->Qm;
|
|
||||||
int G=ulsch_harq->G;
|
int G=ulsch_harq->G;
|
||||||
uint32_t E=0;
|
int Kr_bytes=rdata->Kr>>3;
|
||||||
uint32_t Gp,GpmodC,Nl=1;
|
int16_t dummy_w[3*(6144+64)];
|
||||||
uint32_t C = ulsch_harq->C;
|
|
||||||
decoder_if_t *tc;
|
|
||||||
|
|
||||||
if (llr8_flag == 0)
|
memset(&dummy_w[0],0,3*(6144+64)*sizeof(short));
|
||||||
tc = decoder16;
|
|
||||||
else
|
|
||||||
tc = decoder8;
|
|
||||||
|
|
||||||
// go through first half of segments to get r_offset
|
|
||||||
for (r=0; r<(ulsch_harq->C/2); r++) {
|
|
||||||
// Get Turbo interleaver parameters
|
|
||||||
if (r<ulsch_harq->Cminus)
|
|
||||||
Kr = ulsch_harq->Kminus;
|
|
||||||
else
|
|
||||||
Kr = ulsch_harq->Kplus;
|
|
||||||
|
|
||||||
Kr_bytes = Kr>>3;
|
|
||||||
// This is stolen from rate-matching algorithm to get the value of E
|
|
||||||
Gp = G/Nl/Q_m;
|
|
||||||
GpmodC = Gp%C;
|
|
||||||
|
|
||||||
if (r < (C-(GpmodC)))
|
|
||||||
E = Nl*Q_m * (Gp/C);
|
|
||||||
else
|
|
||||||
E = Nl*Q_m * ((GpmodC==0?0:1) + (Gp/C));
|
|
||||||
|
|
||||||
r_offset += E;
|
|
||||||
|
|
||||||
if (r==0) {
|
|
||||||
offset = Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0);
|
|
||||||
} else {
|
|
||||||
offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// go through second half of segments
|
|
||||||
for (; r<(ulsch_harq->C); r++) {
|
|
||||||
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
|
|
||||||
// Get Turbo interleaver parameters
|
|
||||||
if (r<ulsch_harq->Cminus)
|
|
||||||
Kr = ulsch_harq->Kminus;
|
|
||||||
else
|
|
||||||
Kr = ulsch_harq->Kplus;
|
|
||||||
|
|
||||||
Kr_bytes = Kr>>3;
|
|
||||||
memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short));
|
|
||||||
ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8),
|
ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8),
|
||||||
(uint8_t *)&dummy_w[r][0],
|
(uint8_t *)&dummy_w[0],
|
||||||
(r==0) ? ulsch_harq->F : 0);
|
(r==0) ? ulsch_harq->F : 0);
|
||||||
#ifdef DEBUG_ULSCH_DECODING
|
|
||||||
printf("Rate Matching Segment %u (coded bits (G) %d,unpunctured/repeated bits %u, Q_m %d, nb_rb %d, Nl %d)...\n",
|
|
||||||
r, G,
|
|
||||||
Kr*3,
|
|
||||||
Q_m,
|
|
||||||
nb_rb,
|
|
||||||
ulsch_harq->Nl);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (lte_rate_matching_turbo_rx(ulsch_harq->RTC[r],
|
|
||||||
G,
|
|
||||||
ulsch_harq->w[r],
|
|
||||||
(uint8_t *) &dummy_w[r][0],
|
|
||||||
ulsch_harq->e+r_offset,
|
|
||||||
ulsch_harq->C,
|
|
||||||
NSOFT,
|
|
||||||
0, //Uplink
|
|
||||||
1,
|
|
||||||
ulsch_harq->rvidx,
|
|
||||||
(ulsch_harq->round==0)?1:0, // clear
|
|
||||||
ulsch_harq->Qm,
|
|
||||||
1,
|
|
||||||
r,
|
|
||||||
&E)==-1) {
|
|
||||||
LOG_E(PHY,"ulsch_decoding.c: Problem in rate matching\n");
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
r_offset += E;
|
|
||||||
sub_block_deinterleaving_turbo(4+Kr,
|
|
||||||
&ulsch_harq->d[r][96],
|
|
||||||
ulsch_harq->w[r]);
|
|
||||||
|
|
||||||
if (ulsch_harq->C == 1)
|
|
||||||
crc_type = CRC24_A;
|
|
||||||
else
|
|
||||||
crc_type = CRC24_B;
|
|
||||||
|
|
||||||
ret = tc(&ulsch_harq->d[r][96],
|
|
||||||
NULL,
|
|
||||||
ulsch_harq->c[r],
|
|
||||||
NULL,
|
|
||||||
Kr,
|
|
||||||
ulsch->max_turbo_iterations,//MAX_TURBO_ITERATIONS,
|
|
||||||
crc_type,
|
|
||||||
(r==0) ? ulsch_harq->F : 0,
|
|
||||||
&eNB->ulsch_tc_init_stats,
|
|
||||||
&eNB->ulsch_tc_alpha_stats,
|
|
||||||
&eNB->ulsch_tc_beta_stats,
|
|
||||||
&eNB->ulsch_tc_gamma_stats,
|
|
||||||
&eNB->ulsch_tc_ext_stats,
|
|
||||||
&eNB->ulsch_tc_intl1_stats,
|
|
||||||
&eNB->ulsch_tc_intl2_stats);
|
|
||||||
|
|
||||||
// Reassembly of Transport block here
|
|
||||||
|
|
||||||
if (ret != (1+ulsch->max_turbo_iterations)) {
|
|
||||||
if (r<ulsch_harq->Cminus)
|
|
||||||
Kr = ulsch_harq->Kminus;
|
|
||||||
else
|
|
||||||
Kr = ulsch_harq->Kplus;
|
|
||||||
|
|
||||||
Kr_bytes = Kr>>3;
|
|
||||||
memcpy(ulsch_harq->b+offset,
|
|
||||||
ulsch_harq->c[r],
|
|
||||||
Kr_bytes - ((ulsch_harq->C>1)?3:0));
|
|
||||||
offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0));
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void *td_thread(void *param) {
|
|
||||||
PHY_VARS_eNB *eNB = ((td_params *)param)->eNB;
|
|
||||||
L1_proc_t *proc = &eNB->proc;
|
|
||||||
pthread_setname_np( pthread_self(),"td processing");
|
|
||||||
LOG_I(PHY,"thread td created id=%ld\n", syscall(__NR_gettid));
|
|
||||||
//wait_sync("td_thread");
|
|
||||||
|
|
||||||
while (!oai_exit) {
|
|
||||||
if (wait_on_condition(&proc->mutex_td,&proc->cond_td,&proc->instance_cnt_td,"td thread")<0) break;
|
|
||||||
|
|
||||||
if(oai_exit) break;
|
|
||||||
|
|
||||||
((td_params *)param)->ret = ulsch_decoding_data_2thread0((td_params *)param);
|
|
||||||
|
|
||||||
if (release_thread(&proc->mutex_td,&proc->instance_cnt_td,"td thread")<0) break;
|
|
||||||
|
|
||||||
if (pthread_cond_signal(&proc->cond_td) != 0) {
|
|
||||||
printf("[eNB] ERROR pthread_cond_signal for td thread exit\n");
|
|
||||||
exit_fun( "ERROR pthread_cond_signal" );
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) {
|
|
||||||
L1_proc_t *proc = &eNB->proc;
|
|
||||||
unsigned int r,r_offset=0,Kr,Kr_bytes;
|
|
||||||
uint8_t crc_type;
|
|
||||||
int offset = 0;
|
|
||||||
int ret = 1;
|
|
||||||
int16_t dummy_w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)];
|
|
||||||
LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id];
|
|
||||||
LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
|
|
||||||
int G = ulsch_harq->G;
|
|
||||||
unsigned int E;
|
|
||||||
int Cby2;
|
|
||||||
decoder_if_t *tc;
|
|
||||||
struct timespec wait;
|
|
||||||
wait.tv_sec=0;
|
|
||||||
wait.tv_nsec=5000000L;
|
|
||||||
|
|
||||||
if (llr8_flag == 0)
|
|
||||||
tc = decoder16;
|
|
||||||
else
|
|
||||||
tc = decoder8;
|
|
||||||
|
|
||||||
if (ulsch_harq->C>1) { // wakeup worker if more than 1 segment
|
|
||||||
if (pthread_mutex_timedlock(&proc->mutex_td,&wait) != 0) {
|
|
||||||
printf("[eNB] ERROR pthread_mutex_lock for TD thread (IC %d)\n", proc->instance_cnt_td);
|
|
||||||
exit_fun( "error locking mutex_fep" );
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (proc->instance_cnt_td==0) {
|
|
||||||
printf("[eNB] TD thread busy\n");
|
|
||||||
exit_fun("TD thread busy");
|
|
||||||
pthread_mutex_unlock( &proc->mutex_td );
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
++proc->instance_cnt_td;
|
|
||||||
proc->tdp.eNB = eNB;
|
|
||||||
proc->tdp.UE_id = UE_id;
|
|
||||||
proc->tdp.harq_pid = harq_pid;
|
|
||||||
proc->tdp.llr8_flag = llr8_flag;
|
|
||||||
|
|
||||||
// wakeup worker to do second half segments
|
|
||||||
if (pthread_cond_signal(&proc->cond_td) != 0) {
|
|
||||||
printf("[eNB] ERROR pthread_cond_signal for td thread exit\n");
|
|
||||||
exit_fun( "ERROR pthread_cond_signal" );
|
|
||||||
return (1+ulsch->max_turbo_iterations);
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_unlock( &proc->mutex_td );
|
|
||||||
Cby2 = ulsch_harq->C/2;
|
|
||||||
} else {
|
|
||||||
Cby2 = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// go through first half of segments in main thread
|
|
||||||
for (r=0; r<Cby2; r++) {
|
|
||||||
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
|
|
||||||
// Get Turbo interleaver parameters
|
|
||||||
if (r<ulsch_harq->Cminus)
|
|
||||||
Kr = ulsch_harq->Kminus;
|
|
||||||
else
|
|
||||||
Kr = ulsch_harq->Kplus;
|
|
||||||
|
|
||||||
Kr_bytes = Kr>>3;
|
|
||||||
memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short));
|
|
||||||
ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8),
|
|
||||||
(uint8_t *)&dummy_w[r][0],
|
|
||||||
(r==0) ? ulsch_harq->F : 0);
|
|
||||||
#ifdef DEBUG_ULSCH_DECODING
|
|
||||||
printf("Rate Matching Segment %u (coded bits (G) %d,unpunctured/repeated bits %u, Q_m %d, nb_rb %d, Nl %d)...\n",
|
|
||||||
r, G,
|
|
||||||
Kr*3,
|
|
||||||
Q_m,
|
|
||||||
nb_rb,
|
|
||||||
ulsch_harq->Nl);
|
|
||||||
#endif
|
|
||||||
start_meas(&eNB->ulsch_rate_unmatching_stats);
|
|
||||||
|
|
||||||
if (lte_rate_matching_turbo_rx(ulsch_harq->RTC[r],
|
|
||||||
G,
|
|
||||||
ulsch_harq->w[r],
|
|
||||||
(uint8_t *) &dummy_w[r][0],
|
|
||||||
ulsch_harq->e+r_offset,
|
|
||||||
ulsch_harq->C,
|
|
||||||
NSOFT,
|
|
||||||
0, //Uplink
|
|
||||||
1,
|
|
||||||
ulsch_harq->rvidx,
|
|
||||||
(ulsch_harq->round==0)?1:0, // clear
|
|
||||||
ulsch_harq->Qm,
|
|
||||||
1,
|
|
||||||
r,
|
|
||||||
&E)==-1) {
|
|
||||||
LOG_E(PHY,"ulsch_decoding.c: Problem in rate matching\n");
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
stop_meas(&eNB->ulsch_rate_unmatching_stats);
|
|
||||||
r_offset += E;
|
|
||||||
start_meas(&eNB->ulsch_deinterleaving_stats);
|
start_meas(&eNB->ulsch_deinterleaving_stats);
|
||||||
sub_block_deinterleaving_turbo(4+Kr,
|
|
||||||
&ulsch_harq->d[r][96],
|
|
||||||
ulsch_harq->w[r]);
|
|
||||||
stop_meas(&eNB->ulsch_deinterleaving_stats);
|
|
||||||
|
|
||||||
if (ulsch_harq->C == 1)
|
|
||||||
crc_type = CRC24_A;
|
|
||||||
else
|
|
||||||
crc_type = CRC24_B;
|
|
||||||
|
|
||||||
start_meas(&eNB->ulsch_turbo_decoding_stats);
|
|
||||||
ret = tc(&ulsch_harq->d[r][96],
|
|
||||||
NULL,
|
|
||||||
ulsch_harq->c[r],
|
|
||||||
NULL,
|
|
||||||
Kr,
|
|
||||||
ulsch->max_turbo_iterations,//MAX_TURBO_ITERATIONS,
|
|
||||||
crc_type,
|
|
||||||
(r==0) ? ulsch_harq->F : 0,
|
|
||||||
&eNB->ulsch_tc_init_stats,
|
|
||||||
&eNB->ulsch_tc_alpha_stats,
|
|
||||||
&eNB->ulsch_tc_beta_stats,
|
|
||||||
&eNB->ulsch_tc_gamma_stats,
|
|
||||||
&eNB->ulsch_tc_ext_stats,
|
|
||||||
&eNB->ulsch_tc_intl1_stats,
|
|
||||||
&eNB->ulsch_tc_intl2_stats);
|
|
||||||
|
|
||||||
// Reassembly of Transport block here
|
|
||||||
|
|
||||||
if (ret != (1+ulsch->max_turbo_iterations)) {
|
|
||||||
if (r<ulsch_harq->Cminus)
|
|
||||||
Kr = ulsch_harq->Kminus;
|
|
||||||
else
|
|
||||||
Kr = ulsch_harq->Kplus;
|
|
||||||
|
|
||||||
Kr_bytes = Kr>>3;
|
|
||||||
|
|
||||||
if (r==0) {
|
|
||||||
memcpy(ulsch_harq->b,
|
|
||||||
&ulsch_harq->c[0][(ulsch_harq->F>>3)],
|
|
||||||
Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0));
|
|
||||||
offset = Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0);
|
|
||||||
} else {
|
|
||||||
memcpy(ulsch_harq->b+offset,
|
|
||||||
ulsch_harq->c[r],
|
|
||||||
Kr_bytes - ((ulsch_harq->C>1)?3:0));
|
|
||||||
offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
stop_meas(&eNB->ulsch_turbo_decoding_stats);
|
|
||||||
//printf("/////////////////////////////////////////**************************loop for %d time in ulsch_decoding main\n",r);
|
|
||||||
}
|
|
||||||
|
|
||||||
// wait for worker to finish
|
|
||||||
wait_on_busy_condition(&proc->mutex_td,&proc->cond_td,&proc->instance_cnt_td,"td thread");
|
|
||||||
return( (ret>proc->tdp.ret) ? ret : proc->tdp.ret );
|
|
||||||
}
|
|
||||||
|
|
||||||
int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) {
|
|
||||||
unsigned int r,r_offset=0,Kr,Kr_bytes;
|
|
||||||
uint8_t crc_type;
|
|
||||||
int offset = 0;
|
|
||||||
int ret = 1;
|
|
||||||
int16_t dummy_w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)];
|
|
||||||
LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id];
|
|
||||||
LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
|
|
||||||
int G = ulsch_harq->G;
|
|
||||||
unsigned int E;
|
unsigned int E;
|
||||||
decoder_if_t *tc;
|
|
||||||
static int32_t pusch_rep_buffer[3*(6144+64)];
|
|
||||||
int max_Ncb;
|
|
||||||
|
|
||||||
if (llr8_flag == 0)
|
|
||||||
tc = *decoder16;
|
|
||||||
else
|
|
||||||
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++) {
|
|
||||||
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
|
|
||||||
// Get Turbo interleaver parameters
|
|
||||||
if (r<ulsch_harq->Cminus)
|
|
||||||
Kr = ulsch_harq->Kminus;
|
|
||||||
else
|
|
||||||
Kr = ulsch_harq->Kplus;
|
|
||||||
|
|
||||||
Kr_bytes = Kr>>3;
|
|
||||||
memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short));
|
|
||||||
ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8),
|
|
||||||
(uint8_t *)&dummy_w[r][0],
|
|
||||||
(r==0) ? ulsch_harq->F : 0);
|
|
||||||
#ifdef DEBUG_ULSCH_DECODING
|
|
||||||
printf("Rate Matching Segment %u (coded bits (G) %d,unpunctured/repeated bits %u, Q_m %d, Nl %d)...\n",
|
|
||||||
r, G,
|
|
||||||
Kr*3,
|
|
||||||
ulsch_harq->Qm,
|
|
||||||
ulsch_harq->Nl);
|
|
||||||
#endif
|
|
||||||
start_meas(&eNB->ulsch_rate_unmatching_stats);
|
|
||||||
|
|
||||||
if (lte_rate_matching_turbo_rx(ulsch_harq->RTC[r],
|
if (lte_rate_matching_turbo_rx(ulsch_harq->RTC[r],
|
||||||
G,
|
G,
|
||||||
ulsch_harq->w[r],
|
ulsch_harq->w[r],
|
||||||
(uint8_t *) &dummy_w[r][0],
|
(uint8_t *) &dummy_w[0],
|
||||||
ulsch_harq->e+r_offset,
|
ulsch_harq->eUL+rdata->r_offset,
|
||||||
ulsch_harq->C,
|
ulsch_harq->C,
|
||||||
NSOFT,
|
NSOFT,
|
||||||
0, //Uplink
|
0, //Uplink
|
||||||
@@ -603,48 +241,41 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag)
|
|||||||
r,
|
r,
|
||||||
&E)==-1) {
|
&E)==-1) {
|
||||||
LOG_E(PHY,"ulsch_decoding.c: Problem in rate matching\n");
|
LOG_E(PHY,"ulsch_decoding.c: Problem in rate matching\n");
|
||||||
return(-1);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
stop_meas(&eNB->ulsch_rate_unmatching_stats);
|
stop_meas(&eNB->ulsch_rate_unmatching_stats);
|
||||||
max_Ncb = 3*ulsch_harq->RTC[r]*32 ;
|
int max_Ncb = 3*ulsch_harq->RTC[r]*32 ;
|
||||||
|
|
||||||
|
if(ulsch_harq->repetition_number == 1) {
|
||||||
|
memset(ulsch_harq->pusch_rep_buffer[r],0,(sizeof(int32_t)*3*(6144+64))) ; // reset the buffer every new repetitions
|
||||||
|
}
|
||||||
if(ulsch_harq->total_number_of_repetitions > 1) {
|
if(ulsch_harq->total_number_of_repetitions > 1) {
|
||||||
if (ulsch_harq->rvidx==1) {
|
if (ulsch_harq->rvidx==1) {
|
||||||
|
LOG_E(PHY,"Adding HARQ data for segment: %d\n", r);
|
||||||
// Store the result of HARQ combining in the last emtc repetitions of sequence 0,2,3,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++) {
|
for (int nn=0; nn<max_Ncb; nn++)
|
||||||
pusch_rep_buffer[nn] += ulsch_harq->w[r][nn] ;
|
ulsch_harq->pusch_rep_buffer[r][nn] += ulsch_harq->w[r][nn] ;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ulsch_harq->repetition_number == ulsch_harq->total_number_of_repetitions) {
|
if (ulsch_harq->repetition_number == ulsch_harq->total_number_of_repetitions) {
|
||||||
for (int nn=0; nn<max_Ncb; nn++) {
|
LOG_E(PHY,"Will use HARQ data sum up for segment: %d\n", r);
|
||||||
ulsch_harq->w[r][nn] = pusch_rep_buffer[nn] ;
|
for (int nn=0; nn<max_Ncb; nn++)
|
||||||
|
ulsch_harq->w[r][nn] = ulsch_harq->pusch_rep_buffer[r][nn] ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
int16_t soft_bits[3*8*6144+12+96] __attribute__((aligned(32)));
|
||||||
|
sub_block_deinterleaving_turbo(4+rdata->Kr,
|
||||||
r_offset += E;
|
soft_bits+96,
|
||||||
start_meas(&eNB->ulsch_deinterleaving_stats);
|
|
||||||
sub_block_deinterleaving_turbo(4+Kr,
|
|
||||||
&ulsch_harq->d[r][96],
|
|
||||||
ulsch_harq->w[r]);
|
ulsch_harq->w[r]);
|
||||||
stop_meas(&eNB->ulsch_deinterleaving_stats);
|
stop_meas(&eNB->ulsch_deinterleaving_stats);
|
||||||
|
rdata->decodeIterations = rdata->function( soft_bits+96,
|
||||||
if (ulsch_harq->C == 1)
|
|
||||||
crc_type = CRC24_A;
|
|
||||||
else
|
|
||||||
crc_type = CRC24_B;
|
|
||||||
|
|
||||||
start_meas(&eNB->ulsch_turbo_decoding_stats);
|
|
||||||
ret = tc(&ulsch_harq->d[r][96],
|
|
||||||
NULL,
|
NULL,
|
||||||
ulsch_harq->c[r],
|
rdata->decoded_bytes,
|
||||||
NULL,
|
NULL,
|
||||||
Kr,
|
rdata->Kr,
|
||||||
ulsch->max_turbo_iterations,//MAX_TURBO_ITERATIONS,
|
rdata->maxIterations,
|
||||||
crc_type,
|
rdata->nbSegments == 1 ? CRC24_A: CRC24_B,
|
||||||
(r==0) ? ulsch_harq->F : 0,
|
rdata->Fbits,
|
||||||
&eNB->ulsch_tc_init_stats,
|
&eNB->ulsch_tc_init_stats,
|
||||||
&eNB->ulsch_tc_alpha_stats,
|
&eNB->ulsch_tc_alpha_stats,
|
||||||
&eNB->ulsch_tc_beta_stats,
|
&eNB->ulsch_tc_beta_stats,
|
||||||
@@ -654,46 +285,88 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag)
|
|||||||
&eNB->ulsch_tc_intl2_stats);
|
&eNB->ulsch_tc_intl2_stats);
|
||||||
stop_meas(&eNB->ulsch_turbo_decoding_stats);
|
stop_meas(&eNB->ulsch_turbo_decoding_stats);
|
||||||
|
|
||||||
// Reassembly of Transport block here
|
}
|
||||||
|
|
||||||
if (ret != (1+ulsch->max_turbo_iterations)) {
|
void *td_thread(void *param) {
|
||||||
if (r<ulsch_harq->Cminus)
|
|
||||||
Kr = ulsch_harq->Kminus;
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ulsch_decoding_data(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc,
|
||||||
|
int UE_id,int harq_pid,int llr8_flag) {
|
||||||
|
unsigned int r_offset=0;
|
||||||
|
int offset = 0;
|
||||||
|
LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id];
|
||||||
|
LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
|
||||||
|
int G = ulsch_harq->G;
|
||||||
|
unsigned int E;
|
||||||
|
int ret=0;
|
||||||
|
|
||||||
|
decoder_if_t * td=llr8_flag == 0 ?
|
||||||
|
*decoder16 : *decoder8;
|
||||||
|
ulsch_harq->processedSegments=0;
|
||||||
|
|
||||||
|
for (int r=0; r<ulsch_harq->C; r++) {
|
||||||
|
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
|
||||||
|
// Get Turbo interleaver parameters
|
||||||
|
unsigned int Kr= r<ulsch_harq->Cminus ?
|
||||||
|
ulsch_harq->Kminus :ulsch_harq->Kplus;
|
||||||
|
unsigned int Kr_bytes = Kr>>3;
|
||||||
|
|
||||||
|
#ifdef DEBUG_ULSCH_DECODING
|
||||||
|
printf("Rate Matching Segment %d (coded bits (G) %d,unpunctured/repeated bits %u, Q_m %d, Nl %d, r_offset %u)...\n",
|
||||||
|
r, G,
|
||||||
|
Kr*3,
|
||||||
|
ulsch_harq->Qm,
|
||||||
|
ulsch_harq->Nl, r_offset);
|
||||||
|
#endif
|
||||||
|
int Gp=G/ulsch_harq->Qm;
|
||||||
|
int GpmodC = Gp%ulsch_harq->C;
|
||||||
|
|
||||||
|
if (r < (ulsch_harq->C-(GpmodC)))
|
||||||
|
E = ulsch_harq->Qm * (Gp/ulsch_harq->C);
|
||||||
else
|
else
|
||||||
Kr = ulsch_harq->Kplus;
|
E = ulsch_harq->Qm * ((GpmodC==0?0:1) + (Gp/ulsch_harq->C));
|
||||||
|
|
||||||
Kr_bytes = Kr>>3;
|
if ( split73 == SPLIT73_DU ) {
|
||||||
|
sendFs6Ul(eNB, UE_id, harq_pid, r, ulsch_harq->eUL+r_offset, E*sizeof(int16_t), r_offset);
|
||||||
if (r==0) {
|
r_offset += E;
|
||||||
memcpy(ulsch_harq->b,
|
continue;
|
||||||
&ulsch_harq->c[0][(ulsch_harq->F>>3)],
|
|
||||||
Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0));
|
|
||||||
offset = Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0);
|
|
||||||
} else {
|
|
||||||
memcpy(ulsch_harq->b+offset,
|
|
||||||
ulsch_harq->c[r],
|
|
||||||
Kr_bytes - ((ulsch_harq->C>1)?3:0));
|
|
||||||
offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
union turboReqUnion id= {.s={ulsch->rnti,proc->frame_rx,proc->subframe_rx,0,0}};
|
||||||
|
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(turboDecode_t), id.p, proc->respDecode, processULSegment);
|
||||||
|
turboDecode_t * rdata=(turboDecode_t *) NotifiedFifoData(req);
|
||||||
|
|
||||||
|
rdata->eNB=eNB;
|
||||||
|
rdata->frame=proc->frame_rx;
|
||||||
|
rdata->subframe=proc->subframe_rx;
|
||||||
|
rdata->UEid=UE_id;
|
||||||
|
rdata->harq_pid=harq_pid;
|
||||||
|
rdata->Kr=Kr;
|
||||||
|
rdata->maxIterations=eNB->ulsch[UE_id]->max_turbo_iterations;
|
||||||
|
rdata->ulsch_harq=ulsch_harq;
|
||||||
|
rdata->eNB=eNB;
|
||||||
|
rdata->nbSegments=ulsch_harq->C;
|
||||||
|
rdata->segment_r=r;
|
||||||
|
rdata->Fbits=(r==0) ? ulsch_harq->F : 0;
|
||||||
|
rdata->r_offset=r_offset;
|
||||||
|
rdata->offset=offset;
|
||||||
|
rdata->function=td;
|
||||||
|
int Fbytes=(r==0) ? rdata->Fbits>>3 : 0;
|
||||||
|
int sz=Kr_bytes - Fbytes - ((ulsch_harq->C>1)?3:0);
|
||||||
|
pushTpool(proc->threadPool,req);
|
||||||
|
proc->nbDecode++;
|
||||||
|
LOG_D(PHY,"Added a block to decode, in pipe: %d\n",proc->nbDecode);
|
||||||
|
r_offset+=E;
|
||||||
|
offset+=sz;
|
||||||
|
}
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ulsch_decoding_data_all(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) {
|
int ulsch_decoding_data_all(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,
|
||||||
int ret = 0;
|
int UE_id,int harq_pid,int llr8_flag) {
|
||||||
/*if(get_thread_worker_conf() == WORKER_ENABLE)
|
return ulsch_decoding_data(eNB,proc,UE_id,harq_pid,llr8_flag);
|
||||||
{
|
|
||||||
ret = ulsch_decoding_data_2thread(eNB,UE_id,harq_pid,llr8_flag);
|
|
||||||
}
|
|
||||||
else*/
|
|
||||||
{
|
|
||||||
ret = ulsch_decoding_data(eNB,UE_id,harq_pid,llr8_flag);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2, unsigned char reset) __attribute__((always_inline));
|
static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2, unsigned char reset) __attribute__((always_inline));
|
||||||
@@ -767,7 +440,6 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,
|
|||||||
else
|
else
|
||||||
harq_pid = subframe2harq_pid(frame_parms,proc->frame_rx,subframe);
|
harq_pid = subframe2harq_pid(frame_parms,proc->frame_rx,subframe);
|
||||||
|
|
||||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0+harq_pid,1);
|
|
||||||
// x1 is set in lte_gold_generic
|
// x1 is set in lte_gold_generic
|
||||||
x2 = ((uint32_t)ulsch->rnti<<14) + ((uint32_t)subframe<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.3.1
|
x2 = ((uint32_t)ulsch->rnti<<14) + ((uint32_t)subframe<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.3.1
|
||||||
ulsch_harq = ulsch->harq_processes[harq_pid];
|
ulsch_harq = ulsch->harq_processes[harq_pid];
|
||||||
@@ -779,8 +451,9 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,
|
|||||||
A = ulsch_harq->TBS;
|
A = ulsch_harq->TBS;
|
||||||
Q_m = ulsch_harq->Qm;
|
Q_m = ulsch_harq->Qm;
|
||||||
G = nb_rb * (12 * Q_m) * ulsch_harq->Nsymb_pusch;
|
G = nb_rb * (12 * Q_m) * ulsch_harq->Nsymb_pusch;
|
||||||
|
LOG_D(PHY, "PUSCH nb_rb %d Q_m %d ulsch_harq->Nsymb_pusch %d\n",nb_rb, Q_m, ulsch_harq->Nsymb_pusch);
|
||||||
//#ifdef DEBUG_ULSCH_DECODING
|
//#ifdef DEBUG_ULSCH_DECODING
|
||||||
LOG_D(PHY,"[PUSCH %d] Frame %d, Subframe %d: ulsch_decoding (Nid_cell %d, rnti %x, x2 %x): A %d, round %d, RV %d, O_r1 %d, O_RI %d, O_ACK %d, G %d, Q_m %d Nsymb_pusch %d nb_rb %d\n",
|
LOG_D(PHY,"[PUSCH harq %d] Frame %d, Subframe %d: ulsch_decoding (Nid_cell %d, rnti %x, x2 %x): TBS %d, round %d, RV %d, O_r1 %d, O_RI %d, O_ACK %d, G %d, Q_m %d Nsymb_pusch %d nb_rb %d\n",
|
||||||
harq_pid,
|
harq_pid,
|
||||||
proc->frame_rx,subframe,
|
proc->frame_rx,subframe,
|
||||||
frame_parms->Nid_cell,ulsch->rnti,x2,
|
frame_parms->Nid_cell,ulsch->rnti,x2,
|
||||||
@@ -833,6 +506,12 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,
|
|||||||
subframe);
|
subframe);
|
||||||
// Compute Q_ri
|
// Compute Q_ri
|
||||||
Qprime = ulsch_harq->O_RI*ulsch_harq->Msc_initial*ulsch_harq->Nsymb_initial * ulsch->beta_offset_ri_times8;
|
Qprime = ulsch_harq->O_RI*ulsch_harq->Msc_initial*ulsch_harq->Nsymb_initial * ulsch->beta_offset_ri_times8;
|
||||||
|
LOG_D(PHY, "Qprime %d, O_RI %d, Msc %d, Nym %d beta %d\n",
|
||||||
|
Qprime,
|
||||||
|
ulsch_harq->O_RI,
|
||||||
|
ulsch_harq->Msc_initial,
|
||||||
|
ulsch_harq->Nsymb_initial,
|
||||||
|
ulsch->beta_offset_ri_times8);
|
||||||
|
|
||||||
if (Qprime > 0 ) {
|
if (Qprime > 0 ) {
|
||||||
if ((Qprime % (8*sumKr)) > 0)
|
if ((Qprime % (8*sumKr)) > 0)
|
||||||
@@ -893,7 +572,7 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,
|
|||||||
G = G - Q_RI - Q_CQI;
|
G = G - Q_RI - Q_CQI;
|
||||||
ulsch_harq->G = G;
|
ulsch_harq->G = G;
|
||||||
AssertFatal((int)G > 0,
|
AssertFatal((int)G > 0,
|
||||||
"FATAL: ulsch_decoding.c G < 0 (%d) : Q_RI %d, Q_CQI %d\n",G,Q_RI,Q_CQI);
|
"FATAL: ulsch_decoding.c G < 0 (%u) : Q_RI %u, Q_CQI %u\n",G,Q_RI,Q_CQI);
|
||||||
H = G + Q_CQI;
|
H = G + Q_CQI;
|
||||||
Hprime = H/Q_m;
|
Hprime = H/Q_m;
|
||||||
// Demultiplexing/Deinterleaving of PUSCH/ACK/RI/CQI
|
// Demultiplexing/Deinterleaving of PUSCH/ACK/RI/CQI
|
||||||
@@ -1209,8 +888,8 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,
|
|||||||
j2+=2;
|
j2+=2;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulsch_harq->e[iprime++] = y[j2++];
|
ulsch_harq->eUL[iprime++] = y[j2++];
|
||||||
ulsch_harq->e[iprime++] = y[j2++];
|
ulsch_harq->eUL[iprime++] = y[j2++];
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -1222,10 +901,10 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,
|
|||||||
j2+=4;
|
j2+=4;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulsch_harq->e[iprime++] = y[j2++];
|
ulsch_harq->eUL[iprime++] = y[j2++];
|
||||||
ulsch_harq->e[iprime++] = y[j2++];
|
ulsch_harq->eUL[iprime++] = y[j2++];
|
||||||
ulsch_harq->e[iprime++] = y[j2++];
|
ulsch_harq->eUL[iprime++] = y[j2++];
|
||||||
ulsch_harq->e[iprime++] = y[j2++];
|
ulsch_harq->eUL[iprime++] = y[j2++];
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -1237,12 +916,12 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,
|
|||||||
j2+=6;
|
j2+=6;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulsch_harq->e[iprime++] = y[j2++];
|
ulsch_harq->eUL[iprime++] = y[j2++];
|
||||||
ulsch_harq->e[iprime++] = y[j2++];
|
ulsch_harq->eUL[iprime++] = y[j2++];
|
||||||
ulsch_harq->e[iprime++] = y[j2++];
|
ulsch_harq->eUL[iprime++] = y[j2++];
|
||||||
ulsch_harq->e[iprime++] = y[j2++];
|
ulsch_harq->eUL[iprime++] = y[j2++];
|
||||||
ulsch_harq->e[iprime++] = y[j2++];
|
ulsch_harq->eUL[iprime++] = y[j2++];
|
||||||
ulsch_harq->e[iprime++] = y[j2++];
|
ulsch_harq->eUL[iprime++] = y[j2++];
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -1280,7 +959,7 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,
|
|||||||
*/
|
*/
|
||||||
int16_t *yp,*ep;
|
int16_t *yp,*ep;
|
||||||
|
|
||||||
for (iprime=0,yp=&y[j2],ep=&ulsch_harq->e[0];
|
for (iprime=0,yp=&y[j2],ep=&ulsch_harq->eUL[0];
|
||||||
iprime<G;
|
iprime<G;
|
||||||
iprime+=8,j2+=8,ep+=8,yp+=8) {
|
iprime+=8,j2+=8,ep+=8,yp+=8) {
|
||||||
ep[0] = yp[0];
|
ep[0] = yp[0];
|
||||||
@@ -1404,7 +1083,6 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,
|
|||||||
|
|
||||||
LOG_D(PHY,"frame %d subframe %d O_ACK:%d o_ACK[]=%d:%d:%d:%d\n",frame,subframe,ulsch_harq->O_ACK,ulsch_harq->o_ACK[0],ulsch_harq->o_ACK[1],ulsch_harq->o_ACK[2],ulsch_harq->o_ACK[3]);
|
LOG_D(PHY,"frame %d subframe %d O_ACK:%d o_ACK[]=%d:%d:%d:%d\n",frame,subframe,ulsch_harq->O_ACK,ulsch_harq->o_ACK[0],ulsch_harq->o_ACK[1],ulsch_harq->o_ACK[2],ulsch_harq->o_ACK[3]);
|
||||||
// Do ULSCH Decoding for data portion
|
// Do ULSCH Decoding for data portion
|
||||||
ret = ulsch_decoding_data_all(eNB,UE_id,harq_pid,llr8_flag);
|
ret = ulsch_decoding_data_all(eNB,proc, UE_id,harq_pid,llr8_flag);
|
||||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0+harq_pid,0);
|
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -780,7 +780,6 @@ void ulsch_channel_compensation(int32_t **rxdataF_ext,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (rb=0; rb<nb_rb; rb++) {
|
for (rb=0; rb<nb_rb; rb++) {
|
||||||
LOG_D(PHY,"comp: symbol %d rb %d\n",symbol,rb);
|
|
||||||
// just compute channel magnitude without scaling, this is done after equalization for SC-FDMA
|
// just compute channel magnitude without scaling, this is done after equalization for SC-FDMA
|
||||||
#if defined(__x86_64__) || defined(__i386__)
|
#if defined(__x86_64__) || defined(__i386__)
|
||||||
mmtmpU0 = _mm_madd_epi16(ul_ch128[0],ul_ch128[0]);
|
mmtmpU0 = _mm_madd_epi16(ul_ch128[0],ul_ch128[0]);
|
||||||
|
|||||||
@@ -793,7 +793,7 @@ int dlsch_encoding_SIC(PHY_VARS_UE *ue,
|
|||||||
r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
|
r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
|
||||||
G, //G
|
G, //G
|
||||||
dlsch->harq_processes[harq_pid]->w[r],
|
dlsch->harq_processes[harq_pid]->w[r],
|
||||||
dlsch->harq_processes[harq_pid]->e+r_offset,
|
dlsch->harq_processes[harq_pid]->eDL+r_offset,
|
||||||
dlsch->harq_processes[harq_pid]->C, // C
|
dlsch->harq_processes[harq_pid]->C, // C
|
||||||
dlsch->Nsoft, // Nsoft,
|
dlsch->Nsoft, // Nsoft,
|
||||||
dlsch->Mdlharq,
|
dlsch->Mdlharq,
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1
|
|||||||
uint16_t *prach_root_sequence_map;
|
uint16_t *prach_root_sequence_map;
|
||||||
uint16_t preamble_offset,preamble_shift;
|
uint16_t preamble_offset,preamble_shift;
|
||||||
uint16_t preamble_index0,n_shift_ra,n_shift_ra_bar;
|
uint16_t preamble_index0,n_shift_ra,n_shift_ra_bar;
|
||||||
uint16_t d_start,numshift;
|
uint16_t d_start=-1,numshift;
|
||||||
uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type);
|
uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type);
|
||||||
//uint8_t Nsp=2;
|
//uint8_t Nsp=2;
|
||||||
//uint8_t f_ra,t1_ra;
|
//uint8_t f_ra,t1_ra;
|
||||||
|
|||||||
@@ -446,6 +446,13 @@ uint32_t ulsch_encoding(uint8_t *a,
|
|||||||
Qprime = (ulsch->O + L) * ulsch->harq_processes[harq_pid]->Msc_initial*ulsch->harq_processes[harq_pid]->Nsymb_initial * ulsch->beta_offset_cqi_times8;
|
Qprime = (ulsch->O + L) * ulsch->harq_processes[harq_pid]->Msc_initial*ulsch->harq_processes[harq_pid]->Nsymb_initial * ulsch->beta_offset_cqi_times8;
|
||||||
else
|
else
|
||||||
Qprime = 0;
|
Qprime = 0;
|
||||||
|
LOG_D(PHY,"Qprime %d, O_RI %d + %d, Msc %d, Nym %d beta %d\n",
|
||||||
|
Qprime,
|
||||||
|
ulsch->O, L,
|
||||||
|
ulsch->harq_processes[harq_pid]->Msc_initial,
|
||||||
|
ulsch->harq_processes[harq_pid]->Nsymb_initial,
|
||||||
|
ulsch->beta_offset_cqi_times8);
|
||||||
|
|
||||||
|
|
||||||
if (Qprime > 0) {
|
if (Qprime > 0) {
|
||||||
if ((Qprime % (8*sumKr)) > 0)
|
if ((Qprime % (8*sumKr)) > 0)
|
||||||
@@ -455,7 +462,7 @@ uint32_t ulsch_encoding(uint8_t *a,
|
|||||||
}
|
}
|
||||||
|
|
||||||
G = ulsch->harq_processes[harq_pid]->nb_rb * (12 * Q_m) * (ulsch->Nsymb_pusch);
|
G = ulsch->harq_processes[harq_pid]->nb_rb * (12 * Q_m) * (ulsch->Nsymb_pusch);
|
||||||
|
LOG_D(PHY,"G: rb %d * ( 12 * Qm %d ) * nsymb %d, Qprime %d, O_RI %d\n", ulsch->harq_processes[harq_pid]->nb_rb, Q_m, ulsch->Nsymb_pusch, Qprime, ulsch->O_RI);
|
||||||
if (Qprime > (G - ulsch->O_RI))
|
if (Qprime > (G - ulsch->O_RI))
|
||||||
Qprime = G - ulsch->O_RI;
|
Qprime = G - ulsch->O_RI;
|
||||||
|
|
||||||
@@ -465,6 +472,7 @@ uint32_t ulsch_encoding(uint8_t *a,
|
|||||||
|
|
||||||
|
|
||||||
G = G - Q_RI - Q_CQI;
|
G = G - Q_RI - Q_CQI;
|
||||||
|
LOG_D(PHY,"new G: %d, Q_RI %d Q_CQI %d\n", G , Q_RI , Q_CQI);
|
||||||
ulsch->harq_processes[harq_pid]->G = G;
|
ulsch->harq_processes[harq_pid]->G = G;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m) {
|
|||||||
|
|
||||||
|
|
||||||
int N_reg = n_rb * pdcch_pdu_rel15->DurationSymbols;
|
int N_reg = n_rb * pdcch_pdu_rel15->DurationSymbols;
|
||||||
int C;
|
int C=-1;
|
||||||
|
|
||||||
for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++) {
|
for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++) {
|
||||||
int L = pdcch_pdu_rel15->AggregationLevel[d];
|
int L = pdcch_pdu_rel15->AggregationLevel[d];
|
||||||
@@ -210,7 +210,7 @@ void nr_fill_dci(PHY_VARS_gNB *gNB,
|
|||||||
|
|
||||||
for (int i=0;i<pdcch_pdu_rel15->numDlDci;i++) {
|
for (int i=0;i<pdcch_pdu_rel15->numDlDci;i++) {
|
||||||
|
|
||||||
uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->Payload[i];
|
//uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->Payload[i];
|
||||||
|
|
||||||
|
|
||||||
int dlsch_id = find_nr_dlsch(pdcch_pdu_rel15->RNTI[i],gNB,SEARCH_EXIST_OR_FREE);
|
int dlsch_id = find_nr_dlsch(pdcch_pdu_rel15->RNTI[i],gNB,SEARCH_EXIST_OR_FREE);
|
||||||
@@ -248,7 +248,7 @@ void nr_fill_ul_dci(PHY_VARS_gNB *gNB,
|
|||||||
|
|
||||||
for (int i=0;i<pdcch_pdu_rel15->numDlDci;i++) {
|
for (int i=0;i<pdcch_pdu_rel15->numDlDci;i++) {
|
||||||
|
|
||||||
uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->Payload[i];
|
//uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->Payload[i];
|
||||||
|
|
||||||
// if there's no DL DCI then generate CCE list
|
// if there's no DL DCI then generate CCE list
|
||||||
if (gNB->pdcch_pdu) nr_fill_cce_list(gNB,0);
|
if (gNB->pdcch_pdu) nr_fill_cce_list(gNB,0);
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
|
|||||||
uint16_t *prach_root_sequence_map;
|
uint16_t *prach_root_sequence_map;
|
||||||
uint16_t preamble_offset,preamble_shift;
|
uint16_t preamble_offset,preamble_shift;
|
||||||
uint16_t preamble_index0,n_shift_ra,n_shift_ra_bar;
|
uint16_t preamble_index0,n_shift_ra,n_shift_ra_bar;
|
||||||
uint16_t d_start,numshift;
|
uint16_t d_start=-1,numshift;
|
||||||
|
|
||||||
uint16_t prach_fmt = get_nr_prach_fmt(prach_ConfigIndex,fp->frame_type,fp->freq_range);
|
uint16_t prach_fmt = get_nr_prach_fmt(prach_ConfigIndex,fp->frame_type,fp->freq_range);
|
||||||
//uint8_t Nsp=2;
|
//uint8_t Nsp=2;
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
|||||||
uint16_t beta_ptrs; // PTRS parameter related to power control
|
uint16_t beta_ptrs; // PTRS parameter related to power control
|
||||||
|
|
||||||
NR_UE_ULSCH_t *ulsch_ue;
|
NR_UE_ULSCH_t *ulsch_ue;
|
||||||
NR_UL_UE_HARQ_t *harq_process_ul_ue;
|
NR_UL_UE_HARQ_t *harq_process_ul_ue=NULL;
|
||||||
NR_DL_FRAME_PARMS *frame_parms = &UE->frame_parms;
|
NR_DL_FRAME_PARMS *frame_parms = &UE->frame_parms;
|
||||||
NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][gNB_id];
|
NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][gNB_id];
|
||||||
uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES];
|
uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES];
|
||||||
|
|||||||
@@ -325,14 +325,20 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
|
|||||||
// PUSCH I/Q of MF Output
|
// PUSCH I/Q of MF Output
|
||||||
if (pusch_comp!=NULL) {
|
if (pusch_comp!=NULL) {
|
||||||
ind=0;
|
ind=0;
|
||||||
|
int range=80*1000*1000;
|
||||||
|
|
||||||
for (k=0; k<frame_parms->symbols_per_tti; k++) {
|
for (k=0; k<frame_parms->symbols_per_tti; k++) {
|
||||||
for (i=0; i<12*frame_parms->N_RB_UL; i++) {
|
for (i=0; i<12*frame_parms->N_RB_UL; i++) {
|
||||||
|
if ( pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i] > -range &&
|
||||||
|
pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i] < range &&
|
||||||
|
pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i+1] > -range &&
|
||||||
|
pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i+1] < range ) {
|
||||||
I[ind] = pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i];
|
I[ind] = pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i];
|
||||||
Q[ind] = pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i+1];
|
Q[ind] = pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i+1];
|
||||||
ind++;
|
ind++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fl_set_xyplot_data(form->pusch_comp,I,Q,ind,"","","");
|
fl_set_xyplot_data(form->pusch_comp,I,Q,ind,"","","");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
// global var to enable openair performance profiler
|
// global var to enable openair performance profiler
|
||||||
extern int opp_enabled;
|
extern int opp_enabled;
|
||||||
double cpu_freq_GHz;
|
double cpu_freq_GHz __attribute__ ((aligned(32)));;
|
||||||
|
|
||||||
#if defined(__x86_64__) || defined(__i386__)
|
#if defined(__x86_64__) || defined(__i386__)
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
#include "openairinterface5g_limits.h"
|
#include "openairinterface5g_limits.h"
|
||||||
#include "PHY/TOOLS/time_meas.h"
|
#include "PHY/TOOLS/time_meas.h"
|
||||||
#include "defs_common.h"
|
#include "defs_common.h"
|
||||||
|
#include <openair2/PHY_INTERFACE/IF_Module.h>
|
||||||
|
|
||||||
|
|
||||||
#define MAX_BANDS_PER_RRU 4
|
#define MAX_BANDS_PER_RRU 4
|
||||||
|
|||||||
+55
-34
@@ -201,41 +201,11 @@ typedef struct {
|
|||||||
int repetition_number[4];
|
int repetition_number[4];
|
||||||
} LTE_eNB_PRACH;
|
} LTE_eNB_PRACH;
|
||||||
|
|
||||||
/// Context data structure for RX/TX portion of subframe processing
|
#include "PHY/TOOLS/time_meas.h"
|
||||||
typedef struct {
|
#include "PHY/CODING/coding_defs.h"
|
||||||
/// Component Carrier index
|
#include "PHY/TOOLS/tools_defs.h"
|
||||||
uint8_t CC_id;
|
#include "PHY/LTE_TRANSPORT/transport_eNB.h"
|
||||||
/// timestamp transmitted to HW
|
|
||||||
openair0_timestamp timestamp_tx;
|
|
||||||
/// subframe to act upon for transmission
|
|
||||||
int subframe_tx;
|
|
||||||
/// subframe to act upon for reception
|
|
||||||
int subframe_rx;
|
|
||||||
/// frame to act upon for transmission
|
|
||||||
int frame_tx;
|
|
||||||
/// frame to act upon for reception
|
|
||||||
int frame_rx;
|
|
||||||
/// \brief Instance count for RXn-TXnp4 processing thread.
|
|
||||||
/// \internal This variable is protected by \ref mutex_rxtx.
|
|
||||||
int instance_cnt;
|
|
||||||
/// pthread structure for RXn-TXnp4 processing thread
|
|
||||||
pthread_t pthread;
|
|
||||||
/// pthread attributes for RXn-TXnp4 processing thread
|
|
||||||
pthread_attr_t attr;
|
|
||||||
/// condition variable for tx processing thread
|
|
||||||
pthread_cond_t cond;
|
|
||||||
/// mutex for RXn-TXnp4 processing thread
|
|
||||||
pthread_mutex_t mutex;
|
|
||||||
/// scheduling parameters for RXn-TXnp4 thread
|
|
||||||
struct sched_param sched_param_rxtx;
|
|
||||||
|
|
||||||
/// \internal This variable is protected by \ref mutex_RUs.
|
|
||||||
int instance_cnt_RUs;
|
|
||||||
/// condition variable for tx processing thread
|
|
||||||
pthread_cond_t cond_RUs;
|
|
||||||
/// mutex for RXn-TXnp4 processing thread
|
|
||||||
pthread_mutex_t mutex_RUs;
|
|
||||||
} L1_rxtx_proc_t;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct PHY_VARS_eNB_s *eNB;
|
struct PHY_VARS_eNB_s *eNB;
|
||||||
@@ -694,6 +664,57 @@ typedef struct PHY_VARS_eNB_s {
|
|||||||
int32_t pusch_stats_mcs[NUMBER_OF_UE_MAX][10240];
|
int32_t pusch_stats_mcs[NUMBER_OF_UE_MAX][10240];
|
||||||
int32_t pusch_stats_bsr[NUMBER_OF_UE_MAX][10240];
|
int32_t pusch_stats_bsr[NUMBER_OF_UE_MAX][10240];
|
||||||
int32_t pusch_stats_BO[NUMBER_OF_UE_MAX][10240];
|
int32_t pusch_stats_BO[NUMBER_OF_UE_MAX][10240];
|
||||||
|
uint8_t *FS6bufferZone;
|
||||||
} PHY_VARS_eNB;
|
} PHY_VARS_eNB;
|
||||||
|
|
||||||
|
|
||||||
|
struct turboReqId {
|
||||||
|
uint16_t rnti;
|
||||||
|
uint16_t frame;
|
||||||
|
uint8_t subframe;
|
||||||
|
uint8_t codeblock;
|
||||||
|
uint16_t spare;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
union turboReqUnion {
|
||||||
|
struct turboReqId s;
|
||||||
|
uint64_t p;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct TurboDecode_s {
|
||||||
|
PHY_VARS_eNB *eNB;
|
||||||
|
decoder_if_t *function;
|
||||||
|
uint8_t decoded_bytes[3+1768] __attribute__((aligned(32)));
|
||||||
|
int UEid;
|
||||||
|
int harq_pid;
|
||||||
|
int frame;
|
||||||
|
int subframe;
|
||||||
|
int Fbits;
|
||||||
|
int Kr;
|
||||||
|
LTE_UL_eNB_HARQ_t *ulsch_harq;
|
||||||
|
int nbSegments;
|
||||||
|
int segment_r;
|
||||||
|
int r_offset;
|
||||||
|
int offset;
|
||||||
|
int maxIterations;
|
||||||
|
int decodeIterations;
|
||||||
|
} turboDecode_t;
|
||||||
|
|
||||||
|
#define TURBO_SIMD_SOFTBITS 96+12+3+3*6144
|
||||||
|
typedef struct turboEncode_s {
|
||||||
|
uint8_t * input;
|
||||||
|
int Kr_bytes;
|
||||||
|
int filler;
|
||||||
|
unsigned int G;
|
||||||
|
int r;
|
||||||
|
int harq_pid;
|
||||||
|
int round;
|
||||||
|
int r_offset;
|
||||||
|
LTE_eNB_DLSCH_t *dlsch;
|
||||||
|
time_stats_t *rm_stats;
|
||||||
|
time_stats_t *te_stats;
|
||||||
|
time_stats_t *i_stats;
|
||||||
|
} turboEncode_t;
|
||||||
|
|
||||||
|
|
||||||
#endif /* __PHY_DEFS_ENB__H__ */
|
#endif /* __PHY_DEFS_ENB__H__ */
|
||||||
|
|||||||
@@ -745,9 +745,8 @@ void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void schedule_response(Sched_Rsp_t *Sched_INFO) {
|
void schedule_response(Sched_Rsp_t *Sched_INFO, L1_rxtx_proc_t *proc) {
|
||||||
PHY_VARS_eNB *eNB;
|
PHY_VARS_eNB *eNB;
|
||||||
L1_rxtx_proc_t *proc;
|
|
||||||
// copy data from L2 interface into L1 structures
|
// copy data from L2 interface into L1 structures
|
||||||
module_id_t Mod_id = Sched_INFO->module_id;
|
module_id_t Mod_id = Sched_INFO->module_id;
|
||||||
uint8_t CC_id = Sched_INFO->CC_id;
|
uint8_t CC_id = Sched_INFO->CC_id;
|
||||||
@@ -767,7 +766,6 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
|
|||||||
AssertFatal(RC.eNB[Mod_id][CC_id]!=NULL,"RC.eNB[%d][%d] is null\n",Mod_id,CC_id);
|
AssertFatal(RC.eNB[Mod_id][CC_id]!=NULL,"RC.eNB[%d][%d] is null\n",Mod_id,CC_id);
|
||||||
eNB = RC.eNB[Mod_id][CC_id];
|
eNB = RC.eNB[Mod_id][CC_id];
|
||||||
fp = &eNB->frame_parms;
|
fp = &eNB->frame_parms;
|
||||||
proc = &eNB->proc.L1_proc;
|
|
||||||
/* TODO: check that following line is correct - in the meantime it is disabled */
|
/* TODO: check that following line is correct - in the meantime it is disabled */
|
||||||
//if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)==SF_UL)) return;
|
//if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)==SF_UL)) return;
|
||||||
ul_subframe = pdcch_alloc2ul_subframe(fp,subframe);
|
ul_subframe = pdcch_alloc2ul_subframe(fp,subframe);
|
||||||
@@ -1020,11 +1018,11 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
|
|||||||
|
|
||||||
/*Dummy functions*/
|
/*Dummy functions*/
|
||||||
|
|
||||||
int memcpy_dl_config_req (nfapi_pnf_p7_config_t *pnf_p7, nfapi_dl_config_request_t *req) {
|
int memcpy_dl_config_req (L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_dl_config_request_t *req) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int memcpy_ul_config_req (nfapi_pnf_p7_config_t *pnf_p7, nfapi_ul_config_request_t *req) {
|
int memcpy_ul_config_req (L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_ul_config_request_t *req) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,10 +37,10 @@
|
|||||||
#include "SCHED/sched_common.h"
|
#include "SCHED/sched_common.h"
|
||||||
#include "nfapi_interface.h"
|
#include "nfapi_interface.h"
|
||||||
|
|
||||||
void fill_uci_harq_indication(PHY_VARS_eNB *eNB,LTE_eNB_UCI *uci,int frame,int subframe,uint8_t *harq_ack,uint8_t tdd_mapping_mode,uint16_t tdd_multiplexing_mask);
|
void fill_uci_harq_indication(int UEid, PHY_VARS_eNB *eNB,LTE_eNB_UCI *uci,int frame,int subframe,uint8_t *harq_ack,uint8_t tdd_mapping_mode,uint16_t tdd_multiplexing_mask);
|
||||||
void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq,uint16_t rnti, int frame,int subframe,int bundling);
|
void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq,uint16_t rnti, int frame,int subframe,int bundling);
|
||||||
void fill_ulsch_cqi_indication(PHY_VARS_eNB *eNB,uint16_t frame,uint8_t subframe,LTE_UL_eNB_HARQ_t *ulsch_harq,uint16_t rnti);
|
void fill_ulsch_cqi_indication(PHY_VARS_eNB *eNB,uint16_t frame,uint8_t subframe,LTE_UL_eNB_HARQ_t *ulsch_harq,uint16_t rnti);
|
||||||
void fill_sr_indication(PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe,uint32_t stat);
|
void fill_sr_indication(int UEid, PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe,uint32_t stat);
|
||||||
void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe);
|
void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe);
|
||||||
void fill_crc_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe,uint8_t crc_flag);
|
void fill_crc_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe,uint8_t crc_flag);
|
||||||
void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc,nfapi_dl_config_request_pdu_t *dl_config_pdu);
|
void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc,nfapi_dl_config_request_pdu_t *dl_config_pdu);
|
||||||
@@ -81,4 +81,4 @@ void handle_uci_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu
|
|||||||
|
|
||||||
void handle_srs_pdu(PHY_VARS_eNB *eNB,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe);
|
void handle_srs_pdu(PHY_VARS_eNB *eNB,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe);
|
||||||
|
|
||||||
void schedule_response(Sched_Rsp_t *Sched_INFO);
|
void schedule_response(Sched_Rsp_t *Sched_INFO, L1_rxtx_proc_t *proc);
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "intertask_interface.h"
|
#include "intertask_interface.h"
|
||||||
|
#include <executables/split_headers.h>
|
||||||
|
|
||||||
#define MBMS_NFAPI_SCHEDULER
|
#define MBMS_NFAPI_SCHEDULER
|
||||||
|
|
||||||
@@ -303,6 +304,7 @@ bool dlsch_procedures(PHY_VARS_eNB *eNB,
|
|||||||
|
|
||||||
start_meas(&eNB->dlsch_encoding_stats);
|
start_meas(&eNB->dlsch_encoding_stats);
|
||||||
dlsch_encoding_all(eNB,
|
dlsch_encoding_all(eNB,
|
||||||
|
proc,
|
||||||
dlsch_harq->pdu,
|
dlsch_harq->pdu,
|
||||||
dlsch_harq->pdsch_start,
|
dlsch_harq->pdsch_start,
|
||||||
dlsch,
|
dlsch,
|
||||||
@@ -317,6 +319,14 @@ bool dlsch_procedures(PHY_VARS_eNB *eNB,
|
|||||||
&eNB->dlsch_interleaving_stats);
|
&eNB->dlsch_interleaving_stats);
|
||||||
stop_meas(&eNB->dlsch_encoding_stats);
|
stop_meas(&eNB->dlsch_encoding_stats);
|
||||||
|
|
||||||
|
if ( proc->threadPool->activated ) {
|
||||||
|
// Wait all other threads finish to process
|
||||||
|
while (proc->nbEncode) {
|
||||||
|
delNotifiedFIFO_elt(pullTpool(proc->respEncode, proc->threadPool));
|
||||||
|
proc->nbEncode--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(eNB->dlsch_encoding_stats.p_time>500*3000 && opp_enabled == 1) {
|
if(eNB->dlsch_encoding_stats.p_time>500*3000 && opp_enabled == 1) {
|
||||||
print_meas_now(&eNB->dlsch_encoding_stats,"total coding",stderr);
|
print_meas_now(&eNB->dlsch_encoding_stats,"total coding",stderr);
|
||||||
}
|
}
|
||||||
@@ -431,6 +441,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
|
|||||||
if (ul_subframe < 10) { // This means that there is a potential UL subframe that will be scheduled here
|
if (ul_subframe < 10) { // This means that there is a potential UL subframe that will be scheduled here
|
||||||
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
|
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
|
||||||
if (eNB->ulsch[i] && eNB->ulsch[i]->ue_type >0) harq_pid = 0;
|
if (eNB->ulsch[i] && eNB->ulsch[i]->ue_type >0) harq_pid = 0;
|
||||||
|
|
||||||
else
|
else
|
||||||
harq_pid = subframe2harq_pid(fp,ul_frame,ul_subframe);
|
harq_pid = subframe2harq_pid(fp,ul_frame,ul_subframe);
|
||||||
|
|
||||||
@@ -591,7 +602,12 @@ void srs_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fill_sr_indication(PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe,uint32_t stat) {
|
void fill_sr_indication(int UEid, PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe,uint32_t stat) {
|
||||||
|
if ( split73 == SPLIT73_DU ) {
|
||||||
|
sendFs6Ulharq(fs6ULindicationSr, UEid, eNB, NULL, frame, subframe, NULL,0,0, rnti, stat);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&eNB->UL_INFO_mutex);
|
pthread_mutex_lock(&eNB->UL_INFO_mutex);
|
||||||
nfapi_sr_indication_t *sr_ind = &eNB->UL_INFO.sr_ind;
|
nfapi_sr_indication_t *sr_ind = &eNB->UL_INFO.sr_ind;
|
||||||
nfapi_sr_indication_body_t *sr_ind_body = &sr_ind->sr_indication_body;
|
nfapi_sr_indication_body_t *sr_ind_body = &sr_ind->sr_indication_body;
|
||||||
@@ -604,6 +620,7 @@ void fill_sr_indication(PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe,u
|
|||||||
pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG;
|
pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG;
|
||||||
pdu->rx_ue_information.rnti = rnti;
|
pdu->rx_ue_information.rnti = rnti;
|
||||||
int SNRtimes10 = dB_fixed_times10(stat) - 10 * eNB->measurements.n0_subband_power_dB[0][0];
|
int SNRtimes10 = dB_fixed_times10(stat) - 10 * eNB->measurements.n0_subband_power_dB[0][0];
|
||||||
|
LOG_D(PHY,"stat %d subbandpower %d, SNRtimes10 %d\n", stat, eNB->measurements.n0_subband_power_dB[0][0], SNRtimes10);
|
||||||
pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG;
|
pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG;
|
||||||
|
|
||||||
if (SNRtimes10 < -640) pdu->ul_cqi_information.ul_cqi=0;
|
if (SNRtimes10 < -640) pdu->ul_cqi_information.ul_cqi=0;
|
||||||
@@ -714,7 +731,7 @@ uci_procedures(PHY_VARS_eNB *eNB,
|
|||||||
|
|
||||||
if (uci->type == SR) {
|
if (uci->type == SR) {
|
||||||
if (SR_payload == 1) {
|
if (SR_payload == 1) {
|
||||||
fill_sr_indication(eNB,uci->rnti,frame,subframe,metric_SR);
|
fill_sr_indication(i, eNB,uci->rnti,frame,subframe,metric_SR);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
@@ -748,7 +765,7 @@ uci_procedures(PHY_VARS_eNB *eNB,
|
|||||||
|
|
||||||
/* cancel SR detection if reception on n1_pucch0 is better than on SR PUCCH resource index, otherwise send it up to MAC */
|
/* cancel SR detection if reception on n1_pucch0 is better than on SR PUCCH resource index, otherwise send it up to MAC */
|
||||||
if (uci->type==HARQ_SR && metric[0] > metric_SR) SR_payload = 0;
|
if (uci->type==HARQ_SR && metric[0] > metric_SR) SR_payload = 0;
|
||||||
else if (SR_payload == 1) fill_sr_indication(eNB,uci->rnti,frame,subframe,metric_SR);
|
else if (SR_payload == 1) fill_sr_indication(i, eNB,uci->rnti,frame,subframe,metric_SR);
|
||||||
|
|
||||||
if (uci->type==HARQ_SR && metric[0] <= metric_SR) {
|
if (uci->type==HARQ_SR && metric[0] <= metric_SR) {
|
||||||
/* when transmitting ACK/NACK on SR PUCCH resource index, SR payload is always 1 */
|
/* when transmitting ACK/NACK on SR PUCCH resource index, SR payload is always 1 */
|
||||||
@@ -773,7 +790,7 @@ uci_procedures(PHY_VARS_eNB *eNB,
|
|||||||
frame,subframe,
|
frame,subframe,
|
||||||
pucch_b0b1[0][0],metric[0]);
|
pucch_b0b1[0][0],metric[0]);
|
||||||
uci->stat = metric[0];
|
uci->stat = metric[0];
|
||||||
fill_uci_harq_indication(eNB,uci,frame,subframe,pucch_b0b1[0],0,0xffff);
|
fill_uci_harq_indication(i, eNB,uci,frame,subframe,pucch_b0b1[0],0,0xffff);
|
||||||
} else { // frame_type == TDD
|
} else { // frame_type == TDD
|
||||||
LOG_D(PHY,"Frame %d Subframe %d Demodulating PUCCH (UCI %d) for ACK/NAK (uci->pucch_fmt %d,uci->type %d.uci->frame %d, uci->subframe %d): n1_pucch0 %d SR_payload %d\n",
|
LOG_D(PHY,"Frame %d Subframe %d Demodulating PUCCH (UCI %d) for ACK/NAK (uci->pucch_fmt %d,uci->type %d.uci->frame %d, uci->subframe %d): n1_pucch0 %d SR_payload %d\n",
|
||||||
frame,subframe,i,
|
frame,subframe,i,
|
||||||
@@ -795,7 +812,7 @@ uci_procedures(PHY_VARS_eNB *eNB,
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (uci->type==HARQ_SR && metric[0] > metric_SR) SR_payload = 0;
|
if (uci->type==HARQ_SR && metric[0] > metric_SR) SR_payload = 0;
|
||||||
else if (SR_payload == 1) fill_sr_indication(eNB,uci->rnti,frame,subframe,metric_SR);
|
else if (SR_payload == 1) fill_sr_indication(i, eNB,uci->rnti,frame,subframe,metric_SR);
|
||||||
|
|
||||||
if (uci->type==HARQ_SR && metric[0] <= metric_SR) {
|
if (uci->type==HARQ_SR && metric[0] <= metric_SR) {
|
||||||
SR_payload = 1;
|
SR_payload = 1;
|
||||||
@@ -877,7 +894,7 @@ uci_procedures(PHY_VARS_eNB *eNB,
|
|||||||
}
|
}
|
||||||
|
|
||||||
uci->stat = metric[0];
|
uci->stat = metric[0];
|
||||||
fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,2,0xffff); // special_bundling mode
|
fill_uci_harq_indication(i, eNB,uci,frame,subframe,harq_ack,2,0xffff); // special_bundling mode
|
||||||
} else if ((uci->tdd_bundling == 0) && (uci->num_pucch_resources==2)) { // multiplexing + no SR, implement Table 10.1.3-5 (Rel14) for multiplexing with M=2
|
} else if ((uci->tdd_bundling == 0) && (uci->num_pucch_resources==2)) { // multiplexing + no SR, implement Table 10.1.3-5 (Rel14) for multiplexing with M=2
|
||||||
if (pucch_b0b1[0][0] == 4 ||
|
if (pucch_b0b1[0][0] == 4 ||
|
||||||
pucch_b0b1[1][0] == 4) { // there isn't a likely transmission
|
pucch_b0b1[1][0] == 4) { // there isn't a likely transmission
|
||||||
@@ -913,7 +930,7 @@ uci_procedures(PHY_VARS_eNB *eNB,
|
|||||||
}
|
}
|
||||||
|
|
||||||
uci->stat = max(metric[0],metric[1]);
|
uci->stat = max(metric[0],metric[1]);
|
||||||
fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode
|
fill_uci_harq_indication(i, eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode
|
||||||
} //else if ((uci->tdd_bundling == 0) && (res==2))
|
} //else if ((uci->tdd_bundling == 0) && (res==2))
|
||||||
else if ((uci->tdd_bundling == 0) && (uci->num_pucch_resources==3)) { // multiplexing + no SR, implement Table 10.1.3-6 (Rel14) for multiplexing with M=3
|
else if ((uci->tdd_bundling == 0) && (uci->num_pucch_resources==3)) { // multiplexing + no SR, implement Table 10.1.3-6 (Rel14) for multiplexing with M=3
|
||||||
if (harq_ack[0] == 4 ||
|
if (harq_ack[0] == 4 ||
|
||||||
@@ -984,7 +1001,7 @@ uci_procedures(PHY_VARS_eNB *eNB,
|
|||||||
}
|
}
|
||||||
|
|
||||||
uci->stat = max_metric;
|
uci->stat = max_metric;
|
||||||
fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode
|
fill_uci_harq_indication(i, eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode
|
||||||
}
|
}
|
||||||
} //else if ((uci->tdd_bundling == 0) && (res==3))
|
} //else if ((uci->tdd_bundling == 0) && (res==3))
|
||||||
else if ((uci->tdd_bundling == 0) && (uci->num_pucch_resources==4)) { // multiplexing + no SR, implement Table 10.1.3-7 (Rel14) for multiplexing with M=4
|
else if ((uci->tdd_bundling == 0) && (uci->num_pucch_resources==4)) { // multiplexing + no SR, implement Table 10.1.3-7 (Rel14) for multiplexing with M=4
|
||||||
@@ -1106,14 +1123,14 @@ uci_procedures(PHY_VARS_eNB *eNB,
|
|||||||
}
|
}
|
||||||
|
|
||||||
uci->stat = max_metric;
|
uci->stat = max_metric;
|
||||||
fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode
|
fill_uci_harq_indication(i, eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode
|
||||||
} // else if ((uci->tdd_bundling == 0) && (res==4))
|
} // else if ((uci->tdd_bundling == 0) && (res==4))
|
||||||
else { // bundling
|
else { // bundling
|
||||||
harq_ack[0] = pucch_b0b1[0][0];
|
harq_ack[0] = pucch_b0b1[0][0];
|
||||||
harq_ack[1] = pucch_b0b1[0][1];
|
harq_ack[1] = pucch_b0b1[0][1];
|
||||||
uci->stat = metric[0];
|
uci->stat = metric[0];
|
||||||
LOG_D(PHY,"bundling: (%d,%d), metric %d\n",harq_ack[0],harq_ack[1],uci->stat);
|
LOG_D(PHY,"bundling: (%d,%d), metric %d\n",harq_ack[0],harq_ack[1],uci->stat);
|
||||||
fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,0,0xffff); // special_bundling mode
|
fill_uci_harq_indication(i, eNB,uci,frame,subframe,harq_ack,0,0xffff); // special_bundling mode
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_PHY_PROC
|
#ifdef DEBUG_PHY_PROC
|
||||||
@@ -1144,8 +1161,93 @@ uci_procedures(PHY_VARS_eNB *eNB,
|
|||||||
} // end loop for (int i = 0; i < NUMBER_OF_UE_MAX; i++) {
|
} // end loop for (int i = 0; i < NUMBER_OF_UE_MAX; i++) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void postDecode(L1_rxtx_proc_t *proc, notifiedFIFO_elt_t *req) {
|
||||||
|
turboDecode_t * rdata=(turboDecode_t *) NotifiedFifoData(req);
|
||||||
|
|
||||||
|
LTE_eNB_ULSCH_t *ulsch = rdata->eNB->ulsch[rdata->UEid];
|
||||||
|
LTE_UL_eNB_HARQ_t *ulsch_harq = rdata->ulsch_harq;
|
||||||
|
PHY_VARS_eNB *eNB=rdata->eNB;
|
||||||
|
|
||||||
|
bool decodeSucess=rdata->decodeIterations <= rdata->maxIterations;
|
||||||
|
ulsch_harq->processedSegments++;
|
||||||
|
LOG_D(PHY, "processing result of segment: %d, ue %d, processed %d/%d\n",
|
||||||
|
rdata->segment_r, rdata->UEid, ulsch_harq->processedSegments, rdata->nbSegments);
|
||||||
|
proc->nbDecode--;
|
||||||
|
LOG_D(PHY,"remain to decoded in subframe: %d\n", proc->nbDecode);
|
||||||
|
if (decodeSucess) {
|
||||||
|
int Fbytes=(rdata->segment_r==0) ? rdata->Fbits>>3 : 0;
|
||||||
|
int sz=(rdata->Kr>>3) - Fbytes - ((ulsch_harq->C>1)?3:0);
|
||||||
|
memcpy(ulsch_harq->decodedBytes+rdata->offset,
|
||||||
|
rdata->decoded_bytes+Fbytes,
|
||||||
|
sz);
|
||||||
|
} else {
|
||||||
|
if ( rdata->nbSegments != ulsch_harq->processedSegments ) {
|
||||||
|
int nb=abortTpool(proc->threadPool, req->key);
|
||||||
|
nb+=abortNotifiedFIFO(proc->respDecode, req->key);
|
||||||
|
proc->nbDecode-=nb;
|
||||||
|
LOG_I(PHY,"uplink segment error %d/%d, aborted %d segments\n",rdata->segment_r,rdata->nbSegments, nb);
|
||||||
|
AssertFatal(ulsch_harq->processedSegments+nb == rdata->nbSegments,"processed: %d, aborted: %d, total %d\n",
|
||||||
|
ulsch_harq->processedSegments, nb, rdata->nbSegments);
|
||||||
|
ulsch_harq->processedSegments=rdata->nbSegments;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if this UE segments are all done
|
||||||
|
if ( rdata->nbSegments == ulsch_harq->processedSegments) {
|
||||||
|
//compute the expected ULSCH RX power (for the stats)
|
||||||
|
int i=rdata->UEid;
|
||||||
|
ulsch_harq->delta_TF = get_hundred_times_delta_IF_eNB(eNB,i,rdata->harq_pid, 0); // 0 means bw_factor is not considered
|
||||||
|
if (RC.mac != NULL) { /* ulsim does not use RC.mac context. */
|
||||||
|
if (ulsch_harq->cqi_crc_status == 1) {
|
||||||
|
fill_ulsch_cqi_indication(eNB,rdata->frame,rdata->subframe,ulsch_harq,ulsch->rnti);
|
||||||
|
RC.mac[eNB->Mod_id]->UE_info.UE_sched_ctrl[i].cqi_req_flag &= (~(1 << rdata->subframe));
|
||||||
|
} else {
|
||||||
|
if(RC.mac[eNB->Mod_id]->UE_info.UE_sched_ctrl[i].cqi_req_flag & (1 << rdata->subframe) ) {
|
||||||
|
RC.mac[eNB->Mod_id]->UE_info.UE_sched_ctrl[i].cqi_req_flag &= (~(1 << rdata->subframe));
|
||||||
|
RC.mac[eNB->Mod_id]->UE_info.UE_sched_ctrl[i].cqi_req_timer=30;
|
||||||
|
LOG_D(PHY,"Frame %d,Subframe %d, We're supposed to get a cqi here. Set cqi_req_timer to 30.\n",rdata->frame,rdata->subframe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!decodeSucess) {
|
||||||
|
fill_crc_indication(eNB,i,rdata->frame,rdata->subframe,1); // indicate NAK to MAC
|
||||||
|
fill_rx_indication(eNB,i,rdata->frame,rdata->subframe); // indicate SDU to MAC
|
||||||
|
LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d Error receiving ULSCH, round %d/%d (ACK %d,%d)\n",
|
||||||
|
eNB->Mod_id,rdata->harq_pid,
|
||||||
|
rdata->frame,rdata->subframe, i,
|
||||||
|
ulsch_harq->round,
|
||||||
|
ulsch->Mlimit,
|
||||||
|
ulsch_harq->o_ACK[0],
|
||||||
|
ulsch_harq->o_ACK[1]);
|
||||||
|
|
||||||
|
if (ulsch_harq->round >= 3) {
|
||||||
|
ulsch_harq->status = SCH_IDLE;
|
||||||
|
ulsch_harq->handled = 0;
|
||||||
|
ulsch->harq_mask &= ~(1 << rdata->harq_pid);
|
||||||
|
ulsch_harq->round = 0;
|
||||||
|
}
|
||||||
|
/* Mark the HARQ process to release it later if max transmission reached
|
||||||
|
* (see below).
|
||||||
|
* MAC does not send the max transmission count, we have to deal with it
|
||||||
|
* locally in PHY.
|
||||||
|
*/
|
||||||
|
ulsch_harq->handled = 1;
|
||||||
|
} // ulsch in error
|
||||||
|
else if(ulsch_harq->repetition_number == ulsch_harq->total_number_of_repetitions){
|
||||||
|
fill_crc_indication(eNB,i,rdata->frame,rdata->subframe,0); // indicate ACK to MAC
|
||||||
|
fill_rx_indication(eNB,i,rdata->frame,rdata->subframe); // indicate SDU to MAC
|
||||||
|
ulsch_harq->status = SCH_IDLE;
|
||||||
|
ulsch->harq_mask &= ~(1 << rdata->harq_pid);
|
||||||
|
} // ulsch not in error
|
||||||
|
|
||||||
|
if (ulsch_harq->O_ACK>0)
|
||||||
|
fill_ulsch_harq_indication(eNB,ulsch_harq,ulsch->rnti,rdata->frame,rdata->subframe,ulsch->bundling);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
|
void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
|
||||||
uint32_t ret=0,i;
|
uint32_t i;
|
||||||
uint32_t harq_pid;
|
uint32_t harq_pid;
|
||||||
uint8_t nPRS;
|
uint8_t nPRS;
|
||||||
LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
|
LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
|
||||||
@@ -1154,7 +1256,6 @@ 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];
|
||||||
@@ -1208,127 +1309,13 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
|
|||||||
rx_ulsch(eNB,proc, i);
|
rx_ulsch(eNB,proc, i);
|
||||||
stop_meas(&eNB->ulsch_demodulation_stats);
|
stop_meas(&eNB->ulsch_demodulation_stats);
|
||||||
start_meas(&eNB->ulsch_decoding_stats);
|
start_meas(&eNB->ulsch_decoding_stats);
|
||||||
ret = ulsch_decoding(eNB,proc,
|
ulsch_decoding(eNB,proc,
|
||||||
i,
|
i,
|
||||||
0, // control_only_flag
|
0, // control_only_flag
|
||||||
ulsch_harq->V_UL_DAI,
|
ulsch_harq->V_UL_DAI,
|
||||||
ulsch_harq->nb_rb>20 ? 1 : 0);
|
ulsch_harq->nb_rb>20 ? 1 : 0);
|
||||||
stop_meas(&eNB->ulsch_decoding_stats);
|
stop_meas(&eNB->ulsch_decoding_stats);
|
||||||
LOG_D(PHY,
|
|
||||||
"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d ulsch_harq->cqi_crc_status:%d ackBits:%d ulsch_decoding_stats[t:%lld max:%lld]\n",
|
|
||||||
eNB->Mod_id,harq_pid,
|
|
||||||
frame,subframe,
|
|
||||||
ulsch->rnti,
|
|
||||||
dB_fixed(eNB->pusch_vars[i]->ulsch_power[0]),
|
|
||||||
dB_fixed(eNB->pusch_vars[i]->ulsch_power[1]),
|
|
||||||
30,//eNB->measurements.n0_power_dB[0],
|
|
||||||
30,//eNB->measurements.n0_power_dB[1],
|
|
||||||
ulsch_harq->o_ACK[0],
|
|
||||||
ulsch_harq->o_ACK[1],
|
|
||||||
ret,
|
|
||||||
ulsch_harq->cqi_crc_status,
|
|
||||||
ulsch_harq->O_ACK,
|
|
||||||
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)
|
|
||||||
ulsch_harq->delta_TF = get_hundred_times_delta_IF_eNB(eNB,i,harq_pid, 0); // 0 means bw_factor is not considered
|
|
||||||
|
|
||||||
if (RC.mac != NULL) { /* ulsim does not use RC.mac context. */
|
|
||||||
if (ulsch_harq->cqi_crc_status == 1) {
|
|
||||||
#ifdef DEBUG_PHY_PROC
|
|
||||||
//if (((frame%10) == 0) || (frame < 50))
|
|
||||||
print_CQI(ulsch_harq->o,ulsch_harq->uci_format,0,fp->N_RB_DL);
|
|
||||||
#endif
|
|
||||||
fill_ulsch_cqi_indication(eNB,frame,subframe,ulsch_harq,ulsch->rnti);
|
|
||||||
RC.mac[eNB->Mod_id]->UE_info.UE_sched_ctrl[i].cqi_req_flag &= (~(1 << subframe));
|
|
||||||
} else {
|
|
||||||
if(RC.mac[eNB->Mod_id]->UE_info.UE_sched_ctrl[i].cqi_req_flag & (1 << subframe) ) {
|
|
||||||
RC.mac[eNB->Mod_id]->UE_info.UE_sched_ctrl[i].cqi_req_flag &= (~(1 << subframe));
|
|
||||||
RC.mac[eNB->Mod_id]->UE_info.UE_sched_ctrl[i].cqi_req_timer=30;
|
|
||||||
LOG_D(PHY,"Frame %d,Subframe %d, We're supposed to get a cqi here. Set cqi_req_timer to 30.\n",frame,subframe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == (1+MAX_TURBO_ITERATIONS)) {
|
|
||||||
T(T_ENB_PHY_ULSCH_UE_NACK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(ulsch->rnti),
|
|
||||||
T_INT(harq_pid));
|
|
||||||
fill_crc_indication(eNB,i,frame,subframe,1); // indicate NAK to MAC
|
|
||||||
fill_rx_indication(eNB,i,frame,subframe); // indicate SDU to MAC
|
|
||||||
LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d Error receiving ULSCH, round %d/%d (ACK %d,%d)\n",
|
|
||||||
eNB->Mod_id,harq_pid,
|
|
||||||
frame,subframe, i,
|
|
||||||
ulsch_harq->round,
|
|
||||||
ulsch->Mlimit,
|
|
||||||
ulsch_harq->o_ACK[0],
|
|
||||||
ulsch_harq->o_ACK[1]);
|
|
||||||
|
|
||||||
if (ulsch_harq->round >= 3) {
|
|
||||||
ulsch_harq->status = SCH_IDLE;
|
|
||||||
ulsch_harq->handled = 0;
|
|
||||||
ulsch->harq_mask &= ~(1 << harq_pid);
|
|
||||||
ulsch_harq->round = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
MSC_LOG_RX_DISCARDED_MESSAGE(
|
|
||||||
MSC_PHY_ENB,MSC_PHY_UE,
|
|
||||||
NULL,0,
|
|
||||||
"%05u:%02u ULSCH received rnti %x harq id %u round %d",
|
|
||||||
frame,subframe,
|
|
||||||
ulsch->rnti,harq_pid,
|
|
||||||
ulsch_harq->round-1
|
|
||||||
);
|
|
||||||
/* Mark the HARQ process to release it later if max transmission reached
|
|
||||||
* (see below).
|
|
||||||
* MAC does not send the max transmission count, we have to deal with it
|
|
||||||
* locally in PHY.
|
|
||||||
*/
|
|
||||||
ulsch_harq->handled = 1;
|
|
||||||
} // ulsch in error
|
|
||||||
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_rx_indication(eNB,i,frame,subframe); // indicate SDU to MAC
|
|
||||||
ulsch_harq->status = SCH_IDLE;
|
|
||||||
ulsch->harq_mask &= ~(1 << harq_pid);
|
|
||||||
T (T_ENB_PHY_ULSCH_UE_ACK, T_INT (eNB->Mod_id), T_INT (frame), T_INT (subframe), T_INT (ulsch->rnti), T_INT (harq_pid));
|
|
||||||
MSC_LOG_RX_MESSAGE(
|
|
||||||
MSC_PHY_ENB,MSC_PHY_UE,
|
|
||||||
NULL,0,
|
|
||||||
"%05u:%02u ULSCH received rnti %x harq id %u",
|
|
||||||
frame,subframe,
|
|
||||||
ulsch->rnti,harq_pid
|
|
||||||
);
|
|
||||||
#ifdef DEBUG_PHY_PROC
|
|
||||||
#ifdef DEBUG_ULSCH
|
|
||||||
LOG_D(PHY,"[eNB] Frame %d, Subframe %d : ULSCH SDU (RX harq_pid %d) %d bytes:",frame,subframe,
|
|
||||||
harq_pid,ulsch_harq->TBS>>3);
|
|
||||||
|
|
||||||
for (j=0; j<ulsch_harq->TBS>>3; j++)
|
|
||||||
LOG_T(PHY,"%x.",ulsch->harq_processes[harq_pid]->b[j]);
|
|
||||||
|
|
||||||
LOG_T(PHY,"\n");
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
} // ulsch not in error
|
|
||||||
|
|
||||||
if (ulsch_harq->O_ACK>0) fill_ulsch_harq_indication(eNB,ulsch_harq,ulsch->rnti,frame,subframe,ulsch->bundling);
|
|
||||||
|
|
||||||
LOG_D(PHY,"[eNB %d] Frame %d subframe %d: received ULSCH harq_pid %d for UE %d, ret = %d, CQI CRC Status %d, ACK %d,%d, ulsch_errors %d/%d\n",
|
|
||||||
eNB->Mod_id,frame,subframe,
|
|
||||||
harq_pid,
|
|
||||||
i,
|
|
||||||
ret,
|
|
||||||
ulsch_harq->cqi_crc_status,
|
|
||||||
ulsch_harq->o_ACK[0],
|
|
||||||
ulsch_harq->o_ACK[1],
|
|
||||||
eNB->UE_stats[i].ulsch_errors[harq_pid],
|
|
||||||
eNB->UE_stats[i].ulsch_decoding_attempts[harq_pid][0]);
|
|
||||||
} // if ((ulsch) &&
|
|
||||||
// (ulsch->rnti>0) &&
|
|
||||||
// (ulsch_harq->status == ACTIVE))
|
|
||||||
else if ((ulsch) &&
|
else if ((ulsch) &&
|
||||||
(ulsch->rnti>0) &&
|
(ulsch->rnti>0) &&
|
||||||
(ulsch_harq->status == ACTIVE) &&
|
(ulsch_harq->status == ACTIVE) &&
|
||||||
@@ -1342,6 +1329,12 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
|
|||||||
LOG_W (PHY, "Removing stale ULSCH config for UE %x harq_pid %d (harq_mask is now 0x%2.2x)\n", ulsch->rnti, harq_pid, ulsch->harq_mask);
|
LOG_W (PHY, "Removing stale ULSCH config for UE %x harq_pid %d (harq_mask is now 0x%2.2x)\n", ulsch->rnti, harq_pid, ulsch->harq_mask);
|
||||||
}
|
}
|
||||||
} // for (i=0; i<NUMBER_OF_UE_MAX; i++)
|
} // for (i=0; i<NUMBER_OF_UE_MAX; i++)
|
||||||
|
|
||||||
|
while (proc->nbDecode > 0) {
|
||||||
|
notifiedFIFO_elt_t *req=pullTpool(proc->respDecode, proc->threadPool);
|
||||||
|
postDecode(proc, req);
|
||||||
|
delNotifiedFIFO_elt(req);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int oai_exit;
|
extern int oai_exit;
|
||||||
@@ -1349,24 +1342,29 @@ extern int oai_exit;
|
|||||||
extern void *td_thread (void *);
|
extern void *td_thread (void *);
|
||||||
|
|
||||||
void init_td_thread(PHY_VARS_eNB *eNB) {
|
void init_td_thread(PHY_VARS_eNB *eNB) {
|
||||||
|
/*
|
||||||
L1_proc_t *proc = &eNB->proc;
|
L1_proc_t *proc = &eNB->proc;
|
||||||
proc->tdp.eNB = eNB;
|
proc->tdp.eNB = eNB;
|
||||||
proc->instance_cnt_td = -1;
|
proc->instance_cnt_td = -1;
|
||||||
threadCreate(&proc->pthread_td, td_thread, (void *)&proc->tdp, "TD", -1, OAI_PRIORITY_RT);
|
threadCreate(&proc->pthread_td, td_thread, (void *)&proc->tdp, "TD", -1, OAI_PRIORITY_RT);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void kill_td_thread(PHY_VARS_eNB *eNB) {
|
void kill_td_thread(PHY_VARS_eNB *eNB) {
|
||||||
|
/*
|
||||||
L1_proc_t *proc = &eNB->proc;
|
L1_proc_t *proc = &eNB->proc;
|
||||||
proc->instance_cnt_td = 0;
|
proc->instance_cnt_td = 0;
|
||||||
pthread_cond_signal(&proc->cond_td);
|
pthread_cond_signal(&proc->cond_td);
|
||||||
pthread_join(proc->pthread_td, NULL);
|
pthread_join(proc->pthread_td, NULL);
|
||||||
pthread_mutex_destroy( &proc->mutex_td );
|
pthread_mutex_destroy( &proc->mutex_td );
|
||||||
pthread_cond_destroy( &proc->cond_td );
|
pthread_cond_destroy( &proc->cond_td );
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void *te_thread (void *);
|
extern void *te_thread (void *);
|
||||||
|
|
||||||
void init_te_thread(PHY_VARS_eNB *eNB) {
|
void init_te_thread(PHY_VARS_eNB *eNB) {
|
||||||
|
/*
|
||||||
L1_proc_t *proc = &eNB->proc;
|
L1_proc_t *proc = &eNB->proc;
|
||||||
|
|
||||||
for(int i=0; i<3 ; i++) {
|
for(int i=0; i<3 ; i++) {
|
||||||
@@ -1377,9 +1375,11 @@ void init_te_thread(PHY_VARS_eNB *eNB) {
|
|||||||
sprintf(txt,"TE_%d", i);
|
sprintf(txt,"TE_%d", i);
|
||||||
threadCreate(&proc->tep[i].pthread_te, te_thread, (void *)&proc->tep[i], txt, -1, OAI_PRIORITY_RT);
|
threadCreate(&proc->tep[i].pthread_te, te_thread, (void *)&proc->tep[i], txt, -1, OAI_PRIORITY_RT);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void kill_te_thread(PHY_VARS_eNB *eNB) {
|
void kill_te_thread(PHY_VARS_eNB *eNB) {
|
||||||
|
/*
|
||||||
L1_proc_t *proc = &eNB->proc;
|
L1_proc_t *proc = &eNB->proc;
|
||||||
|
|
||||||
for(int i=0; i<3 ; i++) {
|
for(int i=0; i<3 ; i++) {
|
||||||
@@ -1389,6 +1389,7 @@ void kill_te_thread(PHY_VARS_eNB *eNB) {
|
|||||||
pthread_mutex_destroy( &proc->tep[i].mutex_te);
|
pthread_mutex_destroy( &proc->tep[i].mutex_te);
|
||||||
pthread_cond_destroy( &proc->tep[i].cond_te);
|
pthread_cond_destroy( &proc->tep[i].cond_te);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void fill_rx_indication(PHY_VARS_eNB *eNB,
|
void fill_rx_indication(PHY_VARS_eNB *eNB,
|
||||||
@@ -1416,7 +1417,7 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,
|
|||||||
pdu->rx_indication_rel8.tl.tag = NFAPI_RX_INDICATION_REL8_TAG;
|
pdu->rx_indication_rel8.tl.tag = NFAPI_RX_INDICATION_REL8_TAG;
|
||||||
pdu->rx_indication_rel8.length = eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS>>3;
|
pdu->rx_indication_rel8.length = eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS>>3;
|
||||||
pdu->rx_indication_rel8.offset = 1; // DJP - I dont understand - but broken unless 1 ???? 0; // filled in at the end of the UL_INFO formation
|
pdu->rx_indication_rel8.offset = 1; // DJP - I dont understand - but broken unless 1 ???? 0; // filled in at the end of the UL_INFO formation
|
||||||
pdu->data = eNB->ulsch[UE_id]->harq_processes[harq_pid]->b;
|
pdu->data = eNB->ulsch[UE_id]->harq_processes[harq_pid]->decodedBytes;
|
||||||
// estimate timing advance for MAC
|
// estimate timing advance for MAC
|
||||||
sync_pos = lte_est_timing_advance_pusch(eNB,UE_id);
|
sync_pos = lte_est_timing_advance_pusch(eNB,UE_id);
|
||||||
timing_advance_update = sync_pos; // - eNB->frame_parms.nb_prefix_samples/4; //to check
|
timing_advance_update = sync_pos; // - eNB->frame_parms.nb_prefix_samples/4; //to check
|
||||||
@@ -1749,7 +1750,12 @@ void fill_ulsch_harq_indication (PHY_VARS_eNB *eNB, LTE_UL_eNB_HARQ_t *ulsch_har
|
|||||||
pthread_mutex_unlock(&eNB->UL_INFO_mutex);
|
pthread_mutex_unlock(&eNB->UL_INFO_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fill_uci_harq_indication (PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask) {
|
void fill_uci_harq_indication (int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask) {
|
||||||
|
if ( split73 == SPLIT73_DU ) {
|
||||||
|
sendFs6Ulharq(fs6ULindicationHarq, UEid, eNB, uci, frame, subframe, harq_ack, tdd_mapping_mode, tdd_multiplexing_mask, 0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int UE_id=find_dlsch(uci->rnti,eNB,SEARCH_EXIST);
|
int UE_id=find_dlsch(uci->rnti,eNB,SEARCH_EXIST);
|
||||||
|
|
||||||
//AssertFatal(UE_id>=0,"UE_id doesn't exist rnti:%x\n", uci->rnti);
|
//AssertFatal(UE_id>=0,"UE_id doesn't exist rnti:%x\n", uci->rnti);
|
||||||
|
|||||||
@@ -321,7 +321,7 @@ void feptx_ofdm(RU_t *ru,
|
|||||||
fp->nb_prefix_samples,
|
fp->nb_prefix_samples,
|
||||||
CYCLIC_PREFIX);
|
CYCLIC_PREFIX);
|
||||||
} else {
|
} else {
|
||||||
if(is_pmch_subframe(ru->proc.frame_tx,subframe,fp)/*subframe==1*/){
|
if(is_pmch_subframe(frame,subframe,fp)/*subframe==1*/){
|
||||||
normal_prefix_mod(&ru->common.txdataF_BF[aa][0],
|
normal_prefix_mod(&ru->common.txdataF_BF[aa][0],
|
||||||
dummy_tx_b,
|
dummy_tx_b,
|
||||||
2,
|
2,
|
||||||
@@ -426,7 +426,7 @@ void feptx_ofdm(RU_t *ru,
|
|||||||
|
|
||||||
stop_meas(&ru->ofdm_mod_stats);
|
stop_meas(&ru->ofdm_mod_stats);
|
||||||
LOG_D(PHY,"feptx_ofdm (TXPATH): frame %d, subframe %d: txp (time %p) %d dB, txp (freq) %d dB\n",
|
LOG_D(PHY,"feptx_ofdm (TXPATH): frame %d, subframe %d: txp (time %p) %d dB, txp (freq) %d dB\n",
|
||||||
ru->proc.frame_tx,subframe,txdata,dB_fixed(signal_energy((int32_t*)txdata,fp->samples_per_tti)),
|
frame,subframe,txdata,dB_fixed(signal_energy((int32_t*)txdata,fp->samples_per_tti)),
|
||||||
dB_fixed(signal_energy_nodc(ru->common.txdataF_BF[aa],2*slot_sizeF)));
|
dB_fixed(signal_energy_nodc(ru->common.txdataF_BF[aa],2*slot_sizeF)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -311,7 +311,7 @@ void get_cqipmiri_params(PHY_VARS_UE *ue,uint8_t eNB_id);
|
|||||||
|
|
||||||
int8_t get_PHR(uint8_t Mod_id, uint8_t CC_id, uint8_t eNB_index);
|
int8_t get_PHR(uint8_t Mod_id, uint8_t CC_id, uint8_t eNB_index);
|
||||||
|
|
||||||
void schedule_response(Sched_Rsp_t *Sched_INFO);
|
void schedule_response(Sched_Rsp_t *Sched_INFO, L1_rxtx_proc_t *proc);
|
||||||
|
|
||||||
LTE_eNB_UE_stats* get_UE_stats(uint8_t Mod_id, uint8_t CC_id,uint16_t rnti);
|
LTE_eNB_UE_stats* get_UE_stats(uint8_t Mod_id, uint8_t CC_id,uint16_t rnti);
|
||||||
|
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ int8_t find_ue_ulsch(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void schedule_response(Sched_Rsp_t *Sched_INFO);
|
void schedule_response(Sched_Rsp_t *Sched_INFO, L1_rxtx_proc_t *proc);
|
||||||
|
|
||||||
LTE_eNB_UE_stats *get_UE_stats(uint8_t Mod_id, uint8_t CC_id,uint16_t rnti);
|
LTE_eNB_UE_stats *get_UE_stats(uint8_t Mod_id, uint8_t CC_id,uint16_t rnti);
|
||||||
|
|
||||||
@@ -218,8 +218,6 @@ int is_srs_occasion_common(LTE_DL_FRAME_PARMS *frame_parms,int frame_tx,int subf
|
|||||||
void compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset);
|
void compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset);
|
||||||
|
|
||||||
void release_rnti_of_phy(module_id_t mod_id);
|
void release_rnti_of_phy(module_id_t mod_id);
|
||||||
|
|
||||||
void ru_fep_full_2thread(RU_t *ru, int subframe);
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ int set_tdd_config_nr( nfapi_nr_config_request_scf_t *cfg,
|
|||||||
|
|
||||||
void add_tdd_dedicated_configuration_nr(NR_DL_FRAME_PARMS *frame_parms, int slotIndex, int nrofDownlinkSymbols, int nrofUplinkSymbols) {
|
void add_tdd_dedicated_configuration_nr(NR_DL_FRAME_PARMS *frame_parms, int slotIndex, int nrofDownlinkSymbols, int nrofUplinkSymbols) {
|
||||||
TDD_UL_DL_SlotConfig_t *p_TDD_UL_DL_ConfigDedicated = frame_parms->p_TDD_UL_DL_ConfigDedicated;
|
TDD_UL_DL_SlotConfig_t *p_TDD_UL_DL_ConfigDedicated = frame_parms->p_TDD_UL_DL_ConfigDedicated;
|
||||||
TDD_UL_DL_SlotConfig_t *p_previous_TDD_UL_DL_ConfigDedicated;
|
TDD_UL_DL_SlotConfig_t *p_previous_TDD_UL_DL_ConfigDedicated=NULL;
|
||||||
int next = 0;
|
int next = 0;
|
||||||
|
|
||||||
while (p_TDD_UL_DL_ConfigDedicated != NULL) {
|
while (p_TDD_UL_DL_ConfigDedicated != NULL) {
|
||||||
|
|||||||
@@ -2460,7 +2460,7 @@ ue->prach_resources[eNB_id]->ra_PreambleIndex = preamble_tx;
|
|||||||
ue->tx_total_RE[nr_tti_tx] = 96;
|
ue->tx_total_RE[nr_tti_tx] = 96;
|
||||||
|
|
||||||
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
|
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
|
||||||
ue->prach_vars[eNB_id]->amp = get_tx_amp(ue->tx_power_dBm[nr_tti_tx],
|
ue->prach_vars[eNB_id]->amp = nr_get_tx_amp(ue->tx_power_dBm[nr_tti_tx],
|
||||||
ue->tx_power_max_dBm,
|
ue->tx_power_max_dBm,
|
||||||
ue->frame_parms.N_RB_UL,
|
ue->frame_parms.N_RB_UL,
|
||||||
6);
|
6);
|
||||||
|
|||||||
@@ -59,6 +59,7 @@
|
|||||||
#include "unitary_defs.h"
|
#include "unitary_defs.h"
|
||||||
#include "dummy_functions.c"
|
#include "dummy_functions.c"
|
||||||
#include "executables/thread-common.h"
|
#include "executables/thread-common.h"
|
||||||
|
#include "executables/split_headers.h"
|
||||||
|
|
||||||
void feptx_ofdm(RU_t *ru, int frame, int subframe);
|
void feptx_ofdm(RU_t *ru, int frame, int subframe);
|
||||||
void feptx_prec(RU_t *ru, int frame, int subframe);
|
void feptx_prec(RU_t *ru, int frame, int subframe);
|
||||||
@@ -78,6 +79,13 @@ int n_tx_dropped = 0; /*!< \brief initial max process time for tx */
|
|||||||
int n_rx_dropped = 0; /*!< \brief initial max process time for rx */
|
int n_rx_dropped = 0; /*!< \brief initial max process time for rx */
|
||||||
|
|
||||||
int emulate_rf = 0;
|
int emulate_rf = 0;
|
||||||
|
int split73=0;
|
||||||
|
void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset) {
|
||||||
|
AssertFatal(false, "Must not be called in this context\n");
|
||||||
|
}
|
||||||
|
void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask, uint16_t rnti, int32_t stat) {
|
||||||
|
AssertFatal(false, "Must not be called in this context\n");
|
||||||
|
}
|
||||||
|
|
||||||
void handler(int sig) {
|
void handler(int sig) {
|
||||||
void *array[10];
|
void *array[10];
|
||||||
@@ -515,7 +523,7 @@ int main(int argc, char **argv) {
|
|||||||
char fname[32],vname[32];
|
char fname[32],vname[32];
|
||||||
FILE *bler_fd;
|
FILE *bler_fd;
|
||||||
char bler_fname[256];
|
char bler_fname[256];
|
||||||
FILE *time_meas_fd;
|
FILE *time_meas_fd=NULL;
|
||||||
char time_meas_fname[256];
|
char time_meas_fname[256];
|
||||||
// FILE *tikz_fd;
|
// FILE *tikz_fd;
|
||||||
// char tikz_fname[256];
|
// char tikz_fname[256];
|
||||||
@@ -1266,6 +1274,13 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
L1_rxtx_proc_t *proc_eNB = &eNB->proc.L1_proc;
|
L1_rxtx_proc_t *proc_eNB = &eNB->proc.L1_proc;
|
||||||
|
proc_eNB->threadPool=(tpool_t*)malloc(sizeof(tpool_t));
|
||||||
|
proc_eNB->respEncode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||||
|
proc_eNB->respDecode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||||
|
initTpool("n", proc_eNB->threadPool, true);
|
||||||
|
initNotifiedFIFO(proc_eNB->respEncode);
|
||||||
|
initNotifiedFIFO(proc_eNB->respDecode);
|
||||||
|
|
||||||
proc_eNB->frame_tx=0;
|
proc_eNB->frame_tx=0;
|
||||||
|
|
||||||
if (input_fd==NULL) {
|
if (input_fd==NULL) {
|
||||||
@@ -1446,7 +1461,7 @@ int main(int argc, char **argv) {
|
|||||||
sched_resp.subframe=subframe;
|
sched_resp.subframe=subframe;
|
||||||
sched_resp.frame=proc_eNB->frame_tx;
|
sched_resp.frame=proc_eNB->frame_tx;
|
||||||
eNB->abstraction_flag=0;
|
eNB->abstraction_flag=0;
|
||||||
schedule_response(&sched_resp);
|
schedule_response(&sched_resp, proc_eNB);
|
||||||
phy_procedures_eNB_TX(eNB,proc_eNB,1);
|
phy_procedures_eNB_TX(eNB,proc_eNB,1);
|
||||||
|
|
||||||
if (uncoded_ber_bit == NULL) {
|
if (uncoded_ber_bit == NULL) {
|
||||||
@@ -1480,7 +1495,7 @@ int main(int argc, char **argv) {
|
|||||||
TX_req.tx_request_body.number_of_pdus=0;
|
TX_req.tx_request_body.number_of_pdus=0;
|
||||||
proc_eNB->subframe_tx = subframe+1;
|
proc_eNB->subframe_tx = subframe+1;
|
||||||
sched_resp.subframe=subframe+1;
|
sched_resp.subframe=subframe+1;
|
||||||
schedule_response(&sched_resp);
|
schedule_response(&sched_resp, proc_eNB);
|
||||||
phy_procedures_eNB_TX(eNB,proc_eNB,0);
|
phy_procedures_eNB_TX(eNB,proc_eNB,0);
|
||||||
ru->proc.tti_tx=(subframe+1)%10;
|
ru->proc.tti_tx=(subframe+1)%10;
|
||||||
feptx_prec(ru,proc_eNB->frame_tx,subframe+1);
|
feptx_prec(ru,proc_eNB->frame_tx,subframe+1);
|
||||||
@@ -1583,11 +1598,11 @@ int main(int argc, char **argv) {
|
|||||||
subframe<<1);
|
subframe<<1);
|
||||||
|
|
||||||
for (i=0; i<coded_bits_per_codeword; i++)
|
for (i=0; i<coded_bits_per_codeword; i++)
|
||||||
if ((eNB->dlsch[0][0]->harq_processes[0]->e[i]==1 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] > 0)||
|
if ((eNB->dlsch[0][0]->harq_processes[0]->eDL[i]==1 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] > 0)||
|
||||||
(eNB->dlsch[0][0]->harq_processes[0]->e[i]==0 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] < 0)) {
|
(eNB->dlsch[0][0]->harq_processes[0]->eDL[i]==0 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] < 0)) {
|
||||||
uncoded_ber_bit[bit_errors++] = 1;
|
uncoded_ber_bit[bit_errors++] = 1;
|
||||||
printf("error in pos %d : %d => %d\n",i,
|
printf("error in pos %d : %d => %d\n",i,
|
||||||
eNB->dlsch[0][0]->harq_processes[0]->e[i],
|
eNB->dlsch[0][0]->harq_processes[0]->eDL[i],
|
||||||
UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i]);
|
UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i]);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
@@ -1634,7 +1649,7 @@ int main(int argc, char **argv) {
|
|||||||
//pdsch_vars
|
//pdsch_vars
|
||||||
printf("coded_bits_per_codeword %u\n",coded_bits_per_codeword);
|
printf("coded_bits_per_codeword %u\n",coded_bits_per_codeword);
|
||||||
dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid);
|
dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid);
|
||||||
LOG_M("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4);
|
LOG_M("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->eDL,coded_bits_per_codeword,1,4);
|
||||||
//pdcch_vars
|
//pdcch_vars
|
||||||
LOG_M("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1);
|
LOG_M("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1);
|
||||||
LOG_M("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1);
|
LOG_M("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1);
|
||||||
|
|||||||
@@ -54,6 +54,7 @@
|
|||||||
#include "common/config/config_load_configmodule.h"
|
#include "common/config/config_load_configmodule.h"
|
||||||
#include "executables/thread-common.h"
|
#include "executables/thread-common.h"
|
||||||
#include "targets/RT/USER/lte-softmodem.h"
|
#include "targets/RT/USER/lte-softmodem.h"
|
||||||
|
#include "executables/split_headers.h"
|
||||||
|
|
||||||
double cpuf;
|
double cpuf;
|
||||||
#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0))
|
#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0))
|
||||||
@@ -81,6 +82,14 @@ int n_tx_dropped = 0; /*!< \brief initial max process time for tx */
|
|||||||
int n_rx_dropped = 0; /*!< \brief initial max process time for rx */
|
int n_rx_dropped = 0; /*!< \brief initial max process time for rx */
|
||||||
|
|
||||||
|
|
||||||
|
int split73=0;
|
||||||
|
void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset) {
|
||||||
|
AssertFatal(false, "Must not be called in this context\n");
|
||||||
|
}
|
||||||
|
void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask, uint16_t rnti, int32_t stat) {
|
||||||
|
AssertFatal(false, "Must not be called in this context\n");
|
||||||
|
}
|
||||||
|
|
||||||
extern void fep_full(RU_t *ru, int subframe);
|
extern void fep_full(RU_t *ru, int subframe);
|
||||||
extern void ru_fep_full_2thread(RU_t *ru, int subframe);
|
extern void ru_fep_full_2thread(RU_t *ru, int subframe);
|
||||||
//extern void eNB_fep_full(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc);
|
//extern void eNB_fep_full(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc);
|
||||||
@@ -793,6 +802,13 @@ int main(int argc, char **argv) {
|
|||||||
proc_rxtx_ue->frame_rx = (subframe<4)?(proc_rxtx->frame_tx-1):(proc_rxtx->frame_tx);
|
proc_rxtx_ue->frame_rx = (subframe<4)?(proc_rxtx->frame_tx-1):(proc_rxtx->frame_tx);
|
||||||
proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx;
|
proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx;
|
||||||
proc_rxtx_ue->subframe_rx = (proc_rxtx->subframe_tx+6)%10;
|
proc_rxtx_ue->subframe_rx = (proc_rxtx->subframe_tx+6)%10;
|
||||||
|
proc_rxtx->threadPool=(tpool_t*)malloc(sizeof(tpool_t));
|
||||||
|
proc_rxtx->respEncode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||||
|
proc_rxtx->respDecode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||||
|
initTpool("n",proc_rxtx->threadPool, true);
|
||||||
|
initNotifiedFIFO(proc_rxtx->respEncode);
|
||||||
|
initNotifiedFIFO(proc_rxtx->respDecode);
|
||||||
|
|
||||||
printf("Init UL hopping UE\n");
|
printf("Init UL hopping UE\n");
|
||||||
init_ul_hopping(&UE->frame_parms);
|
init_ul_hopping(&UE->frame_parms);
|
||||||
printf("Init UL hopping eNB\n");
|
printf("Init UL hopping eNB\n");
|
||||||
@@ -995,7 +1011,7 @@ int main(int argc, char **argv) {
|
|||||||
srs_flag);
|
srs_flag);
|
||||||
sched_resp.subframe=(subframe+6)%10;
|
sched_resp.subframe=(subframe+6)%10;
|
||||||
sched_resp.frame=(1024+eNB->proc.frame_rx+((subframe<4)?-1:0))&1023;
|
sched_resp.frame=(1024+eNB->proc.frame_rx+((subframe<4)?-1:0))&1023;
|
||||||
schedule_response(&sched_resp);
|
schedule_response(&sched_resp, proc_rxtx);
|
||||||
|
|
||||||
/////////////////////
|
/////////////////////
|
||||||
if (abstx) {
|
if (abstx) {
|
||||||
@@ -1270,7 +1286,7 @@ int main(int argc, char **argv) {
|
|||||||
LOG_UDUMPMSG(SIM,dataArray(table_rx),table_rx->size,LOG_DUMP_DOUBLE,"The receiver raw data: \n");
|
LOG_UDUMPMSG(SIM,dataArray(table_rx),table_rx->size,LOG_DUMP_DOUBLE,"The receiver raw data: \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\n**********rb: %d ***mcs : %d *********SNR = %f dB (%f): TX %u dB (gain %f dB), N0W %f dB, I0 %d dB, delta_IF %d [ (%d,%d) dB / (%d,%d) dB ]**************************\n",
|
printf("\n**********rb: %d ***mcs : %d *********SNR = %f dB (%f): TX %u dB (gain %f dB), N0W %f dB, I0 %u dB, delta_IF %d [ (%d,%d) dB / (%u,%u) dB ]**************************\n",
|
||||||
nb_rb,mcs,SNR,SNR2,
|
nb_rb,mcs,SNR,SNR2,
|
||||||
tx_lev_dB,
|
tx_lev_dB,
|
||||||
20*log10(tx_gain),
|
20*log10(tx_gain),
|
||||||
|
|||||||
@@ -76,3 +76,6 @@ MESSAGE_DEF(NAS_DOWNLINK_DATA_IND, MESSAGE_PRIORITY_MED, NasDlDataInd
|
|||||||
|
|
||||||
// eNB: realtime -> RRC messages
|
// eNB: realtime -> RRC messages
|
||||||
MESSAGE_DEF(RRC_SUBFRAME_PROCESS, MESSAGE_PRIORITY_MED, RrcSubframeProcess, rrc_subframe_process)
|
MESSAGE_DEF(RRC_SUBFRAME_PROCESS, MESSAGE_PRIORITY_MED, RrcSubframeProcess, rrc_subframe_process)
|
||||||
|
|
||||||
|
// eNB: RLC -> RRC messages
|
||||||
|
MESSAGE_DEF(RLC_SDU_INDICATION, MESSAGE_PRIORITY_MED, RlcSduIndication, rlc_sdu_indication)
|
||||||
|
|||||||
@@ -87,6 +87,8 @@
|
|||||||
|
|
||||||
#define RRC_SUBFRAME_PROCESS(mSGpTR) (mSGpTR)->ittiMsg.rrc_subframe_process
|
#define RRC_SUBFRAME_PROCESS(mSGpTR) (mSGpTR)->ittiMsg.rrc_subframe_process
|
||||||
|
|
||||||
|
#define RLC_SDU_INDICATION(mSGpTR) (mSGpTR)->ittiMsg.rlc_sdu_indication
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------------------------//
|
||||||
typedef struct RrcStateInd_s {
|
typedef struct RrcStateInd_s {
|
||||||
Rrc_State_t state;
|
Rrc_State_t state;
|
||||||
@@ -429,4 +431,12 @@ typedef struct rrc_subframe_process_s {
|
|||||||
int CC_id;
|
int CC_id;
|
||||||
} RrcSubframeProcess;
|
} RrcSubframeProcess;
|
||||||
|
|
||||||
|
// eNB: RLC -> RRC messages
|
||||||
|
typedef struct rlc_sdu_indication_s {
|
||||||
|
int rnti;
|
||||||
|
int is_successful;
|
||||||
|
int srb_id;
|
||||||
|
int message_id;
|
||||||
|
} RlcSduIndication;
|
||||||
|
|
||||||
#endif /* RRC_MESSAGES_TYPES_H_ */
|
#endif /* RRC_MESSAGES_TYPES_H_ */
|
||||||
|
|||||||
@@ -290,7 +290,7 @@ Protocol__FlexUlCqiReport * copy_ul_cqi_report(Protocol__FlexUlCqiReport * origi
|
|||||||
full_ul_report->has_sfn_sn = original->has_sfn_sn;
|
full_ul_report->has_sfn_sn = original->has_sfn_sn;
|
||||||
full_ul_report->n_cqi_meas = original->n_cqi_meas;
|
full_ul_report->n_cqi_meas = original->n_cqi_meas;
|
||||||
|
|
||||||
Protocol__FlexUlCqi **ul_report;
|
Protocol__FlexUlCqi **ul_report=NULL;
|
||||||
ul_report = malloc(sizeof(Protocol__FlexUlCqi *) * full_ul_report->n_cqi_meas);
|
ul_report = malloc(sizeof(Protocol__FlexUlCqi *) * full_ul_report->n_cqi_meas);
|
||||||
if(ul_report == NULL)
|
if(ul_report == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
@@ -348,7 +348,7 @@ Protocol__FlexDlCqiReport * copy_dl_cqi_report(Protocol__FlexDlCqiReport * origi
|
|||||||
dl_report->has_sfn_sn = original->has_sfn_sn;
|
dl_report->has_sfn_sn = original->has_sfn_sn;
|
||||||
dl_report->n_csi_report = original->n_csi_report;
|
dl_report->n_csi_report = original->n_csi_report;
|
||||||
|
|
||||||
Protocol__FlexDlCsi **csi_reports;
|
Protocol__FlexDlCsi **csi_reports=NULL;
|
||||||
csi_reports = malloc(sizeof(Protocol__FlexDlCsi *) * dl_report->n_csi_report);
|
csi_reports = malloc(sizeof(Protocol__FlexDlCsi *) * dl_report->n_csi_report);
|
||||||
if (csi_reports == NULL)
|
if (csi_reports == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
@@ -383,7 +383,7 @@ Protocol__FlexPagingBufferReport * copy_paging_buffer_report(Protocol__FlexPagin
|
|||||||
protocol__flex_paging_buffer_report__init(copy);
|
protocol__flex_paging_buffer_report__init(copy);
|
||||||
copy->n_paging_info = original->n_paging_info;
|
copy->n_paging_info = original->n_paging_info;
|
||||||
|
|
||||||
Protocol__FlexPagingInfo **p_info;
|
Protocol__FlexPagingInfo **p_info=NULL;
|
||||||
p_info = malloc(sizeof(Protocol__FlexPagingInfo *) * copy->n_paging_info);
|
p_info = malloc(sizeof(Protocol__FlexPagingInfo *) * copy->n_paging_info);
|
||||||
if (p_info == NULL)
|
if (p_info == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
|
|||||||
@@ -2240,7 +2240,7 @@ void ulsch_scheduler_pre_ue_select_fairRR(
|
|||||||
uint8_t first_ue_total[MAX_NUM_CCs][20];
|
uint8_t first_ue_total[MAX_NUM_CCs][20];
|
||||||
uint8_t first_ue_id[MAX_NUM_CCs][20];
|
uint8_t first_ue_id[MAX_NUM_CCs][20];
|
||||||
uint8_t ul_inactivity_num[MAX_NUM_CCs];
|
uint8_t ul_inactivity_num[MAX_NUM_CCs];
|
||||||
uint8_t ul_inactivity_id[MAX_NUM_CCs][20];
|
uint8_t ul_inactivity_id[MAX_NUM_CCs][20]={0};
|
||||||
// LTE_DL_FRAME_PARMS *frame_parms;
|
// LTE_DL_FRAME_PARMS *frame_parms;
|
||||||
uint8_t ulsch_ue_max_num[MAX_NUM_CCs];
|
uint8_t ulsch_ue_max_num[MAX_NUM_CCs];
|
||||||
uint16_t saved_ulsch_dci[MAX_NUM_CCs];
|
uint16_t saved_ulsch_dci[MAX_NUM_CCs];
|
||||||
|
|||||||
@@ -714,7 +714,7 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
|
|||||||
mbms_rab_id = cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9;
|
mbms_rab_id = cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9;
|
||||||
|
|
||||||
rlc_status =
|
rlc_status =
|
||||||
mac_rlc_status_ind(module_idP, 0/*0xfffd*/, frameP, subframeP,
|
mac_rlc_status_ind(module_idP, 0xfffd, frameP, subframeP,
|
||||||
module_idP, ENB_FLAG_YES, MBMS_FLAG_YES,
|
module_idP, ENB_FLAG_YES, MBMS_FLAG_YES,
|
||||||
cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9,
|
cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9,
|
||||||
//MTCH,
|
//MTCH,
|
||||||
@@ -771,7 +771,7 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
|
|||||||
TBS - header_len_mcch - header_len_msi -
|
TBS - header_len_mcch - header_len_msi -
|
||||||
sdu_length_total - header_len_mtch, header_len_mtch, rlc_status.bytes_in_buffer);
|
sdu_length_total - header_len_mtch, header_len_mtch, rlc_status.bytes_in_buffer);
|
||||||
|
|
||||||
sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 0, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_YES,cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9,
|
sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 0xfffd, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_YES,cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9,
|
||||||
TBS - header_len_mcch - header_len_msi - sdu_length_total - header_len_mtch,
|
TBS - header_len_mcch - header_len_msi - sdu_length_total - header_len_mtch,
|
||||||
(char *)
|
(char *)
|
||||||
&mch_buffer[sdu_length_total]
|
&mch_buffer[sdu_length_total]
|
||||||
@@ -1553,7 +1553,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
|
|||||||
mbms_rab_id = cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9;
|
mbms_rab_id = cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9;
|
||||||
|
|
||||||
rlc_status =
|
rlc_status =
|
||||||
mac_rlc_status_ind(module_idP, 0/*0xfffd*/, frameP, subframeP,
|
mac_rlc_status_ind(module_idP, 0xfffd, frameP, subframeP,
|
||||||
module_idP, ENB_FLAG_YES, MBMS_FLAG_YES,
|
module_idP, ENB_FLAG_YES, MBMS_FLAG_YES,
|
||||||
cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9,
|
cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9,
|
||||||
//MTCH,
|
//MTCH,
|
||||||
@@ -1576,7 +1576,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
|
|||||||
TBS - header_len_mcch - header_len_msi -
|
TBS - header_len_mcch - header_len_msi -
|
||||||
sdu_length_total - header_len_mtch, header_len_mtch, rlc_status.bytes_in_buffer);
|
sdu_length_total - header_len_mtch, header_len_mtch, rlc_status.bytes_in_buffer);
|
||||||
|
|
||||||
sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 0, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_YES,cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9,
|
sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 0xfffd, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_YES,cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9,
|
||||||
TBS - header_len_mcch - header_len_msi - sdu_length_total - header_len_mtch,
|
TBS - header_len_mcch - header_len_msi - sdu_length_total - header_len_mtch,
|
||||||
(char *)
|
(char *)
|
||||||
&mch_buffer[sdu_length_total]
|
&mch_buffer[sdu_length_total]
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ rx_sdu(const module_id_t enb_mod_idP,
|
|||||||
UE_template_ptr->scheduled_ul_bytes = 0;
|
UE_template_ptr->scheduled_ul_bytes = 0;
|
||||||
}
|
}
|
||||||
} else { // sduP == NULL => error
|
} else { // sduP == NULL => error
|
||||||
LOG_W(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d ULSCH in error in round %d, ul_cqi %d, UE_id %d, RNTI %x\n",
|
LOG_W(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d ULSCH in error in round %d, ul_cqi %d, UE_id %d, RNTI %x (len %d)\n",
|
||||||
enb_mod_idP,
|
enb_mod_idP,
|
||||||
harq_pid,
|
harq_pid,
|
||||||
CC_idP,
|
CC_idP,
|
||||||
@@ -189,7 +189,8 @@ rx_sdu(const module_id_t enb_mod_idP,
|
|||||||
UE_scheduling_control->round_UL[CC_idP][harq_pid],
|
UE_scheduling_control->round_UL[CC_idP][harq_pid],
|
||||||
ul_cqi,
|
ul_cqi,
|
||||||
UE_id,
|
UE_id,
|
||||||
current_rnti);
|
current_rnti,
|
||||||
|
sdu_lenP);
|
||||||
|
|
||||||
if (ul_cqi > 200) { // too high energy pattern
|
if (ul_cqi > 200) { // too high energy pattern
|
||||||
UE_scheduling_control->pusch_snr[CC_idP] = ul_cqi;
|
UE_scheduling_control->pusch_snr[CC_idP] = ul_cqi;
|
||||||
|
|||||||
@@ -1972,6 +1972,10 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
|
|||||||
subframe, ENB_FLAG_NO,
|
subframe, ENB_FLAG_NO,
|
||||||
lcid);
|
lcid);
|
||||||
lcid_buffer_occupancy_new = lcid_buffer_occupancy_old;
|
lcid_buffer_occupancy_new = lcid_buffer_occupancy_old;
|
||||||
|
#if 0
|
||||||
|
/* TODO: those assert crash the L2 simulator with the new RLC.
|
||||||
|
* Are they necessary?
|
||||||
|
*/
|
||||||
AssertFatal(lcid_buffer_occupancy_new ==
|
AssertFatal(lcid_buffer_occupancy_new ==
|
||||||
UE_mac_inst[module_idP].
|
UE_mac_inst[module_idP].
|
||||||
scheduling_info.LCID_buffer_remain[lcid],
|
scheduling_info.LCID_buffer_remain[lcid],
|
||||||
@@ -1990,6 +1994,7 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
|
|||||||
scheduling_info.BSR_bytes[UE_mac_inst[module_idP].
|
scheduling_info.BSR_bytes[UE_mac_inst[module_idP].
|
||||||
scheduling_info.LCGID
|
scheduling_info.LCGID
|
||||||
[lcid]]);
|
[lcid]]);
|
||||||
|
#endif
|
||||||
|
|
||||||
//Multiplex all available DCCH RLC PDUs considering to multiplex the last PDU each time for maximize the data
|
//Multiplex all available DCCH RLC PDUs considering to multiplex the last PDU each time for maximize the data
|
||||||
//Adjust at the end of the loop
|
//Adjust at the end of the loop
|
||||||
@@ -2085,18 +2090,10 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Update Buffer remain and BSR bytes after transmission
|
//Update Buffer remain and BSR bytes after transmission
|
||||||
AssertFatal(lcid_buffer_occupancy_new <=
|
UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] = lcid_buffer_occupancy_new;
|
||||||
lcid_buffer_occupancy_old,
|
UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] += (lcid_buffer_occupancy_new - lcid_buffer_occupancy_old);
|
||||||
"MAC UE Tx error : Buffer Occupancy After Tx=%d greater than before=%d BO! for LCID=%d RLC PDU nb=%d Frame %d Subrame %d\n",
|
if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] < 0)
|
||||||
lcid_buffer_occupancy_new,
|
UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] = 0;
|
||||||
lcid_buffer_occupancy_old, lcid,
|
|
||||||
lcid_rlc_pdu_count, frameP, subframe);
|
|
||||||
UE_mac_inst[module_idP].scheduling_info.
|
|
||||||
LCID_buffer_remain[lcid] = lcid_buffer_occupancy_new;
|
|
||||||
UE_mac_inst[module_idP].
|
|
||||||
scheduling_info.BSR_bytes[UE_mac_inst[module_idP].
|
|
||||||
scheduling_info.LCGID[lcid]] +=
|
|
||||||
(lcid_buffer_occupancy_new - lcid_buffer_occupancy_old);
|
|
||||||
|
|
||||||
//Update the number of LCGID with data as BSR shall reflect status after BSR transmission
|
//Update the number of LCGID with data as BSR shall reflect status after BSR transmission
|
||||||
if ((num_lcg_id_with_data > 1)
|
if ((num_lcg_id_with_data > 1)
|
||||||
|
|||||||
@@ -166,6 +166,11 @@ void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
|
|||||||
nr_dci_pdu_rel15_t *nr_pdci_info_extracted);
|
nr_dci_pdu_rel15_t *nr_pdci_info_extracted);
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t
|
||||||
|
nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
|
||||||
|
sub_frame_t subframe, uint8_t eNB_index,
|
||||||
|
uint8_t *ulsch_buffer, uint16_t buflen, uint8_t *access_mode) ;
|
||||||
|
|
||||||
int set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg, int mu,
|
int set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg, int mu,
|
||||||
int nrofDownlinkSlots, int nrofDownlinkSymbols,
|
int nrofDownlinkSlots, int nrofDownlinkSymbols,
|
||||||
int nrofUplinkSlots, int nrofUplinkSymbols);
|
int nrofUplinkSlots, int nrofUplinkSymbols);
|
||||||
|
|||||||
@@ -507,7 +507,7 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
|
|||||||
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n");
|
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n");
|
||||||
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0,
|
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0,
|
||||||
"searchPsacesToAddModList is empty\n");
|
"searchPsacesToAddModList is empty\n");
|
||||||
NR_SearchSpace_t *ss;
|
NR_SearchSpace_t *ss=NULL;
|
||||||
int found=0;
|
int found=0;
|
||||||
int target_ss = NR_SearchSpace__searchSpaceType_PR_common;
|
int target_ss = NR_SearchSpace__searchSpaceType_PR_common;
|
||||||
if (ss_type == 1) {
|
if (ss_type == 1) {
|
||||||
|
|||||||
@@ -1,31 +1,23 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
OpenAirInterface
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||||
Copyright(c) 1999 - 2014 Eurecom
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||||
it under the terms of the GNU General Public License as published by
|
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
* except in compliance with the License.
|
||||||
(at your option) any later version.
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.openairinterface.org/?page_id=698
|
||||||
OpenAirInterface is distributed in the hope that it will be useful,
|
*
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
GNU General Public License for more details.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
You should have received a copy of the GNU General Public License
|
* limitations under the License.
|
||||||
along with OpenAirInterface.The full GNU General Public License is
|
*-------------------------------------------------------------------------------
|
||||||
included in this distribution in the file called "COPYING". If not,
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||||
see <http://www.gnu.org/licenses/>.
|
* contact@openairinterface.org
|
||||||
|
*/
|
||||||
Contact Information
|
|
||||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
|
||||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
|
||||||
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
|
|
||||||
|
|
||||||
Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
/*! \file enb_agent.h
|
/*! \file enb_agent.h
|
||||||
* \brief top level enb agent receive thread and itti task
|
* \brief top level enb agent receive thread and itti task
|
||||||
|
|||||||
@@ -1,32 +1,23 @@
|
|||||||
|
/*
|
||||||
/*******************************************************************************
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||||
OpenAirInterface
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
Copyright(c) 1999 - 2014 Eurecom
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||||
it under the terms of the GNU General Public License as published by
|
* except in compliance with the License.
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
* You may obtain a copy of the License at
|
||||||
(at your option) any later version.
|
*
|
||||||
|
* http://www.openairinterface.org/?page_id=698
|
||||||
|
*
|
||||||
OpenAirInterface is distributed in the hope that it will be useful,
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
GNU General Public License for more details.
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
You should have received a copy of the GNU General Public License
|
*-------------------------------------------------------------------------------
|
||||||
along with OpenAirInterface.The full GNU General Public License is
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||||
included in this distribution in the file called "COPYING". If not,
|
* contact@openairinterface.org
|
||||||
see <http://www.gnu.org/licenses/>.
|
*/
|
||||||
|
|
||||||
Contact Information
|
|
||||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
|
||||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
|
||||||
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
|
|
||||||
|
|
||||||
Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
/*! \file proto_agent.h
|
/*! \file proto_agent.h
|
||||||
* \brief top level protocol agent
|
* \brief top level protocol agent
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user