Merge branch 'NR_UL_scheduling' of https://gitlab.eurecom.fr/oai/openairinterface5g into NR_UL_scheduling

This commit is contained in:
Raymond Knopp
2020-08-25 01:50:43 +02:00
154 changed files with 7638 additions and 4374 deletions
+21 -1
View File
@@ -66,7 +66,8 @@ pipeline {
"Test-IF4p5-TDD-Band38-Multi-RRU",
"Test-eNB-OAI-UE-FDD-Band7",
"Test-Mono-FDD-Band13-X2-HO",
"Test-TDD-Band78-gNB-NR-UE"
"Test-TDD-Band78-gNB-NR-UE",
"Test-OCP-FDD-Band7"
])
ansiColor('xterm')
}
@@ -683,6 +684,25 @@ pipeline {
}
}
}
stage ("Test OAI OCP-eNB - FDD - Band 7 - B210") {
steps {
script {
triggerSlaveJob ('OCPeNB-FDD-Band7-B210', 'Test-OCP-FDD-Band7')
}
}
post {
always {
script {
finalizeSlaveJob('OCPeNB-FDD-Band7-B210')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
}
}
}
}
}
post {
always {
+229
View File
@@ -0,0 +1,229 @@
# * 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 Libs
#-----------------------------------------------------------
import sys # arg
import re # reg
import yaml
#-----------------------------------------------------------
# Parsing Command Line Arguements
#-----------------------------------------------------------
def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,HELP):
py_param_file_present = False
py_params={}
while len(argvs) > 1:
myArgv = argvs.pop(1) # 0th is this file's name
#--help
if re.match('^\-\-help$', myArgv, re.IGNORECASE):
HELP.GenericHelp(CONST.Version)
sys.exit(0)
#--apply=<filename> as parameters file, to replace inline parameters
elif re.match('^\-\-Apply=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-Apply=(.+)$', myArgv, re.IGNORECASE)
py_params_file = matchReg.group(1)
with open(py_params_file,'r') as file:
# The FullLoader parameter handles the conversion from YAML
# scalar values to Python dictionary format
py_params = yaml.load(file,Loader=yaml.FullLoader)
py_param_file_present = True #to be removed once validated
#AssignParams(py_params) #to be uncommented once validated
#consider inline parameters
elif re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE)
mode = matchReg.group(1)
elif re.match('^\-\-eNBRepository=(.+)$|^\-\-ranRepository(.+)$', myArgv, re.IGNORECASE):
if re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE)
else:
matchReg = re.match('^\-\-ranRepository=(.+)$', myArgv, re.IGNORECASE)
CiTestObj.ranRepository = matchReg.group(1)
RAN.ranRepository=matchReg.group(1)
HTML.ranRepository=matchReg.group(1)
ldpc.ranRepository=matchReg.group(1)
elif re.match('^\-\-eNB_AllowMerge=(.+)$|^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE):
if re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE)
else:
matchReg = re.match('^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE)
doMerge = matchReg.group(1)
ldpc.ranAllowMerge=matchReg.group(1)
if ((doMerge == 'true') or (doMerge == 'True')):
CiTestObj.ranAllowMerge = True
RAN.ranAllowMerge=True
HTML.ranAllowMerge=True
elif re.match('^\-\-eNBBranch=(.+)$|^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE):
if re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE)
else:
matchReg = re.match('^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE)
CiTestObj.ranBranch = matchReg.group(1)
RAN.ranBranch=matchReg.group(1)
HTML.ranBranch=matchReg.group(1)
ldpc.ranBranch=matchReg.group(1)
elif re.match('^\-\-eNBCommitID=(.*)$|^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE):
if re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE)
else:
matchReg = re.match('^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE)
CiTestObj.ranCommitID = matchReg.group(1)
RAN.ranCommitID=matchReg.group(1)
HTML.ranCommitID=matchReg.group(1)
ldpc.ranCommitID=matchReg.group(1)
elif re.match('^\-\-eNBTargetBranch=(.*)$|^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE):
if re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE)
else:
matchReg = re.match('^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE)
CiTestObj.ranTargetBranch = matchReg.group(1)
RAN.ranTargetBranch=matchReg.group(1)
HTML.ranTargetBranch=matchReg.group(1)
ldpc.ranTargetBranch=matchReg.group(1)
elif re.match('^\-\-eNBIPAddress=(.+)$|^\-\-eNB[1-2]IPAddress=(.+)$', myArgv, re.IGNORECASE):
if re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE)
RAN.eNBIPAddress=matchReg.group(1)
ldpc.eNBIpAddr=matchReg.group(1)
elif re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE)
RAN.eNB1IPAddress=matchReg.group(1)
elif re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE)
RAN.eNB2IPAddress=matchReg.group(1)
elif re.match('^\-\-eNBUserName=(.+)$|^\-\-eNB[1-2]UserName=(.+)$', myArgv, re.IGNORECASE):
if re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE)
RAN.eNBUserName=matchReg.group(1)
ldpc.eNBUserName=matchReg.group(1)
elif re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE)
RAN.eNB1UserName=matchReg.group(1)
elif re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE)
RAN.eNB2UserName=matchReg.group(1)
elif re.match('^\-\-eNBPassword=(.+)$|^\-\-eNB[1-2]Password=(.+)$', myArgv, re.IGNORECASE):
if re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE)
RAN.eNBPassword=matchReg.group(1)
ldpc.eNBPassWord=matchReg.group(1)
elif re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE)
RAN.eNB1Password=matchReg.group(1)
elif re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE)
RAN.eNB2Password=matchReg.group(1)
elif re.match('^\-\-eNBSourceCodePath=(.+)$|^\-\-eNB[1-2]SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
if re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE)
RAN.eNBSourceCodePath=matchReg.group(1)
ldpc.eNBSourceCodePath=matchReg.group(1)
elif re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE)
RAN.eNB1SourceCodePath=matchReg.group(1)
elif re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE)
RAN.eNB2SourceCodePath=matchReg.group(1)
elif re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE)
EPC.IPAddress=matchReg.group(1)
elif re.match('^\-\-EPCUserName=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-EPCUserName=(.+)$', myArgv, re.IGNORECASE)
EPC.UserName=matchReg.group(1)
elif re.match('^\-\-EPCPassword=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-EPCPassword=(.+)$', myArgv, re.IGNORECASE)
EPC.Password=matchReg.group(1)
elif re.match('^\-\-EPCSourceCodePath=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-EPCSourceCodePath=(.+)$', myArgv, re.IGNORECASE)
EPC.SourceCodePath=matchReg.group(1)
elif re.match('^\-\-EPCType=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-EPCType=(.+)$', myArgv, re.IGNORECASE)
if re.match('OAI', matchReg.group(1), re.IGNORECASE) or re.match('ltebox', matchReg.group(1), re.IGNORECASE) or re.match('OAI-Rel14-CUPS', matchReg.group(1), re.IGNORECASE) or re.match('OAI-Rel14-Docker', matchReg.group(1), re.IGNORECASE):
EPC.Type=matchReg.group(1)
else:
sys.exit('Invalid EPC Type: ' + matchReg.group(1) + ' -- (should be OAI or ltebox or OAI-Rel14-CUPS or OAI-Rel14-Docker)')
elif re.match('^\-\-EPCContainerPrefix=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-EPCContainerPrefix=(.+)$', myArgv, re.IGNORECASE)
EPC.ContainerPrefix=matchReg.group(1)
elif re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE)
CiTestObj.ADBIPAddress = matchReg.group(1)
elif re.match('^\-\-ADBUserName=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-ADBUserName=(.+)$', myArgv, re.IGNORECASE)
CiTestObj.ADBUserName = matchReg.group(1)
elif re.match('^\-\-ADBType=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-ADBType=(.+)$', myArgv, re.IGNORECASE)
if re.match('centralized', matchReg.group(1), re.IGNORECASE) or re.match('distributed', matchReg.group(1), re.IGNORECASE):
if re.match('distributed', matchReg.group(1), re.IGNORECASE):
CiTestObj.ADBCentralized = False
else:
CiTestObj.ADBCentralized = True
else:
sys.exit('Invalid ADB Type: ' + matchReg.group(1) + ' -- (should be centralized or distributed)')
elif re.match('^\-\-ADBPassword=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-ADBPassword=(.+)$', myArgv, re.IGNORECASE)
CiTestObj.ADBPassword = matchReg.group(1)
elif re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE)
CiTestObj.testXMLfiles.append(matchReg.group(1))
HTML.testXMLfiles.append(matchReg.group(1))
HTML.nbTestXMLfiles=HTML.nbTestXMLfiles+1
elif re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE)
CiTestObj.UEIPAddress = matchReg.group(1)
elif re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE)
CiTestObj.UEUserName = matchReg.group(1)
elif re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE)
CiTestObj.UEPassword = matchReg.group(1)
elif re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE)
CiTestObj.UESourceCodePath = matchReg.group(1)
elif re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE)
finalStatus = matchReg.group(1)
if ((finalStatus == 'true') or (finalStatus == 'True')):
CiTestObj.finalStatus = True
else:
HELP.GenericHelp(CONST.Version)
sys.exit('Invalid Parameter: ' + myArgv)
return py_param_file_present, py_params, mode
+88
View File
@@ -0,0 +1,88 @@
# * 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
#---------------------------------------------------------------------
#to use logging.info()
import logging
#to create a SSH object locally in the methods
import sshconnection
#time.sleep
import time
class CotsUe:
def __init__(self,model,UEIPAddr,UEUserName,UEPassWord):
self.model = model
self.UEIPAddr = UEIPAddr
self.UEUserName = UEUserName
self.UEPassWord = UEPassWord
self.runargs = '' #on of off to toggle airplane mode on/off
self.__SetAirplaneRetry = 3
#-----------------$
#PUBLIC Methods$
#-----------------$
def Check_Airplane(self):
mySSH = sshconnection.SSHConnection()
mySSH.open(self.UEIPAddr, self.UEUserName, self.UEPassWord)
status=mySSH.cde_check_value('sudo adb shell settings get global airplane_mode_on ', ['0','1'],5)
mySSH.close()
return status
def Set_Airplane(self,target_state_str):
mySSH = sshconnection.SSHConnection()
mySSH.open(self.UEIPAddr, self.UEUserName, self.UEPassWord)
mySSH.command('sudo adb start-server','$',5)
logging.info("Toggling COTS UE Airplane mode to : "+target_state_str)
current_state = self.Check_Airplane()
if target_state_str.lower()=="on":
target_state=1
else:
target_state=0
if current_state != target_state:
#toggle state
retry = 0
while (current_state!=target_state) and (retry < self.__SetAirplaneRetry):
mySSH.command('sudo adb shell am start -a android.settings.AIRPLANE_MODE_SETTINGS', '\$', 5)
mySSH.command('sudo adb shell input keyevent 20', '\$', 5)
mySSH.command('sudo adb shell input tap 968 324', '\$', 5)
time.sleep(1)
current_state = self.Check_Airplane()
retry+=1
if current_state != target_state:
logging.error("ATTENTION : Could not toggle to : "+target_state_str)
logging.error("Current state is : "+ str(current_state))
else:
print("Airplane mode is already "+ target_state_str)
mySSH.command('sudo adb kill-server','$',5)
mySSH.close()
+284
View File
@@ -0,0 +1,284 @@
Active_eNBs = ( "eNB-Eurecom-LTEBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
eNBs =
(
{
# real_time choice in {hard, rt-preempt, no}
real_time = "no";
////////// Identification parameters:
eNB_ID = 0xe01;
cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB-Eurecom-LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = (
{ mcc = 222; mnc = 01; mnc_length = 2; }
);
tr_s_preference = "local_mac"
////////// Physical parameters:
component_carriers = (
{
node_function = "eNodeB_3GPP";
node_timing = "synch_to_ext_device";
node_synch_ref = 0;
nb_antenna_ports = 1;
ue_TransmissionMode = 1;
frame_type = "FDD";
tdd_config = 3;
tdd_config_s = 0;
prefix_type = "NORMAL";
eutra_band = 7;
downlink_frequency = 2680000000L;
uplink_frequency_offset = -120000000;
Nid_cell = 0;
N_RB_DL = 25;
Nid_cell_mbsfn = 0;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
prach_root = 0;
tx_gain = 90;
rx_gain = 115;
pbch_repetition = "FALSE";
prach_config_index = 0;
prach_high_speed = "DISABLE";
prach_zero_correlation = 1;
prach_freq_offset = 2;
pucch_delta_shift = 1;
pucch_nRB_CQI = 0;
pucch_nCS_AN = 0;
pucch_n1_AN = 0;
pdsch_referenceSignalPower = -29;
pdsch_p_b = 0;
pusch_n_SB = 1;
pusch_enable64QAM = "DISABLE";
pusch_hoppingMode = "interSubFrame";
pusch_hoppingOffset = 0;
pusch_groupHoppingEnabled = "ENABLE";
pusch_groupAssignment = 0;
pusch_sequenceHoppingEnabled = "DISABLE";
pusch_nDMRS1 = 1;
phich_duration = "NORMAL";
phich_resource = "ONESIXTH";
srs_enable = "DISABLE";
/*
srs_BandwidthConfig =;
srs_SubframeConfig =;
srs_ackNackST =;
srs_MaxUpPts =;
*/
pusch_p0_Nominal = -96;
pusch_alpha = "AL1";
pucch_p0_Nominal = -96;
msg3_delta_Preamble = 6;
pucch_deltaF_Format1 = "deltaF2";
pucch_deltaF_Format1b = "deltaF3";
pucch_deltaF_Format2 = "deltaF0";
pucch_deltaF_Format2a = "deltaF0";
pucch_deltaF_Format2b = "deltaF0";
rach_numberOfRA_Preambles = 64;
rach_preamblesGroupAConfig = "DISABLE";
/*
rach_sizeOfRA_PreamblesGroupA = ;
rach_messageSizeGroupA = ;
rach_messagePowerOffsetGroupB = ;
*/
rach_powerRampingStep = 4;
rach_preambleInitialReceivedTargetPower = -108;
rach_preambleTransMax = 10;
rach_raResponseWindowSize = 10;
rach_macContentionResolutionTimer = 48;
rach_maxHARQ_Msg3Tx = 4;
pcch_default_PagingCycle = 128;
pcch_nB = "oneT";
bcch_modificationPeriodCoeff = 2;
ue_TimersAndConstants_t300 = 1000;
ue_TimersAndConstants_t301 = 1000;
ue_TimersAndConstants_t310 = 1000;
ue_TimersAndConstants_t311 = 10000;
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
//Parameters for SIB18
rxPool_sc_CP_Len = "normal";
rxPool_sc_Period = "sf40";
rxPool_data_CP_Len = "normal";
rxPool_ResourceConfig_prb_Num = 20;
rxPool_ResourceConfig_prb_Start = 5;
rxPool_ResourceConfig_prb_End = 44;
rxPool_ResourceConfig_offsetIndicator_present = "prSmall";
rxPool_ResourceConfig_offsetIndicator_choice = 0;
rxPool_ResourceConfig_subframeBitmap_present = "prBs40";
rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000";
rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5;
rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
/*
rxPool_dataHoppingConfig_hoppingParameter = 0;
rxPool_dataHoppingConfig_numSubbands = "ns1";
rxPool_dataHoppingConfig_rbOffset = 0;
rxPool_commTxResourceUC-ReqAllowed = "TRUE";
*/
// Parameters for SIB19
discRxPool_cp_Len = "normal"
discRxPool_discPeriod = "rf32"
discRxPool_numRetx = 1;
discRxPool_numRepetition = 2;
discRxPool_ResourceConfig_prb_Num = 5;
discRxPool_ResourceConfig_prb_Start = 3;
discRxPool_ResourceConfig_prb_End = 21;
discRxPool_ResourceConfig_offsetIndicator_present = "prSmall";
discRxPool_ResourceConfig_offsetIndicator_choice = 0;
discRxPool_ResourceConfig_subframeBitmap_present = "prBs40";
discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff";
discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5;
discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
}
);
srb1_parameters :
{
# timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
timer_poll_retransmit = 80;
# timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
timer_reordering = 35;
# timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
timer_status_prohibit = 0;
# poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
poll_pdu = 4;
# poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
poll_byte = 99999;
# max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
max_retx_threshold = 4;
}
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
enable_measurement_reports = "yes";
////////// MME parameters:
mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
///X2
enable_x2 = "yes";
t_reloc_prep = 1000; /* unit: millisecond */
tx2_reloc_overall = 2000; /* unit: millisecond */
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "eth1";
ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR";
ENB_INTERFACE_NAME_FOR_S1U = "eth1";
ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR";
ENB_PORT_FOR_X2C = 36422; # Spec 36422
};
log_config :
{
global_log_level ="info";
global_log_verbosity ="high";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="high";
rlc_log_level ="debug";
rlc_log_verbosity ="high";
pdcp_log_level ="info";
pdcp_log_verbosity ="high";
rrc_log_level ="info";
rrc_log_verbosity ="medium";
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
phy_test_mode = 0;
puSch10xSnr = 160;
puCch10xSnr = 160;
}
);
THREAD_STRUCT = (
{
parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
worker_config = "ENABLE";
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
}
);
RUs = (
{
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 0
att_rx = 0;
bands = [7];
max_pdschReferenceSignalPower = -27;
max_rxgain = 118;
eNB_instances = [0];
clock_src = "external";
}
);
log_config :
{
global_log_level ="info";
global_log_verbosity ="high";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="high";
rlc_log_level ="info";
rlc_log_verbosity ="high";
pdcp_log_level ="info";
pdcp_log_verbosity ="high";
rrc_log_level ="info";
rrc_log_verbosity ="medium";
};
@@ -0,0 +1,291 @@
Active_gNBs = ( "gNB-Eurecom-5GNRBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
gNBs =
(
{
////////// Identification parameters:
gNB_ID = 0xe00;
cell_type = "CELL_MACRO_GNB";
gNB_name = "gNB-Eurecom-5GNRBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({mcc = 222; mnc = 01; mnc_length = 2;});
tr_s_preference = "local_mac"
////////// Physical parameters:
ssb_SubcarrierOffset = 31; //0;
pdsch_AntennaPorts = 1;
servingCellConfigCommon = (
{
#spCellConfigCommon
physCellId = 0;
# downlinkConfigCommon
#frequencyInfoDL
# this is 3600 MHz + 84 PRBs@30kHz SCS (same as initial BWP)
absoluteFrequencySSB = 641272; //641032; #641968; 641968=start of ssb at 3600MHz + 82 RBs 641032=center of SSB at center of cell
dl_frequencyBand = 78;
# this is 3600 MHz
dl_absoluteFrequencyPointA = 640000;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing = 1;
dl_carrierBandwidth = 106;
#initialDownlinkBWP
#genericParameters
# this is RBstart=84,L=13 (275*(L-1))+RBstart
initialDLBWPlocationAndBandwidth = 6366; //28875; //6366; #6407; #3384;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 1;
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 0;
initialDLBWPsearchSpaceZero = 0;
#pdsch-ConfigCommon
#pdschTimeDomainAllocationList (up to 16 entries)
initialDLBWPk0_0 = 0;
#initialULBWPmappingType
#0=typeA,1=typeB
initialDLBWPmappingType_0 = 0;
#this is SS=1,L=13
initialDLBWPstartSymbolAndLength_0 = 40;
initialDLBWPk0_1 = 0;
initialDLBWPmappingType_1 = 0;
#this is SS=2,L=12
initialDLBWPstartSymbolAndLength_1 = 53;
initialDLBWPk0_2 = 0;
initialDLBWPmappingType_2 = 0;
#this is SS=1,L=12
initialDLBWPstartSymbolAndLength_2 = 54;
initialDLBWPk0_3 = 0;
initialDLBWPmappingType_3 = 0;
#this is SS=1,L=4 //5 (4 is for 43, 5 is for 57)
initialDLBWPstartSymbolAndLength_3 = 57; //43; //57;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 78;
#scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
ul_subcarrierSpacing = 1;
ul_carrierBandwidth = 106;
pMax = 20;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 6366; //28875; //6366; #6407; #3384;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
#rach-ConfigCommon
#rach-ConfigGeneric
prach_ConfigurationIndex = 98;
#prach_msg1_FDM
#0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 13;
preambleReceivedTargetPower = -100;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6;
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 5;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
#oneHalf (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14; //15;
#ra_ContentionResolutionTimer
#(0..7) 8,16,24,32,40,48,56,64
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
#1 = 839, 2 = 139
prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
msg1_SubcarrierSpacing = 1,
# restrictedSetConfig
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
# pusch-ConfigCommon (up to 16 elements)
initialULBWPk2_0 = 2;
initialULBWPmappingType_0 = 1
# this is SS=0 L=11
initialULBWPstartSymbolAndLength_0 = 55;
initialULBWPk2_1 = 2;
initialULBWPmappingType_1 = 1;
# this is SS=0 L=12
initialULBWPstartSymbolAndLength_1 = 69;
initialULBWPk2_2 = 7;
initialULBWPmappingType_2 = 1;
# this is SS=10 L=4
initialULBWPstartSymbolAndLength_2 = 52;
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 40;
p0_nominal = -90;
# ssb_PositionsInBurs_BitmapPR
# 1=short, 2=medium, 3=long
ssb_PositionsInBurst_PR = 2;
ssb_PositionsInBurst_Bitmap = 1; #0x80;
# ssb_periodicityServingCell
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
ssb_periodicityServingCell = 2;
# dmrs_TypeA_position
# 0 = pos2, 1 = pos3
dmrs_TypeA_Position = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
subcarrierSpacing = 1;
#tdd-UL-DL-ConfigurationCommon
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
referenceSubcarrierSpacing = 1;
# pattern1
# dl_UL_TransmissionPeriodicity
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
dl_UL_TransmissionPeriodicity = 6;
nrofDownlinkSlots = 7; //8; //7;
nrofDownlinkSymbols = 6; //0; //6;
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4; //0; //4;
ssPBCH_BlockPower = -25;
}
);
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// MME parameters:
mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
///X2
enable_x2 = "yes";
t_reloc_prep = 1000; /* unit: millisecond */
tx2_reloc_overall = 2000; /* unit: millisecond */
target_enb_x2_ip_address = (
{ ipv4 = "CI_FR1_CTL_ENB_IP_ADDR";
ipv6 = "192:168:30::17";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
GNB_INTERFACE_NAME_FOR_S1_MME = "eth0";
GNB_IPV4_ADDRESS_FOR_S1_MME = "CI_GNB_IP_ADDR";
GNB_INTERFACE_NAME_FOR_S1U = "eth0";
GNB_IPV4_ADDRESS_FOR_S1U = "CI_GNB_IP_ADDR";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
GNB_IPV4_ADDRESS_FOR_X2C = "CI_GNB_IP_ADDR";
GNB_PORT_FOR_X2C = 36422; # Spec 36422
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
}
);
RUs = (
{
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 0
att_rx = 0;
bands = [7];
max_pdschReferenceSignalPower = -27;
max_rxgain = 114;
eNB_instances = [0];
clock_src = "external";
}
);
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
//parallel_config = "PARALLEL_SINGLE_THREAD";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
}
);
log_config :
{
global_log_level ="info";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="high";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
pdcp_log_verbosity ="medium";
rrc_log_level ="info";
rrc_log_verbosity ="medium";
};
-32
View File
@@ -66,38 +66,6 @@ class EPCManagement():
self.MmeIPAddress = ''
self.containerPrefix = 'prod'
#-----------------------------------------------------------
# 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
def SetTestCase_id(self, idx):
self.testCase_id = idx
def GetMmeIPAddress(self):
return self.MmeIPAddress
def SetContainerPrefix(self, prefix):
self.containerPrefix = prefix
#-----------------------------------------------------------
# EPC management functions
+2 -61
View File
@@ -82,73 +82,14 @@ class HTMLManagement():
#-----------------------------------------------------------
# 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):
if nbUEs > 0:
self.htmlUEConnected = nbUEs
else:
self.htmlUEConnected = 1
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
+443 -489
View File
File diff suppressed because it is too large Load Diff
+53
View File
@@ -0,0 +1,53 @@
eNBRepository : b
ranRepository : c
eNB_AllowMerge :
ranAllowMerge :
eNBBranch : f
ranBranch : g
eNBCommitID :
ranCommitID : i
eNBTargetBranch : j
ranTargetBranch : k
nodes :
- type : eNB
IPAddress : 001.1.1
UserName : toto
Password : qwe
SourceCodePath : l
- type : gNB
IPAddress : 002.2.2
UserName : tata
Password : asd
SourceCodePath : m
- type : eNB
IPAddress : 003.3.3
UserName : titi
Password : zxc
SourceCodePath : n
- type : gNB
IPAddress : 004.4.4
UserName : caca
Password : pepe
SourceCodePath : o
EPCIPAddress : p
EPCUserName : q
EPCPassword : r
EPCSourceCodePath : s
EPCType : t
EPCContainerPrefix : u
ADBIPAddress : v
ADBUserName : w
ADBType : x
ADBPassword : y
XMLTestFile : z
UEIPAddress : qqq
UEUserName : www
UEPassword : eee
UESourceCodePath : yyy
finalStatus : bbb
+97
View File
@@ -0,0 +1,97 @@
eNBRepository : b
ranRepository : c
eNB_AllowMerge :
ranAllowMerge :
eNBBranch : f
ranBranch : g
eNBCommitID :
ranCommitID : i
eNBTargetBranch : j
ranTargetBranch : k
RAN:
RAN_inst_0:
name : RAN_1
nodes :
- type : eNB
IPAddress : 001.1.1
UserName : toto
Password : qwe
SourceCodePath : l
- type : gNB
IPAddress : 002.2.2
UserName : tata
Password : asd
SourceCodePath : m
- type : eNB
IPAddress : 003.3.3
UserName : titi
Password : zxc
SourceCodePath : n
- type : gNB
IPAddress : 004.4.4
UserName : caca
Password : pepe
SourceCodePath : o
RAN_inst_1:
name : RAN_2
nodes :
- type : eNB
IPAddress : 101.1.1
UserName : toto
Password : qwe
SourceCodePath : l
- type : gNB
IPAddress : 102.2.2
UserName : zaza
Password : asd
SourceCodePath : m
- type : eNB
IPAddress : 103.3.3
UserName : zizi
Password : zxc
SourceCodePath : n
- type : gNB
IPAddress : 104.4.4
UserName : aaaa
Password : pepe
SourceCodePath : o
EPC:
EPC_inst_0:
EPCIPAddress : p
EPCUserName : q
EPCPassword : r
EPCSourceCodePath : s
EPCType : t
EPCContainerPrefix : u
ADB:
ADBIPAddress : v
ADBUserName : w
ADBType : x
ADBPassword : y
UE:
UE_inst_0:
name : UE_1
type :
UEIPAddress : qqq
UEUserName : www
UEPassword : eee
UESourceCodePath : yyy
UE_inst_1:
name : UE_2
type :
UEIPAddress : bloblob
UEUserName : gwou
UEPassword : zebu
UESourceCodePath : pop
XMLTestFile : z
finalStatus : bbb
+97 -193
View File
@@ -77,8 +77,8 @@ class RANManagement():
self.backgroundBuildTestId = ['', '', '']
self.Build_eNB_forced_workspace_cleanup = False
self.Initialize_eNB_args = ''
self.air_interface = 'lte'
self.eNB_instance = ''
self.air_interface = ['', '', ''] #changed from 'lte' to '' may lead to side effects in main
self.eNB_instance = 0
self.eNB_serverId = ''
self.eNBLogFiles = ['', '', '']
self.eNBOptions = ['', '', '']
@@ -91,140 +91,7 @@ class RANManagement():
self.htmlObj = None
self.epcObj = None
#-----------------------------------------------------------
# Setters and Getters on Public members
#-----------------------------------------------------------
def SetHtmlObj(self, obj):
self.htmlObj = obj
def SetEpcObj(self, obj):
self.epcObj = obj
def SetflexranCtrlInstalled(self,fxrctin):
self.flexranCtrlInstalled = fxrctin
def GetflexranCtrlInstalled(self):
return self.flexranCtrlInstalled
def SetflexranCtrlStarted(self,fxrctst):
self.flexranCtrlStarted = fxrctst
def GetflexranCtrlStarted(self):
return self.flexranCtrlStarted
def SetpStatus(self, pSt):
self.pStatus = pSt
def SetranRepository(self, repository):
self.ranRepository = repository
def GetranRepository(self):
return self.ranRepository
def SetranBranch(self, branch):
self.ranBranch = branch
def GetranBranch(self):
return self.ranBranch
def SetranCommitID(self, commitid):
self.ranCommitID = commitid
def GetranCommitID(self):
return self.ranCommitID
def SeteNB_serverId(self, enbsrvid):
self.eNB_serverId = enbsrvid
def GeteNB_serverId(self):
return self.eNB_serverId
def SeteNBIPAddress(self, enbip):
self.eNBIPAddress = enbip
def GeteNBIPAddress(self):
return self.eNBIPAddress
def SeteNBUserName(self, enbusr):
self.eNBUserName = enbusr
def GeteNBUserName(self):
return self.eNBUserName
def SeteNBPassword(self, enbpw):
self.eNBPassword = enbpw
def GeteNBPassword(self):
return self.eNBPassword
def SeteNBSourceCodePath(self, enbcodepath):
self.eNBSourceCodePath = enbcodepath
def GeteNBSourceCodePath(self):
return self.eNBSourceCodePath
def SetranAllowMerge(self, merge):
self.ranAllowMerge = merge
def GetranAllowMerge(self):
return self.ranAllowMerge
def SetranTargetBranch(self, tbranch):
self.ranTargetBranch = tbranch
def GetranTargetBranch(self):
return self.ranTargetBranch
def SetBuild_eNB_args(self, enbbuildarg):
self.Build_eNB_args = enbbuildarg
def GetBuild_eNB_args(self):
return self.Build_eNB_args
def SetInitialize_eNB_args(self, initenbarg):
self.Initialize_eNB_args = initenbarg
def GetInitialize_eNB_args(self):
return self.Initialize_eNB_args
def SetbackgroundBuild(self, bkbuild):
self.backgroundBuild = bkbuild
def GetbackgroundBuild(self):
return self.backgroundBuild
def SetbackgroundBuildTestId(self, bkbuildid):
self.backgroundBuildTestId = bkbuildid
def GetbackgroundBuildTestId(self):
return self.backgroundBuildTestId
def SetBuild_eNB_forced_workspace_cleanup(self, fcdwspclean):
self.Build_eNB_forced_workspace_cleanup = fcdwspclean
def GetBuild_eNB_forced_workspace_cleanup(self):
return self.Build_eNB_forced_workspace_cleanup
def Setair_interface(self, airif):
self.air_interface = airif
def Getair_interface(self):
return self.air_interface
def SeteNB_instance(self, enbinst):
self.eNB_instance = enbinst
def GeteNB_instance(self):
return self.eNB_instance
def SeteNBLogFile(self, enblog, idx):
self.eNBLogFiles[idx] = enblog
def GeteNBLogFile(self, idx):
return self.eNBLogFiles[idx]
def GeteNBmbmsEnable(self, idx):
return self.eNBmbmsEnables[idx]
def SeteNB1IPAddress(self,enb1ip):
self.eNB1IPAddress = enb1ip
def GeteNB1IPAddress(self):
return self.eNB1IPAddress
def SeteNB1UserName(self, enb1usr):
self.eNB1UserName = enb1usr
def GeteNB1UserName(self):
return self.eNB1UserName
def SeteNB1Password(self, enb1pw):
self.eNB1Password = enb1pw
def GeteNB1Password(self):
return self.eNB1Password
def SeteNB1SourceCodePath(self, enb1codepath):
self.eNB1SourceCodePath = enb1codepath
def GeteNB1SourceCodePath(self):
return self.eNB1SourceCodePath
def SeteNB2IPAddress(self, enb2ip):
self.eNB2IPAddress = enb2ip
def GeteNB2IPAddress(self):
return self.eNB2IPAddress
def SeteNB2UserName(self, enb2usr):
self.eNB2UserName = enb2usr
def GeteNB2UserName(self):
return self.eNB2UserName
def SeteNB2Password(self, enb2pw):
self.eNB2Password = enb2pw
def GeteNB2Password(self):
return self.eNB2Password
def SeteNB2SourceCodePath(self, enb2codepath):
self.eNB2SourceCodePath = enb2codepath
def GeteNB2SourceCodePath(self):
return self.eNB2SourceCodePath
def SetprematureExit(self, premex):
self.prematureExit = premex
def GetprematureExit(self):
return self.prematureExit
#-----------------------------------------------------------
# RAN management functions
@@ -254,17 +121,23 @@ class RANManagement():
sys.exit('Insufficient Parameter')
mySSH = SSH.SSHConnection()
mySSH.open(lIpAddr, lUserName, lPassWord)
# Check if we build an 5G-NR gNB or an LTE eNB
result = re.search('--gNB', self.Build_eNB_args)
# Check if we build an 5G-NR gNB or an LTE eNB or an OCP eNB
result = re.search('--eNBocp', self.Build_eNB_args)
if result is not None:
self.air_interface = 'nr'
else:
self.air_interface = 'lte'
self.air_interface[self.eNB_instance] = 'ocp-enb'
else:
result = re.search('--gNB', self.Build_eNB_args)
if result is not None:
self.air_interface[self.eNB_instance] = 'nr-softmodem'
else:
self.air_interface[self.eNB_instance] = 'lte-softmodem'
# Worakround for some servers, we need to erase completely the workspace
if self.Build_eNB_forced_workspace_cleanup:
mySSH.command('echo ' + lPassWord + ' | sudo -S rm -Rf ' + lSourcePath, '\$', 15)
if self.htmlObj is not None:
self.testCase_id = self.htmlObj.GettestCase_id()
self.testCase_id = self.htmlObj.testCase_id
else:
self.testCase_id = '000000'
# on RedHat/CentOS .git extension is mandatory
@@ -332,7 +205,8 @@ class RANManagement():
if self.backgroundBuild:
mySSH.command('echo "./build_oai ' + self.Build_eNB_args + '" > ./my-lte-softmodem-build.sh', '\$', 5)
mySSH.command('chmod 775 ./my-lte-softmodem-build.sh', '\$', 5)
mySSH.command('echo ' + lPassWord + ' | sudo -S -E daemon --inherit --unsafe --name=build_enb_daemon --chdir=' + lSourcePath + '/cmake_targets -o ' + lSourcePath + '/cmake_targets/compile_oai_enb.log ./my-lte-softmodem-build.sh', '\$', 5)
mySSH.command('echo ' + lPassWord + ' | sudo -S ls', '\$', 5)
mySSH.command('echo $USER; nohup sudo -E ./my-lte-softmodem-build.sh' + ' > ' + lSourcePath + '/cmake_targets/compile_oai_enb.log ' + ' 2>&1 &', lUserName, 5)
mySSH.close()
if self.htmlObj is not None:
self.htmlObj.CreateHtmlTestRow(self.Build_eNB_args, 'OK', CONST.ALL_PROCESSES_OK)
@@ -378,21 +252,21 @@ class RANManagement():
def checkBuildeNB(self, lIpAddr, lUserName, lPassWord, lSourcePath, testcaseId):
if self.htmlObj is not None:
self.htmlObj.SettestCase_id(testcaseId)
self.htmlObj.testCase_id=testcaseId
mySSH = SSH.SSHConnection()
mySSH.open(lIpAddr, lUserName, lPassWord)
mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 3)
mySSH.command('ls ran_build/build', '\$', 3)
mySSH.command('ls ran_build/build', '\$', 3)
if self.air_interface == 'nr':
nodeB_prefix = 'g'
else:
nodeB_prefix = 'e'
buildStatus = True
result = re.search(self.air_interface + '-softmodem', mySSH.getBefore())
#check if we have the build corresponding to the air interface keywords (nr-softmode, lte-softmodem, ocp-enb)
logging.info('CHECK Build with IP='+lIpAddr+' SourcePath='+lSourcePath)
result = re.search(self.air_interface[self.eNB_instance], mySSH.getBefore())
if result is None:
buildStatus = False
buildStatus = False #if not, build failed
else:
buildStatus = True
# Generating a BUILD INFO file
mySSH.command('echo "SRC_BRANCH: ' + self.ranBranch + '" > ../LAST_BUILD_INFO.txt', '\$', 2)
mySSH.command('echo "SRC_COMMIT: ' + self.ranCommitID + '" >> ../LAST_BUILD_INFO.txt', '\$', 2)
@@ -404,6 +278,8 @@ class RANManagement():
mySSH.command('echo "TGT_BRANCH: ' + self.ranTargetBranch + '" >> ../LAST_BUILD_INFO.txt', '\$', 2)
else:
mySSH.command('echo "MERGED_W_TGT_BRANCH: NO" >> ../LAST_BUILD_INFO.txt', '\$', 2)
mySSH.command('mkdir -p build_log_' + testcaseId, '\$', 5)
mySSH.command('mv log/* ' + 'build_log_' + testcaseId, '\$', 5)
mySSH.command('mv compile_oai_enb.log ' + 'build_log_' + testcaseId, '\$', 5)
@@ -420,18 +296,20 @@ class RANManagement():
os.remove('./tmp_build' + testcaseId + '.zip')
mySSH.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword)
mySSH.command('cd ' + self.eNBSourceCodePath + '/cmake_targets', '\$', 5)
mySSH.command('unzip -qq -DD tmp_build' + testcaseId + '.zip', '\$', 5)
#-qq quiet / -u update orcreate files
mySSH.command('unzip -u -qq -DD tmp_build' + testcaseId + '.zip', '\$', 5)
mySSH.command('rm -f tmp_build' + testcaseId + '.zip', '\$', 5)
mySSH.close()
else:
mySSH.close()
#generate logging info depending on buildStatus and air interface
if buildStatus:
logging.info('\u001B[1m Building OAI ' + nodeB_prefix + 'NB Pass\u001B[0m')
logging.info('\u001B[1m Building OAI ' + self.air_interface[self.eNB_instance] + ' Pass\u001B[0m')
if self.htmlObj is not None:
self.htmlObj.CreateHtmlTestRow(self.Build_eNB_args, 'OK', CONST.ALL_PROCESSES_OK)
self.htmlObj.CreateHtmlTestRow(self.Build_eNB_args, 'OK', CONST.ALL_PROCESSES_OK)
else:
logging.error('\u001B[1m Building OAI ' + nodeB_prefix + 'NB Failed\u001B[0m')
logging.error('\u001B[1m Building OAI ' + self.air_interface[self.eNB_instance] + ' Failed\u001B[0m')
if self.htmlObj is not None:
self.htmlObj.CreateHtmlTestRow(self.Build_eNB_args, 'KO', CONST.ALL_PROCESSES_OK)
self.htmlObj.CreateHtmlTabFooter(False)
@@ -458,22 +336,22 @@ class RANManagement():
sys.exit('Insufficient Parameter')
if self.htmlObj is not None:
self.testCase_id = self.htmlObj.GettestCase_id()
self.testCase_id = self.htmlObj.testCase_id
else:
self.testCase_id = '000000'
mySSH = SSH.SSHConnection()
if (self.pStatus < 0):
if self.htmlObj is not None:
self.htmlObj.CreateHtmlTestRow(self.Initialize_eNB_args, 'KO', self.pStatus)
self.htmlObj.CreateHtmlTestRow(self.air_interface[self.eNB_instance] + ' ' + self.Initialize_eNB_args, 'KO', self.pStatus)
self.htmlObj.CreateHtmlTabFooter(False)
sys.exit(1)
# If tracer options is on, running tshark on EPC side and capture traffic b/ EPC and eNB
result = re.search('T_stdout', str(self.Initialize_eNB_args))
if (result is not None) and (self.epcObj is not None):
localEpcIpAddr = self.epcObj.GetIPAddress()
localEpcUserName = self.epcObj.GetUserName()
localEpcPassword = self.epcObj.GetPassword()
localEpcIpAddr = self.epcObj.IPAddress
localEpcUserName = self.epcObj.UserName
localEpcPassword = self.epcObj.Password
mySSH.open(localEpcIpAddr, localEpcUserName, localEpcPassword)
mySSH.command('ip addr show | awk -f /tmp/active_net_interfaces.awk | egrep -v "lo|tun"', '\$', 5)
result = re.search('interfaceToUse=(?P<eth_interface>[a-zA-Z0-9\-\_]+)done', mySSH.getBefore())
@@ -522,12 +400,14 @@ class RANManagement():
# Make a copy and adapt to EPC / eNB IP addresses
mySSH.command('cp ' + full_config_file + ' ' + ci_full_config_file, '\$', 5)
if self.epcObj is not None:
localMmeIpAddr = self.epcObj.GetMmeIPAddress()
localMmeIpAddr = self.epcObj.MmeIPAddress
mySSH.command('sed -i -e \'s/CI_MME_IP_ADDR/' + localMmeIpAddr + '/\' ' + ci_full_config_file, '\$', 2);
mySSH.command('sed -i -e \'s/CI_ENB_IP_ADDR/' + lIpAddr + '/\' ' + ci_full_config_file, '\$', 2);
mySSH.command('sed -i -e \'s/CI_GNB_IP_ADDR/' + lIpAddr + '/\' ' + ci_full_config_file, '\$', 2);
mySSH.command('sed -i -e \'s/CI_RCC_IP_ADDR/' + self.eNBIPAddress + '/\' ' + ci_full_config_file, '\$', 2);
mySSH.command('sed -i -e \'s/CI_RRU1_IP_ADDR/' + self.eNB1IPAddress + '/\' ' + ci_full_config_file, '\$', 2);
mySSH.command('sed -i -e \'s/CI_RRU2_IP_ADDR/' + self.eNB2IPAddress + '/\' ' + ci_full_config_file, '\$', 2);
mySSH.command('sed -i -e \'s/CI_FR1_CTL_ENB_IP_ADDR/' + self.eNBIPAddress + '/\' ' + ci_full_config_file, '\$', 2);
if self.flexranCtrlInstalled and self.flexranCtrlStarted:
mySSH.command('sed -i -e \'s/FLEXRAN_ENABLED.*;/FLEXRAN_ENABLED = "yes";/\' ' + ci_full_config_file, '\$', 2);
else:
@@ -549,15 +429,11 @@ class RANManagement():
if self.air_interface == 'nr':
mySSH.command('if [ -e rbconfig.raw ]; then echo ' + lPassWord + ' | sudo -S rm rbconfig.raw; fi', '\$', 5)
mySSH.command('if [ -e reconfig.raw ]; then echo ' + lPassWord + ' | sudo -S rm reconfig.raw; fi', '\$', 5)
mySSH.command('echo "ulimit -c unlimited && ./ran_build/build/' + self.air_interface + '-softmodem -O ' + lSourcePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
# NOTE: WE SHALL do a check if the executable is present (in case build went wrong)
mySSH.command('echo "ulimit -c unlimited && ./ran_build/build/' + self.air_interface[self.eNB_instance] + ' -O ' + lSourcePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
mySSH.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
mySSH.command('echo ' + lPassWord + ' | sudo -S rm -Rf enb_' + self.testCase_id + '.log', '\$', 5)
mySSH.command('hostnamectl','\$', 5)
result = re.search('CentOS Linux 7', mySSH.getBefore())
if result is not None:
mySSH.command('echo $USER; nohup sudo ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh > ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '.log 2>&1 &', lUserName, 10)
else:
mySSH.command('echo ' + lPassWord + ' | sudo -S -E daemon --inherit --unsafe --name=enb' + str(self.eNB_instance) + '_daemon --chdir=' + lSourcePath + '/cmake_targets -o ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '.log ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
mySSH.command('echo $USER; nohup sudo -E ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh > ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '.log 2>&1 &', lUserName, 10)
self.eNBLogFiles[int(self.eNB_instance)] = 'enb_' + self.testCase_id + '.log'
if extra_options != '':
self.eNBOptions[int(self.eNB_instance)] = extra_options
@@ -574,15 +450,15 @@ class RANManagement():
mySSH.command('killall --signal SIGKILL record', '\$', 5)
mySSH.close()
doLoop = False
logging.error('\u001B[1;37;41m eNB logging system did not show got sync! \u001B[0m')
logging.error('\u001B[1;37;41m eNB/gNB/ocp-eNB logging system did not show got sync! \u001B[0m')
if self.htmlObj is not None:
self.htmlObj.CreateHtmlTestRow('-O ' + config_file + extra_options, 'KO', CONST.ALL_PROCESSES_OK)
self.htmlObj.CreateHtmlTestRow(self.air_interface[self.eNB_instance] + ' -O ' + config_file + extra_options, 'KO', CONST.ALL_PROCESSES_OK)
# In case of T tracer recording, we need to kill tshark on EPC side
result = re.search('T_stdout', str(self.Initialize_eNB_args))
if (result is not None) and (self.epcObj is not None):
localEpcIpAddr = self.epcObj.GetIPAddress()
localEpcUserName = self.epcObj.GetUserName()
localEpcPassword = self.epcObj.GetPassword()
localEpcIpAddr = self.epcObj.IPAddress
localEpcUserName = self.epcObj.UserName
localEpcPassword = self.epcObj.Password
mySSH.open(localEpcIpAddr, localEpcUserName, localEpcPassword)
logging.debug('\u001B[1m Stopping tshark \u001B[0m')
mySSH.command('echo ' + localEpcPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5)
@@ -634,8 +510,8 @@ class RANManagement():
mySSH.close()
if self.htmlObj is not None:
self.htmlObj.CreateHtmlTestRow('-O ' + config_file + extra_options, 'OK', CONST.ALL_PROCESSES_OK)
logging.debug('\u001B[1m Initialize eNB Completed\u001B[0m')
self.htmlObj.CreateHtmlTestRow(self.air_interface[self.eNB_instance] + ' -O ' + config_file + extra_options, 'OK', CONST.ALL_PROCESSES_OK)
logging.debug('\u001B[1m Initialize eNB/gNB/ocp-eNB Completed\u001B[0m')
def CheckeNBProcess(self, status_queue):
try:
@@ -658,8 +534,8 @@ class RANManagement():
lPassWord = self.eNBPassword
mySSH = SSH.SSHConnection()
mySSH.open(lIpAddr, lUserName, lPassWord)
mySSH.command('stdbuf -o0 ps -aux | grep --color=never ' + self.air_interface + '-softmodem | grep -v grep', '\$', 5)
result = re.search(self.air_interface + '-softmodem', mySSH.getBefore())
mySSH.command('stdbuf -o0 ps -aux | grep --color=never ' + self.air_interface[self.eNB_instance] + ' | grep -v grep', '\$', 5)
result = re.search(self.air_interface[self.eNB_instance], mySSH.getBefore())
if result is None:
logging.debug('\u001B[1;37;41m eNB Process Not Found! \u001B[0m')
status_queue.put(CONST.ENB_PROCESS_FAILED)
@@ -691,29 +567,28 @@ class RANManagement():
mySSH = SSH.SSHConnection()
mySSH.open(lIpAddr, lUserName, lPassWord)
mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5)
if self.air_interface == 'lte':
if (self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb'):
nodeB_prefix = 'e'
else:
nodeB_prefix = 'g'
mySSH.command('stdbuf -o0 ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5)
result = re.search('-softmodem', mySSH.getBefore())
mySSH.command('stdbuf -o0 ps -aux | grep --color=never -e softmodem -e ocp-enb | grep -v grep', '\$', 5)
result = re.search('(-softmodem|ocp)', mySSH.getBefore())
if result is not None:
mySSH.command('echo ' + lPassWord + ' | sudo -S daemon --name=enb' + str(self.eNB_instance) + '_daemon --stop', '\$', 5)
mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGINT -r .*-softmodem || true', '\$', 5)
mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGINT -r .*-softmodem ocp-enb || true', '\$', 5)
time.sleep(10)
mySSH.command('stdbuf -o0 ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5)
result = re.search('-softmodem', mySSH.getBefore())
mySSH.command('stdbuf -o0 ps -aux | grep --color=never -e softmodem -e ocp-enb | grep -v grep', '\$', 5)
result = re.search('(-softmodem|ocp)', mySSH.getBefore())
if result is not None:
mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGKILL -r .*-softmodem || true', '\$', 5)
mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGKILL -r .*-softmodem ocp-enb || true', '\$', 5)
time.sleep(5)
mySSH.command('rm -f my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
mySSH.close()
# If tracer options is on, stopping tshark on EPC side
result = re.search('T_stdout', str(self.Initialize_eNB_args))
if (result is not None) and (self.epcObj is not None):
localEpcIpAddr = self.epcObj.GetIPAddress()
localEpcUserName = self.epcObj.GetUserName()
localEpcPassword = self.epcObj.GetPassword()
localEpcIpAddr = self.epcObj.IPAddress
localEpcUserName = self.epcObj.UserName
localEpcPassword = self.epcObj.Password
mySSH.open(localEpcIpAddr, localEpcUserName, localEpcPassword)
logging.debug('\u001B[1m Stopping tshark \u001B[0m')
mySSH.command('echo ' + localEpcPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5)
@@ -752,7 +627,7 @@ class RANManagement():
if (copyin_res == -1):
logging.debug('\u001B[1;37;41m Could not copy ' + nodeB_prefix + 'NB logfile to analyze it! \u001B[0m')
if self.htmlObj is not None:
self.htmlObj.SetHmleNBFailureMsg('Could not copy ' + nodeB_prefix + 'NB logfile to analyze it!')
self.htmlObj.htmleNBFailureMsg='Could not copy ' + nodeB_prefix + 'NB logfile to analyze it!'
self.htmlObj.CreateHtmlTestRow('N/A', 'KO', CONST.ENB_PROCESS_NOLOGFILE_TO_ANALYZE)
self.eNBmbmsEnables[int(self.eNB_instance)] = False
return
@@ -823,7 +698,30 @@ class RANManagement():
X2HO_inNbProcedures = 0
X2HO_outNbProcedures = 0
global_status = CONST.ALL_PROCESSES_OK
# Runtime statistics
runTime = ''
userTime = ''
systemTime = ''
maxPhyMemUsage = ''
nbContextSwitches = ''
for line in enb_log_file.readlines():
# Runtime statistics
result = re.search('Run time:' ,str(line))
if result is not None:
runTime = str(line).strip()
if runTime != '':
result = re.search('Time executing user inst', str(line))
if result is not None:
userTime = 'to be decoded - 1'
result = re.search('Time executing system inst', str(line))
if result is not None:
systemTime = 'to be decoded - 2'
result = re.search('Max. Phy. memory usage:', str(line))
if result is not None:
maxPhyMemUsage = 'to be decoded - 3'
result = re.search('Number of context switch.*process origin', str(line))
if result is not None:
nbContextSwitches = 'to be decoded - 4'
if X2HO_state == CONST.X2_HO_REQ_STATE__IDLE:
result = re.search('target eNB Receives X2 HO Req X2AP_HANDOVER_REQ', str(line))
if result is not None:
@@ -896,8 +794,7 @@ class RANManagement():
if result is not None:
rrcSetupComplete += 1
result = re.search('Generate LTE_RRCConnectionRelease|Generate RRCConnectionRelease', str(line))
if result is not None:
rrcReleaseRequest += 1
if result is not None: rrcReleaseRequest += 1
result = re.search('Generate LTE_RRCConnectionReconfiguration', str(line))
if result is not None:
rrcReconfigRequest += 1
@@ -955,11 +852,11 @@ class RANManagement():
mbmsRequestMsg += 1
enb_log_file.close()
logging.debug(' File analysis completed')
if self.air_interface == 'lte':
if (self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb'):
nodeB_prefix = 'e'
else:
nodeB_prefix = 'g'
if self.air_interface == 'nr':
if self.air_interface[self.eNB_instance] == 'nr-softmodem':
if ulschReceiveOK > 0:
statMsg = nodeB_prefix + 'NB showed ' + str(ulschReceiveOK) + ' "ULSCH received ok" message(s)'
logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
@@ -1080,5 +977,12 @@ class RANManagement():
htmleNBFailureMsg += rlcMsg + '\n'
global_status = CONST.ENB_PROCESS_REALTIME_ISSUE
if self.htmlObj is not None:
self.htmlObj.SetHmleNBFailureMsg(htmleNBFailureMsg)
self.htmlObj.htmleNBFailureMsg=htmleNBFailureMsg
# Runtime statistics
if runTime != '':
logging.debug(runTime)
logging.debug('Time executing user inst : ' + userTime)
logging.debug('Time executing system inst : ' + systemTime)
logging.debug('Max Physical Memory Usage : ' + maxPhyMemUsage)
logging.debug('Nb Context Switches : ' + nbContextSwitches)
return global_status
+12
View File
@@ -101,6 +101,18 @@ class SSHConnection():
else:
sys.exit('SSH Connection Failed')
def cde_check_value(self, commandline, expected, timeout):
logging.debug(commandline)
self.ssh.timeout = timeout
self.ssh.sendline(commandline)
expected.append(pexpect.EOF)
expected.append(pexpect.TIMEOUT)
self.sshresponse = self.ssh.expect(expected)
return self.sshresponse
def command(self, commandline, expectedline, timeout):
logging.debug(commandline)
self.ssh.timeout = timeout
+35
View File
@@ -0,0 +1,35 @@
- COTS_UE_Airplane
- Build_PhySim
- Run_PhySim
- Build_eNB
- WaitEndBuild_eNB
- Initialize_eNB
- Terminate_eNB
- Initialize_UE
- Terminate_UE
- Attach_UE
- Detach_UE
- Build_OAI_UE
- Initialize_OAI_UE
- Terminate_OAI_UE
- DataDisable_UE
- DataEnable_UE
- CheckStatusUE
- Ping
- Iperf
- Reboot_UE
- Initialize_FlexranCtrl
- Terminate_FlexranCtrl
- Initialize_HSS
- Terminate_HSS
- Initialize_MME
- Terminate_MME
- Initialize_SPGW
- Terminate_SPGW
- Initialize_CatM_module
- Terminate_CatM_module
- Attach_CatM_module
- Detach_CatM_module
- Ping_CatM_module
- IdleSleep
- Perform_X2_Handover
@@ -0,0 +1,147 @@
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>test-05-tm1</htmlTabRef>
<htmlTabName>Test-05MHz-TM1</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>4</repeatCount>
<TestCaseRequestedList>
030201
040101
030101 040301 040501 040603 040604 040605 040606 040607 040641 040642 040643 040644 040401 040201 030201
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="030101">
<class>Initialize_eNB</class>
<desc>Initialize OCP-eNB (FDD/Band7/5MHz)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf</Initialize_eNB_args>
<air_interface>ocp</air_interface>
</testCase>
<testCase id="030201">
<class>Terminate_eNB</class>
<desc>Terminate OCP-eNB</desc>
<air_interface>ocp</air_interface>
</testCase>
<testCase id="040101">
<class>Initialize_UE</class>
<desc>Initialize UE</desc>
</testCase>
<testCase id="040201">
<class>Terminate_UE</class>
<desc>Terminate UE</desc>
</testCase>
<testCase id="040301">
<class>Attach_UE</class>
<desc>Attach UE</desc>
</testCase>
<testCase id="040401">
<class>Detach_UE</class>
<desc>Detach UE</desc>
</testCase>
<testCase id="040501">
<class>Ping</class>
<desc>ping (5MHz - 20 sec)</desc>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="040603">
<class>Iperf</class>
<desc>iperf (5MHz - DL/15Mbps/UDP)(30 sec)(balanced profile)</desc>
<iperf_args>-u -b 15M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040604">
<class>Iperf</class>
<desc>iperf (5MHz - DL/15Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 15M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040605">
<class>Iperf</class>
<desc>iperf (5MHz - DL/15Mbps/UDP)(30 sec)(unbalanced profile)</desc>
<iperf_args>-u -b 15M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>unbalanced</iperf_profile>
</testCase>
<testCase id="040606">
<class>Iperf</class>
<desc>iperf (5MHz - DL/TCP)(30 sec)(single-ue profile)</desc>
<iperf_args>-t 30 -i 1 -fm</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040607">
<class>Iperf</class>
<desc>iperf (5MHz - DL/TCP)(30 sec)(balanced profile)</desc>
<iperf_args>-t 30 -i 1 -fm</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040641">
<class>Iperf</class>
<desc>iperf (5MHz - UL/9Mbps/UDP)(30 sec)(balanced profile)</desc>
<iperf_args>-u -b 9M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040642">
<class>Iperf</class>
<desc>iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 9M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040643">
<class>Iperf</class>
<desc>iperf (5MHz - UL/TCP)(30 sec)(single-ue profile)</desc>
<iperf_args>-t 30 -i 1 -fm -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040644">
<class>Iperf</class>
<desc>iperf (5MHz - UL/TCP)(30 sec)(balanced profile)</desc>
<iperf_args>-t 30 -i 1 -fm -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
</testCaseList>
@@ -0,0 +1,38 @@
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>build-tab</htmlTabRef>
<htmlTabName>Build</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
010101
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="010101">
<class>Build_eNB</class>
<desc>Build eNB OCP (USRP)</desc>
<Build_eNB_args>-w USRP -c --eNBocp --ninja</Build_eNB_args>
</testCase>
</testCaseList>
@@ -0,0 +1,66 @@
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>build-tab</htmlTabRef>
<htmlTabName>Build</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
000001 000002
000003 000004
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="000001">
<class>Build_eNB</class>
<desc>Build eNB</desc>
<Build_eNB_args>-w USRP -c --eNB --ninja</Build_eNB_args>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<backgroundBuild>True</backgroundBuild>
</testCase>
<testCase id="000004">
<class>WaitEndBuild_eNB</class>
<desc>Wait for end of Build eNB</desc>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000002">
<class>Build_eNB</class>
<desc>Build gNB</desc>
<Build_eNB_args>-w USRP -c --gNB --ninja</Build_eNB_args>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
<backgroundBuild>True</backgroundBuild>
</testCase>
<testCase id="000003">
<class>WaitEndBuild_eNB</class>
<desc>Wait for end of Build gNB</desc>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
</testCase>
</testCaseList>
@@ -0,0 +1,50 @@
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>test-fr1-tm1</htmlTabRef>
<htmlTabName>Test-FR1-TM1</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
070001
070000
</TestCaseRequestedList>
<TestCaseExclusionList>
</TestCaseExclusionList>
<testCase id="070000">
<class>Terminate_eNB</class>
<desc>Terminate eNB</desc>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="070001">
<class>Terminate_eNB</class>
<desc>Terminate gNB</desc>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
</testCase>
</testCaseList>
@@ -0,0 +1,77 @@
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>test-fr1-tm1</htmlTabRef>
<htmlTabName>Test-FR1-TM1</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
030000
040000
000001
070001
070000
</TestCaseRequestedList>
<TestCaseExclusionList>
</TestCaseExclusionList>
<testCase id="030000">
<class>Initialize_eNB</class>
<desc>Initialize eNB</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf</Initialize_eNB_args>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<air_interface>lte</air_interface>
</testCase>
<testCase id="040000">
<class>Initialize_eNB</class>
<desc>Initialize gNB (3/4 sampling rate)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf -E</Initialize_eNB_args>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
<air_interface>nr</air_interface>
</testCase>
<testCase id="000001">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>30</idle_sleep_time_in_sec>
</testCase>
<testCase id="070000">
<class>Terminate_eNB</class>
<desc>Terminate eNB</desc>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="070001">
<class>Terminate_eNB</class>
<desc>Terminate gNB</desc>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
</testCase>
</testCaseList>
@@ -0,0 +1,39 @@
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>test-airplane-mode</htmlTabRef>
<htmlTabName>AirplaneToggle</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<TestCaseRequestedList>
010000
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="010000">
<class>COTS_UE_Airplane</class>
<desc>Toggle COTS Airplane mode ON</desc>
<cots_ue_airplane_args>ON</cots_ue_airplane_args>
</testCase>
</testCaseList>
+1 -1
View File
@@ -34,7 +34,7 @@
<mode>TesteNB</mode>
<class>Build_eNB</class>
<desc>Build gNB (USRP)</desc>
<Build_eNB_args>--gNB -w USRP</Build_eNB_args>
<Build_eNB_args>--gNB -w USRP --ninja</Build_eNB_args>
<forced_workspace_cleanup>True</forced_workspace_cleanup>
</testCase>
+1 -1
View File
@@ -34,7 +34,7 @@
<mode>TestUE</mode>
<class>Build_OAI_UE</class>
<desc>Build NR UE (USRP)</desc>
<Build_OAI_UE_args>--nrUE -w USRP</Build_OAI_UE_args>
<Build_OAI_UE_args>--nrUE -w USRP --ninja</Build_OAI_UE_args>
<clean_repository>false</clean_repository>
</testCase>
+57 -20
View File
@@ -27,6 +27,10 @@ cmake_minimum_required (VERSION 3.0)
# Base directories, compatible with legacy OAI building #
#########################################################
set (OPENAIR_DIR $ENV{OPENAIR_DIR})
if("${OPENAIR_DIR}" STREQUAL "")
string(REGEX REPLACE "/cmake_targets.*$" "" OPENAIR_DIR ${CMAKE_CURRENT_BINARY_DIR})
endif()
set (NFAPI_DIR ${OPENAIR_DIR}/nfapi/open-nFAPI)
set (NFAPI_USER_DIR ${OPENAIR_DIR}/nfapi/oai_integration)
set (OPENAIR1_DIR ${OPENAIR_DIR}/openair1)
@@ -1252,7 +1256,7 @@ set(SCHED_SRC_NR_UE
${OPENAIR1_DIR}/SCHED_NR_UE/phy_procedures_nr_ue.c
${OPENAIR1_DIR}/SCHED_NR/phy_procedures_nr_common.c
${OPENAIR1_DIR}/SCHED_NR_UE/fapi_nr_ue_l1.c
${OPENAIR1_DIR}/SCHED_NR/phy_frame_config_nr.c
${OPENAIR1_DIR}/SCHED_NR_UE/phy_frame_config_nr_ue.c
${OPENAIR1_DIR}/SCHED_NR_UE/harq_nr.c
${OPENAIR1_DIR}/SCHED_NR_UE/pucch_uci_ue_nr.c
${OPENAIR1_DIR}/SCHED_NR_UE/pucch_power_control_ue_nr.c
@@ -1740,9 +1744,15 @@ set(NR_RLC_SRC
${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_sdu.c
${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_ue_manager.c
)
set(NR_PDCP_SRC
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c
)
set(L2_SRC
${OPENAIR2_DIR}/LAYER2/openair2_proc.c
${PDCP_DIR}/pdcp.c
${PDCP_DIR}/pdcp_fifo.c
${PDCP_DIR}/pdcp_sequence_manager.c
@@ -1750,6 +1760,7 @@ set(L2_SRC
${PDCP_DIR}/pdcp_util.c
${PDCP_DIR}/pdcp_security.c
${PDCP_DIR}/pdcp_netlink.c
${OPENAIR2_DIR}/LAYER2/openair2_proc.c
# ${RRC_DIR}/rrc_UE.c
${RRC_DIR}/rrc_eNB.c
${RRC_DIR}/rrc_eNB_endc.c
@@ -1761,6 +1772,20 @@ set(L2_SRC
${RRC_DIR}/L2_interface_common.c
${RRC_DIR}/L2_interface_ue.c
)
set(L2_RRC_SRC
${OPENAIR2_DIR}/LAYER2/openair2_proc.c
# ${RRC_DIR}/rrc_UE.c
${RRC_DIR}/rrc_eNB.c
${RRC_DIR}/rrc_eNB_endc.c
${RRC_DIR}/rrc_eNB_S1AP.c
${RRC_DIR}/rrc_eNB_M2AP.c
${RRC_DIR}/rrc_eNB_UE_context.c
${RRC_DIR}/rrc_common.c
${RRC_DIR}/L2_interface.c
${RRC_DIR}/L2_interface_common.c
${RRC_DIR}/L2_interface_ue.c
)
set(L2_LTE_SRC
${RLC_V2}
@@ -1768,6 +1793,7 @@ set(L2_LTE_SRC
set(L2_NR_SRC
${NR_RLC_SRC}
${NR_PDCP_SRC}
${NR_RRC_DIR}/rrc_gNB.c
${NR_RRC_DIR}/nr_rrc_common.c
${NR_RRC_DIR}/L2_nr_interface.c
@@ -1792,19 +1818,16 @@ set(L2_SRC_UE
${RRC_DIR}/L2_interface_ue.c
)
set(LTE_NR_L2_SRC_UE
${PDCP_DIR}/pdcp.c
${PDCP_DIR}/pdcp_fifo.c
${PDCP_DIR}/pdcp_sequence_manager.c
${PDCP_DIR}/pdcp_primitives.c
${PDCP_DIR}/pdcp_util.c
${PDCP_DIR}/pdcp_security.c
${PDCP_DIR}/pdcp_netlink.c
${RLC_V2}
)
set(L2_RRC_SRC_UE
${RRC_DIR}/rrc_UE.c
${RRC_DIR}/rrc_common.c
${RRC_DIR}/L2_interface_common.c
${RRC_DIR}/L2_interface_ue.c
)
set(NR_L2_SRC_UE
${NR_RLC_SRC}
${NR_PDCP_SRC}
${NR_UE_RRC_DIR}/L2_interface_ue.c
${NR_UE_RRC_DIR}/main_ue.c
${NR_UE_RRC_DIR}/rrc_UE.c
@@ -1830,6 +1853,7 @@ set (MAC_SRC
${MAC_DIR}/eNB_scheduler_fairRR.c
${MAC_DIR}/eNB_scheduler_phytest.c
${MAC_DIR}/pre_processor.c
${MAC_DIR}/slicing/slicing.c
${MAC_DIR}/config.c
${MAC_DIR}/config_ue.c
)
@@ -1913,6 +1937,14 @@ add_library(L2_NR
${MAC_NR_SRC}
${GNB_APP_SRC}
)
add_library(L2_LTE_NR
${L2_RRC_SRC}
${MAC_SRC}
${ENB_APP_SRC}
${MCE_APP_SRC}
)
add_dependencies(L2_NR rrc_flag nr_rrc_flag s1ap_flag x2_flag)
add_library(L2_UE
@@ -1920,6 +1952,11 @@ add_library(L2_UE
${MAC_SRC_UE}
)
add_library(L2_UE_LTE_NR
${L2_RRC_SRC_UE}
${MAC_SRC_UE}
)
if (NOT ${NOS1})
target_compile_definitions(L2_UE PUBLIC -DPDCP_USE_NETLINK)
endif()
@@ -2473,8 +2510,8 @@ add_library(uescope MODULE ${XFORMS_SOURCE} ${XFORMS_SOURCE_SOFTMODEM} ${XFORMS_
target_link_libraries(enbscope ${XFORMS_LIBRARIES})
target_link_libraries(uescope ${XFORMS_LIBRARIES})
add_library(gnbscope MODULE ${XFORMS_SOURCE_NR})
target_link_libraries(gnbscope ${XFORMS_LIBRARIES})
add_library(nrscope MODULE ${XFORMS_SOURCE_NR})
target_link_libraries(nrscope ${XFORMS_LIBRARIES})
add_library(rfsimulator MODULE
@@ -2623,7 +2660,7 @@ add_executable(ocp-enb
${CONFIG_SOURCES}
${SHLIB_LOADER_SOURCES}
)
add_dependencies(ocp-enb rrc_flag s1ap_flag x2_flag oai_iqplayer)
add_dependencies(ocp-enb rrc_flag s1ap_flag x2_flag oai_iqplayer coding params_libconfig rfsimulator)
target_link_libraries (ocp-enb
-Wl,--start-group
@@ -2730,7 +2767,7 @@ add_executable(nr-softmodem
${OPENAIR_DIR}/common/utils/system.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
${GTPU_need_ITTI}
${XFORMS_SOURCE_NR}
${XFORMSINTERFACE_SOURCE}
${T_SOURCE}
${CONFIG_SOURCES}
${SHLIB_LOADER_SOURCES}
@@ -2740,7 +2777,7 @@ target_link_libraries (nr-softmodem
-Wl,--start-group
UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS NR_GTPV1U SECU_CN SECU_OSA
${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB
S1AP_LIB S1AP_ENB L2 L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB ${PROTO_AGENT_LIB} ${FSPT_MSG_LIB}
-Wl,--end-group z dl)
@@ -2772,7 +2809,7 @@ add_executable(nr-uesoftmodem
${OPENAIR_DIR}/common/utils/utils.c
${OPENAIR_DIR}/common/utils/system.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
${XFORMS_SOURCE_NR}
${XFORMSINTERFACE_SOURCE}
${T_SOURCE}
${UTIL_SRC}
${CONFIG_SOURCES}
@@ -2782,7 +2819,7 @@ add_executable(nr-uesoftmodem
target_link_libraries (nr-uesoftmodem
-Wl,--start-group
RRC_LIB NR_RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB
PHY_COMMON PHY_NR_COMMON PHY_UE PHY_NR_UE PHY_RU LFDS NR_L2_UE L2_UE MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB
PHY_COMMON PHY_NR_COMMON PHY_UE PHY_NR_UE PHY_RU LFDS NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB
NFAPI_USER_LIB S1AP_LIB S1AP_ENB
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES}
-Wl,--end-group z dl)
+16 -6
View File
@@ -67,7 +67,7 @@ UE_TIMING_TRACE="False"
USRP_REC_PLAY="False"
BUILD_ECLIPSE=0
NR="False"
OPTIONAL_LIBRARIES="telnetsrv enbscope uescope msc"
OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope msc"
trap handle_ctrl_c INT
function print_help() {
@@ -96,7 +96,9 @@ Options
enable cmake debugging messages
--eNB
Makes the LTE softmodem
--gNB
--eNBocp
Makes the OCP LTE softmodem
-gNB
Makes the NR softmodem
--nrUE
Makes the NR UE softmodem
@@ -237,7 +239,11 @@ function main() {
eNB=1
echo_info "Will compile eNB"
shift;;
--gNB)
--eNBocp)
eNBocp=1
echo_info "Will compile OCP eNB"
shift;;
--gNB)
gNB=1
NR="True"
echo_info "Will compile gNB"
@@ -443,7 +449,7 @@ function main() {
########################################################
# to be discussed
if [ "$eNB" = "1" -o "$gNB" = "1" ] ; then
if [ "$eNB" = "1" -o "$eNBocp" = "1" -o "$gNB" = "1" ] ; then
if [ "$HW" = "None" -a "$TP" = "None" ] ; then
echo_info "No local radio head and no transport protocol selected"
fi
@@ -574,12 +580,13 @@ function main() {
config_libconfig_shlib=params_libconfig
# first generate the CMakefile in the right directory
if [ "$eNB" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$nrUE" = "1" -o "$HW" = "EXMIMO" ] ; then
if [ "$eNB" = "1" -o "$eNBocp" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$nrUE" = "1" -o "$HW" = "EXMIMO" ] ; then
# softmodem compilation
cmake_file=$DIR/$build_dir/CMakeLists.txt
echo "cmake_minimum_required(VERSION 2.8)" > $cmake_file
echo "project (OpenAirInterface)" >> $cmake_file
echo "set ( CMAKE_BUILD_TYPE $CMAKE_BUILD_TYPE )" >> $cmake_file
echo "set ( CFLAGS_PROCESSOR_USER \"$CFLAGS_PROCESSOR_USER\" )" >> $cmake_file
echo "set ( UE_EXPANSION $UE_EXPANSION )" >> $cmake_file
@@ -606,6 +613,9 @@ function main() {
if [ "$eNB" = "1" ] ; then
execlist="$execlist lte-softmodem"
fi
if [ "$eNBocp" = "1" ] ; then
execlist="$execlist ocp-enb"
fi
if [ "$gNB" = "1" ] ; then
execlist="$execlist nr-softmodem"
fi
@@ -821,7 +831,7 @@ function main() {
####################################################
# Build RF device and transport protocol libraries #
####################################################
if [ "$eNB" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$nrUE" = "1" -o "$HWLAT" = "1" ] ; then
if [ "$eNB" = "1" -o "$eNBocp" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$nrUE" = "1" -o "$HWLAT" = "1" ] ; then
# build RF device libraries
if [ "$HW" != "None" ] ; then
@@ -80,7 +80,7 @@ task_list_t tasks[TASK_MAX];
void *itti_malloc(task_id_t origin_task_id, task_id_t destination_task_id, ssize_t size) {
void *ptr = NULL;
AssertFatal ((ptr=malloc (size)) != NULL, "Memory allocation of %zu bytes failed (%d -> %d)!\n",
AssertFatal ((ptr=calloc (size, 1)) != NULL, "Memory allocation of %zu bytes failed (%d -> %d)!\n",
size, origin_task_id, destination_task_id);
return ptr;
}
+35 -4
View File
@@ -53,6 +53,7 @@
#include <sys/resource.h>
#include "common/utils/load_module_shlib.h"
#include "common/config/config_userapi.h"
#include "common/utils/threadPool/thread-pool.h"
#include "executables/softmodem-common.h"
#include <readline/history.h>
@@ -507,12 +508,22 @@ int process_command(char *buf) {
}
rt= CMDSTATUS_FOUND;
} else if (strncasecmp(cmd,"get",3) == 0 || strncasecmp(cmd,"set",3) == 0) {
} else if (strcasecmp(cmd,"get") == 0 || strcasecmp(cmd,"set") == 0) {
rt= setgetvar(i,cmd[0],cmdb);
} else {
for (k=0 ; telnetparams.CmdParsers[i].cmd[k].cmdfunc != NULL ; k++) {
if (strncasecmp(cmd, telnetparams.CmdParsers[i].cmd[k].cmdname,sizeof(telnetparams.CmdParsers[i].cmd[k].cmdname)) == 0) {
telnetparams.CmdParsers[i].cmd[k].cmdfunc(cmdb, telnetparams.telnetdbg, client_printf);
if (telnetparams.CmdParsers[i].cmd[k].qptr != NULL) {
notifiedFIFO_elt_t *msg =newNotifiedFIFO_elt(sizeof(telnetsrv_qmsg_t),0,NULL,NULL);
telnetsrv_qmsg_t *cmddata=NotifiedFifoData(msg);
cmddata->cmdfunc=(qcmdfunc_t)telnetparams.CmdParsers[i].cmd[k].cmdfunc;
cmddata->prnt=client_printf;
cmddata->debug=telnetparams.telnetdbg;
cmddata->cmdbuff=strdup(cmdb);
pushNotifiedFIFO(telnetparams.CmdParsers[i].cmd[k].qptr, msg);
} else {
telnetparams.CmdParsers[i].cmd[k].cmdfunc(cmdb, telnetparams.telnetdbg, client_printf);
}
rt= CMDSTATUS_FOUND;
}
} /* for k */
@@ -673,6 +684,16 @@ void run_telnetsrv(void) {
return;
}
void poll_telnetcmdq(void *qid, void *arg) {
notifiedFIFO_elt_t *msg = pollNotifiedFIFO((notifiedFIFO_t *)qid);
if (msg != NULL) {
telnetsrv_qmsg_t *msgdata=NotifiedFifoData(msg);
msgdata->cmdfunc(msgdata->cmdbuff,msgdata->debug,msgdata->prnt,arg);
free(msgdata->cmdbuff);
delNotifiedFIFO_elt(msg);
}
}
/*------------------------------------------------------------------------------------------------*/
/* load the commands delivered with the telnet server
*
@@ -758,6 +779,7 @@ int telnetsrv_autoinit(void) {
*/
int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd) {
int i;
notifiedFIFO_t *afifo=NULL;
if( modulename == NULL || var == NULL || cmd == NULL) {
fprintf(stderr,"[TELNETSRV] Telnet server, add_telnetcmd: invalid parameters\n");
@@ -769,6 +791,13 @@ int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmdde
strncpy(telnetparams.CmdParsers[i].module,modulename,sizeof(telnetparams.CmdParsers[i].module)-1);
telnetparams.CmdParsers[i].cmd = cmd;
telnetparams.CmdParsers[i].var = var;
if (cmd->cmdflags & TELNETSRV_CMDFLAG_PUSHINTPOOLQ) {
if (afifo == NULL) {
afifo = malloc(sizeof(notifiedFIFO_t));
initNotifiedFIFO(afifo);
}
cmd->qptr = afifo;
}
printf("[TELNETSRV] Telnet server: module %i = %s added to shell\n",
i,telnetparams.CmdParsers[i].module);
break;
@@ -797,8 +826,10 @@ int telnetsrv_checkbuildver(char *mainexec_buildversion, char **shlib_buildvers
}
int telnetsrv_getfarray(loader_shlibfunc_t **farray) {
*farray=malloc(sizeof(loader_shlibfunc_t));
*farray=malloc(sizeof(loader_shlibfunc_t)*2);
(*farray)[0].fname=TELNET_ADDCMD_FNAME;
(*farray)[0].fptr=(int (*)(void) )add_telnetcmd;
return 1;
(*farray)[1].fname=TELNET_POLLCMDQ_FNAME;
(*farray)[1].fptr=(int (*)(void) )poll_telnetcmdq;
return ( 2);
}
+15 -3
View File
@@ -53,13 +53,26 @@
/* to add a set of new command to the telnet server shell */
typedef void(*telnet_printfunc_t)(const char* format, ...);
typedef int(*cmdfunc_t)(char*, int, telnet_printfunc_t prnt);
typedef int(*qcmdfunc_t)(char*, int, telnet_printfunc_t prnt,void *arg);
#define TELNETSRV_CMDFLAG_PUSHINTPOOLQ (1<<0) // ask the telnet server to push the command in a thread pool queue
typedef struct cmddef {
char cmdname[TELNET_CMD_MAXSIZE];
char helpstr[TELNET_HELPSTR_SIZE];
cmdfunc_t cmdfunc;
unsigned int cmdflags;
void *qptr;
} telnetshell_cmddef_t;
/*----------------------------------------------------------------------------*/
/* structure used to send a command via a message queue to enable */
/* executing a command in a thread different from the telnet server thread */
typedef struct telnetsrv_qmsg {
qcmdfunc_t cmdfunc;
telnet_printfunc_t prnt;
int debug;
char *cmdbuff;
} telnetsrv_qmsg_t;
/*----------------------------------------------------------------------------*/
/*structure to be used when adding a module to the telnet server */
/* This is the first parameter of the add_telnetcmd function, which can be used */
@@ -111,9 +124,6 @@ typedef struct {
} telnetsrv_params_t;
typedef int(*addcmdfunc_t)(char*, telnetshell_vardef_t*, telnetshell_cmddef_t*);
typedef void(*settelnetmodule_t)(char *name, void *ptr);
/*-------------------------------------------------------------------------------------------*/
@@ -133,7 +143,9 @@ VT escape sequence definition, for smarter display....
/*---------------------------------------------------------------------------------------------*/
#define TELNET_ADDCMD_FNAME "add_telnetcmd"
#define TELNET_POLLCMDQ_FNAME "poll_telnetcmdq"
typedef int(*add_telnetcmd_func_t)(char *, telnetshell_vardef_t *, telnetshell_cmddef_t *);
typedef void(*poll_telnetcmdq_func_t)(void *qid,void *arg);
#ifdef TELNETSERVERCODE
int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd);
void set_sched(pthread_t tid, int pid,int priority);
+3 -2
View File
@@ -111,9 +111,10 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) {
pool->activated=true;
initNotifiedFIFO(&pool->incomingFifo);
char *saveptr, * curptr;
char *parms_cpy=strdup(params);
pool->nbThreads=0;
pool->restrictRNTI=false;
curptr=strtok_r(params,",",&saveptr);
curptr=strtok_r(parms_cpy,",",&saveptr);
struct one_thread * ptr;
while ( curptr!=NULL ) {
int c=toupper(curptr[0]);
@@ -145,7 +146,7 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) {
curptr=strtok_r(NULL,",",&saveptr);
}
free(parms_cpy);
if (pool->activated && pool->nbThreads==0) {
printf("No servers created in the thread pool, exit\n");
exit(1);
+19 -24
View File
@@ -1,4 +1,5 @@
STATUS 2020/06/26 : information is up to date, but under continuous improvement
STATUS 2020/07/30 : under continuous improvement ; updated the configuration files links with CI approved reference files
## Table of Contents ##
@@ -78,17 +79,17 @@ https://github.com/OPENAIRINTERFACE/openair-epc-fed/blob/master-documentation/do
Each component (EPC, eNB, gNB) has its own configuration file.
These config files are passed as arguments of the run command line, using the option -O \<conf file\>
Some config examples can be found in the following folder:
https://gitlab.eurecom.fr/oai/openairinterface5g/-/tree/develop/targets/PROJECTS/GENERIC-LTE-EPC/CONF
Also base config files can be found here:
[enb conf file](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/rh_doc_update_3/doc/testing_gnb_w_cots_ue_resources/enb.conf)
[gnb conf file](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/rh_doc_update_3/doc/testing_gnb_w_cots_ue_resources/gnb.conf)
TO DO : attach base confif files
The **REFERENCE** files for eNB and gNB, **used by the CI**, can be found here:
[enb conf file](../ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf)
[gnb conf file](../ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf)
These files have to be updated manually to set the IP addresses and frequency.
**ATTENTION** : an **EXTERNAL** clock is used to sync the eNB and gNB,
whether the clock is internal or external is defined in the configuration files (!! details needed !!)
1- In the **eNB configuration file** :
- look for MME IP address, and update the **ipv4 field** with the IP address of the **EPC** server
```
@@ -128,7 +129,7 @@ These files have to be updated manually to set the IP addresses and frequency.
}
);
```
- look for X2 IP address, and update the **4 fields** with the IP address of the **eNB** server (notice : even if -in principle- S1 MME is not required for gNB setting)
- look for X2 IP address, and update the **4 fields** with the IP address of the **eNB** server / **gNB** server as below (notice : even if -in principle- S1 MME is not required for gNB setting)
```
///X2
@@ -146,11 +147,11 @@ These files have to be updated manually to set the IP addresses and frequency.
{
GNB_INTERFACE_NAME_FOR_S1_MME = "eth0";
GNB_IPV4_ADDRESS_FOR_S1_MME = "**YOUR_ENB_IP_ADDR**";
GNB_IPV4_ADDRESS_FOR_S1_MME = "**YOUR_GNB_IP_ADDR**";
GNB_INTERFACE_NAME_FOR_S1U = "eth0";
GNB_IPV4_ADDRESS_FOR_S1U = "**YOUR_ENB_IP_ADDR**";
GNB_IPV4_ADDRESS_FOR_S1U = "**YOUR_GNB_IP_ADDR**";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
GNB_IPV4_ADDRESS_FOR_X2C = "**YOUR_ENB_IP_ADDR**";
GNB_IPV4_ADDRESS_FOR_X2C = "**YOUR_GNB_IP_ADDR**";
GNB_PORT_FOR_X2C = 36422; # Spec 36422
};
@@ -215,26 +216,20 @@ Execute:
```
For example:
```
~/openairinterface5g/cmake_targets/ran_build/build$ sudo ./lte-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf | tee mylogfile.log
```
- **gNB** (on the gNB host)
Execute:
```
~/openairinterface5g/cmake_targets/ran_build/build$ sudo ./nr-softmodem -O **YOUR_GNB_CONF_FILE** | tee **YOUR_LOG_FILE**
~/openairinterface5g/cmake_targets/ran_build/build$ sudo ./nr-softmodem -O **YOUR_GNB_CONF_FILE** -E | tee **YOUR_LOG_FILE**
```
For example:
```
~/openairinterface5g/cmake_targets/ran_build/build$ sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf | tee mylogfile.log
```
**ATTENTION** : for the gNB execution,
The -E option is required to enable the tri-quarter sampling rate when using a B2xx serie USRP
The -E opton is not needed when using a a N300 USRP
## Test Case
+1 -1
View File
@@ -401,7 +401,7 @@ void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_
hULUE(newUDPheader)->O_ACK=eNB->ulsch[UE_id]->harq_processes[harq_pid]->O_ACK;
memcpy(hULUE(newUDPheader)->o_ACK, eNB->ulsch[UE_id]->harq_processes[harq_pid]->o_ACK,
sizeof(eNB->ulsch[UE_id]->harq_processes[harq_pid]->o_ACK));
hULUE(newUDPheader)->ta=lte_est_timing_advance_pusch(eNB, UE_id);
hULUE(newUDPheader)->ta=lte_est_timing_advance_pusch(&eNB->frame_parms, eNB->pusch_vars[UE_id]->drs_ch_estimates_time);
hULUE(newUDPheader)->segment=segmentID;
memcpy(hULUE(newUDPheader)->o, eNB->ulsch[UE_id]->harq_processes[harq_pid]->o,
sizeof(eNB->ulsch[UE_id]->harq_processes[harq_pid]->o));
+2 -4
View File
@@ -1123,9 +1123,6 @@ int restart_L1L2(module_id_t enb_id) {
sync_var = -1;
pthread_mutex_unlock(&sync_mutex);
RC.ru_mask |= (1 << ru->idx);
/* copy the changed frame parameters to the RU */
/* TODO this should be done for all RUs associated to this eNB */
memcpy(&ru->frame_parms, &RC.eNB[enb_id][0]->frame_parms, sizeof(LTE_DL_FRAME_PARMS));
/* reset the list of connected UEs in the MAC, since in this process with
* loose all UEs (have to reconnect) */
init_UE_info(&RC.mac[enb_id]->UE_info);
@@ -1167,6 +1164,7 @@ int main ( int argc, char **argv ) {
T_Config_Init();
#endif
configure_linux();
set_softmodem_sighandler();
cpuf=get_cpu_freq_GHz();
set_taus_seed (0);
@@ -1347,7 +1345,7 @@ int main ( int argc, char **argv ) {
// end of CI modifications
//getchar();
if(IS_SOFTMODEM_DOFORMS)
load_softscope("enb");
load_softscope("enb", NULL);
itti_wait_tasks_end();
oai_exit=1;
+8 -9
View File
@@ -75,7 +75,7 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "system.h"
#include <openair2/GNB_APP/gnb_app.h>
#include "PHY/TOOLS/phy_scope_interface.h"
#include "PHY/TOOLS/nr_phy_scope.h"
#include "stats.h"
#include "nr-softmodem.h"
@@ -156,7 +156,6 @@ char channels[128] = "0";
int rx_input_level_dBm;
uint32_t do_forms=0;
int otg_enabled;
//int number_of_cards = 1;
@@ -454,7 +453,11 @@ static void get_options(void) {
paramdef_t cmdline_params[] = CMDLINE_PARAMS_DESC_GNB ;
CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP);
get_common_options(SOFTMODEM_GNB_BIT );
config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL);
CONFIG_CLEARRTFLAG(CONFIG_NOEXITONHELP);
@@ -723,9 +726,6 @@ int restart_L1L2(module_id_t gnb_id) {
RC.ru_mask |= (1 << ru->idx);
/* copy the changed frame parameters to the RU */
/* TODO this should be done for all RUs associated to this gNB */
memcpy(&ru->nr_frame_parms, &RC.gNB[gnb_id]->frame_parms, sizeof(NR_DL_FRAME_PARMS));
set_function_spec_param(RC.ru[gnb_id]);
LOG_I(GNB_APP, "attempting to create ITTI tasks\n");
// No more rrc thread, as many race conditions are hidden behind
@@ -817,7 +817,6 @@ int main( int argc, char **argv )
configure_linux();
printf("Reading in command-line options\n");
get_options ();
get_common_options(SOFTMODEM_GNB_BIT );
if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) {
fprintf(stderr,"Getting configuration failed\n");
@@ -959,14 +958,14 @@ if(!IS_SOFTMODEM_NOS1)
printf("RC.nb_RU:%d\n", RC.nb_RU);
// once all RUs are ready initialize the rest of the gNBs ((dependence on final RU parameters after configuration)
printf("ALL RUs ready - init gNBs\n");
if (do_forms==1) {
if(IS_SOFTMODEM_DOFORMS) {
scopeParms_t p;
p.argc=&argc;
p.argv=argv;
p.gNB=RC.gNB[0];
p.ru=RC.ru[0];
gNBinitScope(&p);
load_softscope("nr",&p);
}
if (nfapi_mode != 1 && nfapi_mode != 2) {
-9
View File
@@ -19,21 +19,12 @@
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define CMDLINE_PARAMS_DESC_GNB { \
{"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \
{"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&wait_for_sync, defintval:0, TYPE_INT, 0}, \
{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \
{"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \
{"C" , CONFIG_HLP_DLF, 0, u64ptr:&(downlink_frequency[0][0]), defuintval:DEFAULT_DLF, TYPE_UINT64, 0}, \
{"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \
{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, i8ptr:&threequarter_fs, defintval:0, TYPE_INT8, 0}, \
{"K" , CONFIG_HLP_ITTIL, PARAMFLAG_NOFREE, strptr:&itti_dump_file, defstrval:"/tmp/itti.dump", TYPE_STRING, 0}, \
{"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \
{"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \
{"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&numerology, defintval:0, TYPE_INT, 0}, \
{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \
{"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)&parallel_config, defstrval:NULL, TYPE_STRING, 0}, \
{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \
{"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \
{"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \
}
+1 -11
View File
@@ -35,9 +35,7 @@
#include "NR_MAC_UE/mac_proto.h"
#include "RRC/NR_UE/rrc_proto.h"
//#ifndef NO_RAT_NR
#include "SCHED_NR/phy_frame_config_nr.h"
//#endif
#include "SCHED_NR_UE/phy_frame_config_nr.h"
#include "SCHED_NR_UE/defs.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
@@ -366,8 +364,6 @@ static void UE_synch(void *arg) {
}
void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
fapi_nr_config_request_t *cfg = &UE->nrUE_config;
int tx_slot_type = nr_ue_slot_select(cfg, proc->frame_tx, proc->nr_tti_tx);
uint8_t gNB_id = 0;
@@ -577,12 +573,6 @@ void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
int computeSamplesShift(PHY_VARS_NR_UE *UE) {
if (IS_SOFTMODEM_RFSIM) {
LOG_D(PHY,"SET rx_offset %d \n",UE->rx_offset);
//UE->rx_offset_diff=0;
return 0;
}
// compute TO compensation that should be applied for this frame
if ( UE->rx_offset < UE->frame_parms.samples_per_frame/2 &&
UE->rx_offset > 0 ) {
+9 -10
View File
@@ -76,12 +76,12 @@ unsigned short config_frames[4] = {2,9,11,13};
#include <openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h>
#include <openair1/SCHED_NR_UE/fapi_nr_ue_l1.h>
/* Callbacks, globals and object handlers */
//#include "stats.h"
// current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0)
#include "PHY/TOOLS/phy_scope_interface.h"
#include "PHY/TOOLS/nr_phy_scope.h"
// at eNB 0, an UL scope for every UE
//FD_lte_phy_scope_enb *form_enb[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
#include <executables/nr-uesoftmodem.h>
#include "executables/softmodem-common.h"
#include "executables/thread-common.h"
@@ -151,14 +151,11 @@ char ref[128] = "internal";
char channels[128] = "0";
static char *parallel_config = NULL;
static char *worker_config = NULL;
int rx_input_level_dBm;
//static int online_log_messages=0;
uint32_t do_forms=0;
int otg_enabled;
//int number_of_cards = 1;
@@ -590,7 +587,7 @@ void init_pdcp(void) {
LOG_I(RLC, "Problem at RLC initiation \n");
}
pdcp_layer_init();
nr_ip_over_LTE_DRB_preconfiguration();*/
nr_DRB_preconfiguration();*/
pdcp_module_init(pdcp_initmask);
pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req);
pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind);
@@ -763,8 +760,10 @@ int main( int argc, char **argv ) {
memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs);
configure_linux();
mlockall(MCL_CURRENT | MCL_FUTURE);
if (do_forms)
nrUEinitScope(PHY_vars_UE_g[0][0]);
if(IS_SOFTMODEM_DOFORMS) {
load_softscope("nr",PHY_vars_UE_g[0][0]);
}
number_of_cards = 1;
for(int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-8
View File
@@ -61,19 +61,11 @@
{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \
{"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
{"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \
{"C" , CONFIG_HLP_DLF, 0, u64ptr:&(downlink_frequency[0][0]), defuintval:0,TYPE_UINT64, 0}, \
{"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:&do_forms, defintval:0, TYPE_INT, 0}, \
{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, iptr:&threequarter_fs, defintval:0, TYPE_INT, 0}, \
{"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \
{"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \
{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \
{"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&vcdflag, defintval:0, TYPE_INT, 0}, \
{"numerology" , CONFIG_HLP_NUMEROLOGY, 0, iptr:&numerology, defintval:0, TYPE_INT, 0}, \
{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \
{"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)&parallel_config, defstrval:NULL, TYPE_STRING, 0}, \
{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \
{"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0}, \
{"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, iptr:&UE_no_timing_correction, defintval:0, TYPE_INT, 0}, \
+2
View File
@@ -28,6 +28,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <openair1/PHY/defs_eNB.h>
#include <common/utils/telnetsrv/telnetsrv_proccmd.h>
#define CU_PORT "7878"
#define DU_PORT "8787"
@@ -325,5 +326,6 @@ 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);
void softmodem_printresources(int sig, telnet_printfunc_t pf);
extern uint16_t sf_ahead;
#endif
@@ -364,7 +364,7 @@ typedef struct
//table 3-22
typedef struct
{
nfapi_uint8_tlv_t phy_cell_id;//Physical Cell ID, 𝑁_{𝐼𝐷}^{𝑐𝑒𝑙𝑙} [38.211, sec 7.4.2.1] Value: 0 ->1007
nfapi_uint16_tlv_t phy_cell_id;//Physical Cell ID, 𝑁_{𝐼𝐷}^{𝑐𝑒𝑙𝑙} [38.211, sec 7.4.2.1] Value: 0 ->1007
nfapi_uint8_tlv_t frame_duplex_type;//Frame duplex type Value: 0 = FDD 1 = TDD
} nfapi_nr_cell_config_t;
-1
View File
@@ -186,7 +186,6 @@ void phy_free_RU(RU_t *ru) {
int i,j,p;
RU_CALIBRATION *calibration = &ru->calibration;
LOG_I(PHY, "Feeing RU signal buffers (if_south %s) nb_tx %d\n", ru_if_types[ru->if_south], ru->nb_tx);
free_and_zero(ru->frame_parms);
if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so free memory for time-domain signals
for (i = 0; i < ru->nb_tx; i++) free_and_zero(ru->common.txdata[i]);
+2
View File
@@ -509,6 +509,8 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
LOG_I(PHY, "Initialise nr transport\n");
uint16_t grid_size = cfg->carrier_config.dl_grid_size[fp->numerology_index].value;
memset(gNB->num_pdsch_rnti, 0, sizeof(uint16_t)*80);
for (i=0; i <NUMBER_OF_NR_PDCCH_MAX; i++) {
LOG_I(PHY,"Initializing PDCCH list for PDCCH %d/%d\n",i,NUMBER_OF_NR_PDCCH_MAX);
gNB->pdcch_pdu[i].frame=-1;
+3 -3
View File
@@ -121,9 +121,9 @@ int nr_phy_init_RU(RU_t *ru) {
LOG_E(PHY,"[INIT] %s() RC.nb_nr_L1_inst:%d \n", __FUNCTION__, RC.nb_nr_L1_inst);
int beam_count = 0;
if (ru->nb_log_antennas>1) {
if (ru->nb_tx>1) {//Enable beamforming when nb_tx > 1
for (p=0;p<ru->nb_log_antennas;p++) {
if ((fp->L_ssb >> p) & 0x01)
if ((fp->L_ssb >> (63-p)) & 0x01)//64 bit-map with the MSB @2⁶³ corresponds to SSB ssb_index 0
beam_count++;
}
AssertFatal(ru->nb_bfw==(beam_count*ru->nb_tx),"Number of beam weights from config file is %d while the expected number is %d",ru->nb_bfw,(beam_count*ru->nb_tx));
@@ -131,7 +131,7 @@ int nr_phy_init_RU(RU_t *ru) {
int l_ind = 0;
for (i=0; i<RC.nb_nr_L1_inst; i++) {
for (p=0;p<ru->nb_log_antennas;p++) {
if ((fp->L_ssb >> p) & 0x01) {
if ((fp->L_ssb >> (63-p)) & 0x01) {
ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*));
for (j=0; j<ru->nb_tx; j++) {
ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t));
+2 -2
View File
@@ -308,7 +308,7 @@ int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg,
int num_tx_ant = (cfg == NULL) ? fp->Lmax : cfg->carrier_config.num_tx_ant.value;
for (int p=0; p<num_tx_ant; p++)
fp->N_ssb += ((fp->L_ssb >> p) & 0x01);
fp->N_ssb += ((fp->L_ssb >> (63-p)) & 0x01);
return 0;
@@ -389,7 +389,7 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
fp->N_ssb = 0;
for (int p=0; p<fp->Lmax; p++)
fp->N_ssb += ((fp->L_ssb >> p) & 0x01);
fp->N_ssb += ((fp->L_ssb >> (63-p)) & 0x01);
return 0;
}
+1 -1
View File
@@ -55,7 +55,7 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1
uint8_t preamble_index = ue->prach_resources[eNB_id]->ra_PreambleIndex;
uint8_t tdd_mapindex = ue->prach_resources[eNB_id]->ra_TDD_map_index;
int16_t *prachF = ue->prach_vars[eNB_id]->prachF;
static int16_t prach_tmp[45600*2] __attribute__((aligned(32)));
static int16_t prach_tmp[45600*4] __attribute__((aligned(32)));
int16_t *prach = prach_tmp;
int16_t *prach2;
int16_t amp = ue->prach_vars[eNB_id]->amp;
+1 -1
View File
@@ -155,7 +155,7 @@ int nr_beam_precoding(int32_t **txdataF,
memset(&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size],0,sizeof(int32_t)*(frame_parms->ofdm_symbol_size));
for (p=0; p<nb_antenna_ports; p++) {
if ((frame_parms->L_ssb >> p) & 0x01) {
if ((frame_parms->L_ssb >> (63-p)) & 0x01) {
multadd_cpx_vector((int16_t*)&txdataF[p][symbol*frame_parms->ofdm_symbol_size],
(int16_t*)beam_weights[p][aa],
(int16_t*)&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size],
+1 -1
View File
@@ -291,7 +291,7 @@ void nr_fill_dlsch(PHY_VARS_gNB *gNB,
NR_DL_gNB_HARQ_t **harq = dlsch->harq_processes;
/// DLSCH struct
memcpy((void*)&harq[dlsch->harq_ids[frame%2][slot]]->pdsch_pdu, (void*)pdsch_pdu, sizeof(nfapi_nr_dl_tti_pdsch_pdu));
gNB->num_pdsch_rnti++;
gNB->num_pdsch_rnti[slot]++;
AssertFatal(sdu!=NULL,"sdu is null\n");
harq[dlsch->harq_ids[frame%2][slot]]->pdu = sdu;
+1 -2
View File
@@ -37,7 +37,6 @@
extern uint16_t prach_root_sequence_map_0_3[838];
extern uint16_t prach_root_sequence_map_abc[138];
extern uint16_t nr_du[838];
extern int16_t nr_ru[2*839];
extern const char *prachfmt[9];
void init_prach_list(PHY_VARS_gNB *gNB) {
@@ -540,7 +539,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
uint16_t rootSequenceIndex;
int numrootSequenceIndex;
uint8_t restricted_set;
uint8_t n_ra_prb;
uint8_t n_ra_prb=0xFF;
int16_t *prachF=NULL;
int nb_rx;
@@ -353,4 +353,5 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
nfapi_nr_uci_pucch_pdu_format_0_1_t* uci_pdu,
nfapi_nr_pucch_pdu_t* pucch_pdu);
#endif /*__NR_TRANSPORT__H__*/
@@ -711,8 +711,8 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
}
#ifdef DEBUG_ULSCH_DECODING
LOG_I(PHY, "Decoder output (payload): \n");
for (i = 0; i < harq_process->TBS ; i++) {
LOG_I(PHY, "Decoder output (payload, TBS: %d): \n", harq_process->TBS);
for (i = 0; i < harq_process->TBS; i++) {
//harq_process_ul_ue->a[i] = (unsigned char) rand();
//printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
printf("%02x",harq_process->b[i]);
+15 -9
View File
@@ -340,6 +340,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
}
}
int32_t corr_re,corr_im,temp,no_corr=0;
int32_t av_corr=0;
int seq_index;
for(i=0;i<nr_sequences;i++){
@@ -360,15 +361,15 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
printf("PUCCH IDFT[%d/%d] = (%d,%d)=>%f\n",mcs[i],seq_index,corr_re,corr_im,10*log10(corr_re*corr_re + corr_im*corr_im));
#endif
temp=corr_re*corr_re + corr_im*corr_im;
no_corr+=temp;
av_corr+=temp;
if (temp>xrtmag) {
xrtmag=temp;
maxpos=i;
}
}
no_corr-=xrtmag;
if (nr_sequences>1)
no_corr/=(nr_sequences-1);
if(nr_sequences>1)
no_corr=(av_corr-xrtmag)/(nr_sequences-1);
av_corr/=nr_sequences;
uint8_t xrtmag_dB = dB_fixed(xrtmag);
@@ -386,6 +387,11 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
else if (SNRtimes10 > 635) cqi=255;
else cqi=(640+SNRtimes10)/5;
bool no_conf=false;
if (nr_sequences>1) {
if ((xrtmag_dB<(11+dB_fixed(no_corr))) || (dB_fixed(av_corr)<(13+gNB->measurements.n0_power_tot_dB))) //TODO these are temporary threshold based on measurments with the phone
no_conf=true;
}
// first bit of bitmap for sr presence and second bit for acknack presence
uci_pdu->pduBitmap = pucch_pdu->sr_flag | ((pucch_pdu->bit_len_harq>0)<<1);
uci_pdu->pucch_format = 0; // format 0
@@ -396,7 +402,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
if (pucch_pdu->bit_len_harq==0) {
uci_pdu->harq = NULL;
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
uci_pdu->sr->sr_confidence_level = (xrtmag_dB<(11+gNB->measurements.n0_power_tot_dB)) ? 1 : 0;
uci_pdu->sr->sr_confidence_level = (xrtmag_dB<(13+gNB->measurements.n0_power_tot_dB)) ? 1 : 0;
if (xrtmag_dB>(gNB->measurements.n0_power_tot_dB)) {
uci_pdu->sr->sr_indication = 1;
} else {
@@ -406,7 +412,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
else if (pucch_pdu->bit_len_harq==1) {
uci_pdu->harq = calloc(1,sizeof(*uci_pdu->harq));
uci_pdu->harq->num_harq = 1;
uci_pdu->harq->harq_confidence_level = (xrtmag_dB<(11+dB_fixed(no_corr))) ? 1 : 0;
uci_pdu->harq->harq_confidence_level = (no_conf) ? 1 : 0;
uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(1);
uci_pdu->harq->harq_list[0].harq_value = index&0x01;
LOG_I(PHY, "HARQ value %d with confidence level (0 is good, 1 is bad) %d\n",
@@ -414,13 +420,13 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
if (pucch_pdu->sr_flag == 1) {
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
uci_pdu->sr->sr_indication = (index>1) ? 1 : 0;
uci_pdu->sr->sr_confidence_level = (xrtmag_dB<(11+dB_fixed(no_corr))) ? 1 : 0;
uci_pdu->sr->sr_confidence_level = (no_conf) ? 1 : 0;
}
}
else {
uci_pdu->harq = calloc(1,sizeof(*uci_pdu->harq));
uci_pdu->harq->num_harq = 2;
uci_pdu->harq->harq_confidence_level = (xrtmag_dB<(11+dB_fixed(no_corr))) ? 1 : 0;
uci_pdu->harq->harq_confidence_level = (no_conf) ? 1 : 0;
uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(2);
uci_pdu->harq->harq_list[1].harq_value = index&0x01;
uci_pdu->harq->harq_list[0].harq_value = (index>>1)&0x01;
@@ -429,7 +435,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
if (pucch_pdu->sr_flag == 1) {
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
uci_pdu->sr->sr_indication = (index>3) ? 1 : 0;
uci_pdu->sr->sr_confidence_level = (xrtmag_dB<(11+dB_fixed(no_corr))) ? 1 : 0;
uci_pdu->sr->sr_confidence_level = (no_conf) ? 1 : 0;
}
}
}
@@ -266,8 +266,14 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
double Coderate;// = 0.0;
uint8_t dmrs_Type = harq_process->dmrsConfigType;
AssertFatal(dmrs_Type == 1 || dmrs_Type == 2,"Illegal dmrs_type %d\n",dmrs_Type);
uint8_t nb_re_dmrs = (dmrs_Type==1)?6:4; // should be changed based on MAC parameters
AssertFatal(dmrs_Type == 0 || dmrs_Type == 1, "Illegal dmrs_type %d\n", dmrs_Type);
uint8_t nb_re_dmrs;
if (dmrs_Type==NFAPI_NR_DMRS_TYPE1) {
nb_re_dmrs = 6*harq_process->n_dmrs_cdm_groups;
}
else {
nb_re_dmrs = 4*harq_process->n_dmrs_cdm_groups;
}
uint16_t dmrs_length = get_num_dmrs(harq_process->dlDmrsSymbPos);
AssertFatal(dmrs_length == 1 || dmrs_length == 2,"Illegal dmrs_length %d\n",dmrs_length);
@@ -805,7 +811,12 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
//nfapi_nr_config_request_t *cfg = &phy_vars_ue->nrUE_config;
//uint8_t dmrs_type = cfg->pdsch_config.dmrs_type.value;
uint8_t nb_re_dmrs = 12;//(dmrs_type==1)?6:4;
uint8_t nb_re_dmrs;
if (dmrs_Type == NFAPI_NR_DMRS_TYPE1)
nb_re_dmrs = 6*harq_process->n_dmrs_cdm_groups;
else
nb_re_dmrs = 4*harq_process->n_dmrs_cdm_groups;
uint16_t length_dmrs = get_num_dmrs(dl_config_pdu->dlDmrsSymbPos);
uint32_t i,j;
@@ -134,7 +134,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
int avgs = 0;// rb;
NR_DL_UE_HARQ_t *dlsch0_harq, *dlsch1_harq = NULL;
uint8_t beamforming_mode;
uint8_t beamforming_mode = 0;
int32_t **rxdataF_comp_ptr;
int32_t **dl_ch_mag_ptr;
@@ -162,24 +162,34 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
pdsch_vars = ue->pdsch_vars_SI;
dlsch = &ue->dlsch_SI[eNB_id];
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
beamforming_mode = 0;
break;
case RA_PDSCH:
pdsch_vars = ue->pdsch_vars_ra;
dlsch = &ue->dlsch_ra[eNB_id];
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
beamforming_mode = 0;
// WIP TBR Hotfix
memcpy((void*)&pdsch_vars[eNB_id]->dl_ch_estimates[0][ue->frame_parms.ofdm_symbol_size*2], (void*)&ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][0]->dl_ch_estimates[0][ue->frame_parms.ofdm_symbol_size*2], ue->frame_parms.ofdm_symbol_size*sizeof(int32_t));
break;
case PDSCH:
pdsch_vars = ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]];
dlsch = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id];
beamforming_mode = ue->transmission_mode[eNB_id] < 7 ? 0 :ue->transmission_mode[eNB_id];
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
dlsch1_harq = dlsch[1]->harq_processes[harq_pid];
beamforming_mode = ue->transmission_mode[eNB_id] < 7 ? 0 :ue->transmission_mode[eNB_id];
break;
default:
LOG_E(PHY, "[UE][FATAL] nr_tti_rx %d: Unknown PDSCH format %d\n", nr_tti_rx, type);
return -1;
break;
}
if (dlsch1_harq){
//printf("status TB0 = %d, status TB1 = %d \n", dlsch[0]->harq_processes[harq_pid]->status, dlsch[1]->harq_processes[harq_pid]->status);
LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n", frame, nr_tti_rx, symbol, harq_pid, dlsch0_harq->status, dlsch1_harq->status);
@@ -191,47 +201,51 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
dlsch1_harq = dlsch[codeword_TB1]->harq_processes[harq_pid];
#ifdef DEBUG_HARQ
printf("[DEMOD] I am assuming both TBs are active\n");
printf("[DEMOD] I am assuming both TBs are active, in cw0 %d and cw1 %d \n", codeword_TB0, codeword_TB1);
#endif
} else if ((dlsch0_harq->status == ACTIVE) && (dlsch1_harq->status != ACTIVE) ) {
codeword_TB0 = dlsch0_harq->codeword;
codeword_TB1 = -1;
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
dlsch0_harq = dlsch[codeword_TB0]->harq_processes[harq_pid];
dlsch1_harq = NULL;
#ifdef DEBUG_HARQ
printf("[DEMOD] I am assuming only TB0 is active\n");
printf("[DEMOD] I am assuming only TB0 is active, in cw %d \n", codeword_TB0);
#endif
} else if ((dlsch0_harq->status != ACTIVE) && (dlsch1_harq->status == ACTIVE)){
codeword_TB0 = -1;
codeword_TB1 = dlsch1_harq->codeword;
dlsch0_harq = NULL;
dlsch1_harq = dlsch[1]->harq_processes[codeword_TB1];
dlsch1_harq = dlsch[codeword_TB1]->harq_processes[harq_pid];
#ifdef DEBUG_HARQ
printf("[DEMOD] I am assuming only TB1 is active, it is in cw %d\n", dlsch1_harq->codeword);
printf("[DEMOD] I am assuming only TB1 is active, it is in cw %d\n", codeword_TB1);
#endif
AssertFatal(1 == 0, "[UE][FATAL] DLSCH: TB0 not active and TB1 active case is not supported\n");
LOG_E(PHY, "[UE][FATAL] DLSCH: TB0 not active and TB1 active case is not supported\n");
return -1;
} else {
LOG_E(PHY,"[UE][FATAL] nr_tti_rx %d: no active DLSCH\n", nr_tti_rx);
return(-1);
}
} else if (dlsch0_harq) {
if (dlsch0_harq->status == ACTIVE)
codeword_TB0 = dlsch0_harq->codeword;
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
break;
default:
AssertFatal(1 == 0, "[UE][FATAL] nr_tti_rx %d: Unknown PDSCH format %d\n", nr_tti_rx, type);
return(-1);
break;
#ifdef DEBUG_HARQ
printf("[DEMOD] I am assuming only TB0 is active\n");
#endif
} else {
LOG_E(PHY,"[UE][FATAL] nr_tti_rx %d: no active DLSCH\n", nr_tti_rx);
return (-1);
}
if (dlsch0_harq == NULL)
AssertFatal(1 == 0, "Done\n");
if (dlsch0_harq == NULL) {
LOG_E(PHY, "Done\n");
return -1;
}
dlsch0_harq->Qm = nr_get_Qm_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table);
dlsch0_harq->R = nr_get_code_rate_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table);
@@ -2377,7 +2391,7 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
k = frame_parms->first_carrier_offset + 12*start_rb;
k = frame_parms->first_carrier_offset + NR_NB_SC_PER_RB*start_rb;
if (high_speed_flag == 1)
dl_ch0 = &dl_ch_estimates[aarx][(2*(frame_parms->ofdm_symbol_size))];
+13 -20
View File
@@ -44,18 +44,8 @@
//#define NR_PRACH_DEBUG 1
extern uint16_t NCS_unrestricted_delta_f_RA_125[16];
extern uint16_t NCS_restricted_TypeA_delta_f_RA_125[15];
extern uint16_t NCS_restricted_TypeB_delta_f_RA_125[13];
extern uint16_t NCS_unrestricted_delta_f_RA_5[16];
extern uint16_t NCS_restricted_TypeA_delta_f_RA_5[16];
extern uint16_t NCS_restricted_TypeB_delta_f_RA_5[14];
extern uint16_t NCS_unrestricted_delta_f_RA_15[16];
extern uint16_t prach_root_sequence_map_0_3[838];
extern uint16_t prach_root_sequence_map_abc[138];
extern int64_t table_6_3_3_2_2_prachConfig_Index [256][9];
extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9];
extern int64_t table_6_3_3_2_4_prachConfig_Index [256][10];
extern uint16_t nr_du[838];
extern int16_t nr_ru[2*839];
extern const char *prachfmt[9];
@@ -118,7 +108,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
else
samp_count = (slot%(fp->slots_per_subframe/2)) ? fp->samples_per_slotN0 : fp->samples_per_slot0;
#if defined (OAI_USRP)
#ifdef OAI_USRP
prach_start = (ue->rx_offset + slot*samp_count - ue->hw_timing_advance - ue->N_TA_offset);
#else //normal case (simulation)
prach_start = slot*samp_count - ue->N_TA_offset;
@@ -208,14 +198,17 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
// now generate PRACH signal
#ifdef NR_PRACH_DEBUG
if (NCS>0)
LOG_I(PHY, "PRACH [UE %d] generate PRACH for RootSeqIndex %d, Preamble Index %d, PRACH Format %s, NCS %d (N_ZC %d): Preamble_offset %d, Preamble_shift %d\n", Mod_id,
rootSequenceIndex,
preamble_index,
prach_sequence_length == 0 ? prachfmt03[prach_fmt_id] : prachfmt[prach_fmt_id],
LOG_I(PHY, "PRACH [UE %d] generate PRACH in slot %d for RootSeqIndex %d, Preamble Index %d, PRACH Format %s, NCS %d (N_ZC %d): Preamble_offset %d, Preamble_shift %d msg1 frequency start %d\n",
Mod_id,
slot,
rootSequenceIndex,
preamble_index,
prach_sequence_length == 0 ? prachfmt03[prach_fmt_id] : prachfmt[prach_fmt_id],
NCS,
N_ZC,
preamble_offset,
preamble_shift);
preamble_shift,
n_ra_prb);
#endif
// nsymb = (frame_parms->Ncp==0) ? 14:12;
@@ -383,8 +376,6 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
} else {
//LOG_D(PHY, "PRACH [UE %d] in slot %d, format %d, msg1 frequency start %d startSymbol %d \n", Mod_id, slot, prachfmt[prach_fmt_id], n_ra_prb, prachStartSymbol);
switch (prach_fmt_id) {
case 0: //A1
Ncp = 288/(1<<mu);
@@ -419,7 +410,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
}
}
LOG_D(PHY, "PRACH [UE %d] Ncp %d, dftlen %d \n", Mod_id, Ncp, dftlen);
#ifdef NR_PRACH_DEBUG
LOG_D(PHY, "PRACH [UE %d] Ncp %d, dftlen %d \n", Mod_id, Ncp, dftlen);
#endif
if (fp->N_RB_UL <= 100)
AssertFatal(1==0,"N_RB_UL %d not supported for NR PRACH yet\n",fp->N_RB_UL);
@@ -844,7 +837,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
//}
//printf(" \n");
#if defined(PRACH_WRITE_OUTPUT_DEBUG)
#ifdef PRACH_WRITE_OUTPUT_DEBUG
LOG_M("prach_tx0.m", "prachtx0", prach+(Ncp<<1), prach_len-Ncp, 1, 1);
LOG_M("Prach_txsig.m","txs",(int16_t*)(&ue->common_vars.txdata[0][prach_start]), 2*(prach_start+prach_len), 1, 1)
#endif
@@ -292,6 +292,8 @@ typedef struct {
uint16_t dlDmrsSymbPos;
/// DMRS Configuration Type
uint8_t dmrsConfigType;
// Number of DMRS CDM groups with no data
uint8_t n_dmrs_cdm_groups;
/// Starting Symbol number
uint16_t start_symbol;
/// Current subband PMI allocation
+1 -52
View File
@@ -100,7 +100,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
LOG_D(PHY,"nr_ue_ulsch_procedures hard_id %d %d.%d\n",harq_pid,frame,slot);
uint32_t available_bits, TBS;
uint32_t available_bits;
uint8_t mod_order, cwd_index, num_of_codewords, l;
uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
uint32_t ***pusch_dmrs;
@@ -113,7 +113,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
int ap, start_symbol, Nid_cell, i;
int sample_offsetF, N_RE_prime, N_PRB_oh;
uint16_t ul_dmrs_symb_pos;
uint8_t data_existing =0;
uint8_t L_ptrs, K_ptrs; // PTRS parameters
uint16_t beta_ptrs; // PTRS parameter related to power control
@@ -121,7 +120,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
NR_UL_UE_HARQ_t *harq_process_ul_ue=NULL;
NR_DL_FRAME_PARMS *frame_parms = &UE->frame_parms;
NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][gNB_id];
uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES];
// ptrs_UplinkConfig_t *ptrs_Uplink_Config = &UE->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig;
num_of_codewords = 1; // tmp assumption
@@ -171,54 +169,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
0,
harq_process_ul_ue->pusch_pdu.nrOfLayers);
uint8_t access_mode = SCHEDULED_ACCESS;
//-----------------------------------------------------//
// to be removed later when MAC is ready
if (harq_process_ul_ue != NULL){
TBS = harq_process_ul_ue->pusch_pdu.pusch_data.tb_size;
data_existing = 0;
if (IS_SOFTMODEM_NOS1){
data_existing = nr_ue_get_sdu(UE->Mod_id, UE->CC_id, frame,
slot, 0, ulsch_input_buffer, TBS/8, &access_mode);
//IP traffic to be transmitted
if(data_existing){
//harq_process_ul_ue->a = (unsigned char*)calloc(harq_process_ul_ue->TBS/8, sizeof(unsigned char));
memcpy(harq_process_ul_ue->a, ulsch_input_buffer, TBS/8);
}
}
//Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity
if (!IS_SOFTMODEM_NOS1 || !data_existing) {
//Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid
//and block this traffic from being forwarded to the upper layers at the gNB
LOG_D(PHY, "Random data to be tranmsitted: \n");
//Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2)
//in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should
//have a valid LCID (nr_process_mac_pdu function)
harq_process_ul_ue->a[0] = 0x31;
for (i = 1; i < TBS / 8; i++) {
harq_process_ul_ue->a[i] = (unsigned char) rand();
//printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
}
}
#ifdef DEBUG_MAC_PDU
LOG_I(PHY, "Printing MAC PDU to be encoded, TBS is: %d \n", TBS/8);
for (i = 0; i < TBS / 8; i++) {
printf("%02x",harq_process_ul_ue->a[i]);
}
printf("\n");
#endif
} else {
LOG_E(PHY, "[phy_procedures_nrUE_TX] harq_process_ul_ue is NULL !!\n");
return;
}
//-----------------------------------------------------//
/////////////////////////ULSCH coding/////////////////////////
///////////
@@ -471,7 +421,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
///////////
////////////////////////////////////////////////////////////////////////
LOG_D(PHY, "Is data existing ?: %d \n", data_existing);
}
+4 -4
View File
@@ -963,7 +963,7 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
uint64_t b[16]; // limit to 1024-bit encoded length
// M_bit is the number of bits of block b (payload after encoding)
uint16_t M_bit;
nr_uci_encoding(payload,nr_bit,pucch_format2_nr,0,nrofSymbols,nrofPRB,1,0,0,(void*)b,&M_bit);
nr_uci_encoding(payload,nr_bit,pucch_format2_nr,0,nrofSymbols,nrofPRB,1,0,0,&b[0],&M_bit);
/*
* Implementing TS 38.211
* Subclauses 6.3.2.5.1 Scrambling (PUCCH format 2)
@@ -985,7 +985,7 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
/*
* Implementing TS 38.211 Subclause 6.3.2.5.1 scrambling format 2
*/
nr_pucch2_3_4_scrambling(M_bit,rnti,data_scrambling_id,b,btilde);
nr_pucch2_3_4_scrambling(M_bit,rnti,data_scrambling_id,&b[0],btilde);
/*
* Implementing TS 38.211 Subclause 6.3.2.5.2 modulation format 2
* btilde shall be modulated as described in subclause 5.1 using QPSK
@@ -1154,7 +1154,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
//nrofPRB = 2; // only for test purposes
if (fmt == pucch_format4_nr) nrofPRB = 1;
nr_uci_encoding(payload,nr_bit,fmt,is_pi_over_2_bpsk_enabled,nrofSymbols,nrofPRB,n_SF_PUCCH_s,intraSlotFrequencyHopping,add_dmrs,(void*)b,&M_bit);
nr_uci_encoding(payload,nr_bit,fmt,is_pi_over_2_bpsk_enabled,nrofSymbols,nrofPRB,n_SF_PUCCH_s,intraSlotFrequencyHopping,add_dmrs,&b[0],&M_bit);
/*
* Implementing TS 38.211
* Subclauses 6.3.2.6.1 Scrambling (PUCCH formats 3 and 4)
@@ -1176,7 +1176,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
/*
* Implementing TS 38.211 Subclause 6.3.2.6.1 scrambling formats 3 and 4
*/
nr_pucch2_3_4_scrambling(M_bit,rnti,n_id,b,btilde);
nr_pucch2_3_4_scrambling(M_bit,rnti,n_id,&b[0],btilde);
/*
* Implementing TS 38.211 Subclause 6.3.2.6.2 modulation formats 3 and 4
*
+14 -1
View File
@@ -26,6 +26,7 @@
#include <stdlib.h>
#include "nr_phy_scope.h"
#include "executables/nr-softmodem-common.h"
#include "executables/softmodem-common.h"
#include <forms.h>
#define TPUT_WINDOW_LENGTH 100
@@ -400,7 +401,8 @@ static void *scope_thread_gNB(void *arg) {
// FILE *gNB_stats = fopen("gNB_stats.txt", "w");
//#endif
size_t stksize=0;
pthread_attr_t atr= {0};
pthread_attr_t atr;
pthread_attr_init(&atr);
pthread_attr_getstacksize(&atr, &stksize);
pthread_attr_setstacksize(&atr,32*1024*1024 );
sleep(3); // no clean interthread barriers
@@ -768,6 +770,15 @@ void nrUEinitScope(PHY_VARS_NR_UE *ue) {
threadCreate(&forms_thread, nrUEscopeThread, ue, "scope", -1, OAI_PRIORITY_RT_LOW);
}
void nrscope_autoinit(void *dataptr) {
AssertFatal( (IS_SOFTMODEM_GNB_BIT||IS_SOFTMODEM_5GUE_BIT),"Scope cannot find NRUE or GNB context");
if (IS_SOFTMODEM_GNB_BIT)
gNBinitScope(dataptr);
else
nrUEinitScope(dataptr);
}
// Kept to put back the functionality soon
#if 0
//FD_stats_form *form_stats=NULL,*form_stats_l2=NULL;
@@ -795,6 +806,8 @@ static void reset_stats_gNB(FL_OBJECT *button,
}
}
static FD_stats_form *create_form_stats_form(int ID) {
FL_OBJECT *obj;
FD_stats_form *fdui = calloc(( sizeof *fdui ),1);
-2
View File
@@ -40,8 +40,6 @@ typedef struct {
PHY_VARS_gNB *gNB;
} scopeParms_t;
void gNBinitScope(scopeParms_t *p);
void nrUEinitScope(PHY_VARS_NR_UE *ue);
extern RAN_CONTEXT_t RC;
#endif
+2 -2
View File
@@ -37,10 +37,10 @@
#define SOFTSCOPE_ENDFUNC_IDX 0
static loader_shlibfunc_t scope_fdesc[]= {{"end_forms",NULL}};
int load_softscope(char *exectype) {
int load_softscope(char *exectype, void *initarg) {
char libname[64];
sprintf(libname,"%.10sscope",exectype);
return load_module_shlib(libname,scope_fdesc,1,NULL);
return load_module_shlib(libname,scope_fdesc,1,initarg);
}
int end_forms(void) {
+1 -1
View File
@@ -31,5 +31,5 @@
*/
int load_softscope(char *exectype);
int load_softscope(char *exectype, void *initarg);
int end_forms(void) ;
+12
View File
@@ -0,0 +1,12 @@
To use the scope, run the xNB or the UE with option "-d"
Usage in gdb
In gdb, when you break, you can refresh immediatly the scope view by calling the display function.
The first paramter is the graph context, nevertheless we keep the last value for a dirty call in gdb (so you can use '0')
Example with no variable known
phy_scope_nrUE(0, PHY_vars_UE_g[0][0], 0, 0, 0)
or
phy_scope_gNB(0, phy_vars_gnb, phy_vars_ru, UE_id)
+1 -1
View File
@@ -691,7 +691,7 @@ typedef struct PHY_VARS_gNB_s {
// nfapi_nr_ul_dci_request_pdus_t *ul_dci_pdu;
nfapi_nr_dl_tti_ssb_pdu ssb_pdu;
int num_pdsch_rnti;
uint16_t num_pdsch_rnti[80];
NR_gNB_PBCH pbch;
nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL];
NR_gNB_COMMON common_vars;
+4 -4
View File
@@ -59,10 +59,10 @@ const short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
unsigned char NB_RU=0;
#ifndef OPENAIR2
unsigned char NB_eNB_INST=0;
uint16_t NB_UE_INST=0;
unsigned char NB_RN_INST=0;
unsigned char NB_INST=0;
//unsigned char NB_eNB_INST=0;
//uint16_t NB_UE_INST=0;
//unsigned char NB_RN_INST=0;
//unsigned char NB_INST=0;
#endif
int number_of_cards;
+1 -1
View File
@@ -138,4 +138,4 @@ uint8_t scrambling_lut[65536*16] __attribute__((aligned(32)));
uint8_t max_ldpc_iterations=4;
uint8_t max_turbo_iterations=4;
#endif /*__PHY_VARS_H__ */
#endif
+2 -1
View File
@@ -154,11 +154,12 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
number_ul_dci_pdu,number_ul_tti_pdu);
int pdcch_received=0;
gNB->num_pdsch_rnti=0;
gNB->num_pdsch_rnti[slot]=0;
for (int i=0; i<NUMBER_OF_NR_DLSCH_MAX; i++) {
gNB->dlsch[i][0]->rnti=0;
gNB->dlsch[i][0]->harq_mask=0;
}
gNB->pbch_configured=0;
for (int i=0;i<number_dl_pdu;i++) {
+2 -71
View File
@@ -29,11 +29,9 @@
*
************************************************************************/
#include "SCHED_NR_UE/defs.h"
#include "PHY/defs_nr_common.h"
#include "PHY/defs_nr_UE.h"
#include "SCHED_NR_UE/phy_frame_config_nr.h"
#include "PHY/impl_defs_nr.h"
#include "PHY/impl_defs_top.h"
#include "SCHED_NR/phy_frame_config_nr.h"
/*******************************************************************
*
@@ -369,73 +367,6 @@ int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_tti)
}
}
/*******************************************************************
*
* NAME : nr_ue_slot_select
*
* DESCRIPTION : function for the UE equivalent to nr_slot_select
*
*********************************************************************/
int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_tti) {
/* for FFD all slot can be considered as an uplink */
int mu = cfg->ssb_config.scs_common, check_slot = 0;
if (cfg->cell_config.frame_duplex_type == FDD) {
return (NR_UPLINK_SLOT | NR_DOWNLINK_SLOT);
}
if (nr_frame%2 == 0) {
for(int symbol_count=0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
if (cfg->tdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 1) {
check_slot++;
}
}
if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
return (NR_UPLINK_SLOT);
}
check_slot = 0;
for(int symbol_count=0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
if (cfg->tdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 0) {
check_slot++;
}
}
if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
return (NR_DOWNLINK_SLOT);
} else {
return (NR_MIXED_SLOT);
}
} else {
for(int symbol_count=0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
if (cfg->tdd_table.max_tdd_periodicity_list[((1<<mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME) + nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 1) {
check_slot++;
}
}
if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
return (NR_UPLINK_SLOT);
}
check_slot = 0;
for(int symbol_count=0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
if (cfg->tdd_table.max_tdd_periodicity_list[((1<<mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME) + nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 0) {
check_slot++;
}
}
if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
return (NR_DOWNLINK_SLOT);
} else {
return (NR_MIXED_SLOT);
}
}
}
/*******************************************************************
*
* NAME : free_tdd_configuration_nr
+2 -4
View File
@@ -32,7 +32,6 @@
#ifndef PHY_FRAME_CONFIG_NR_H
#define PHY_FRAME_CONFIG_NR_H
#include <nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h>
/************** DEFINE ********************************************/
#define TDD_CONFIG_NB_FRAMES (2)
@@ -77,10 +76,9 @@ int set_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms);
* @param frame_parms NR DL Frame parameters
* @param nr_frame : frame number
* @param nr_tti : slot number
@returns nr_slot_t : downlink or uplink */
@returns int : downlink, uplink or mixed slot type*/
nr_slot_t nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_tti);
int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_tti);
int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_tti);
/** \brief This function frees tdd configuration for nr
* @param frame_parms NR DL Frame parameters
+20 -19
View File
@@ -170,8 +170,8 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
if (pdcch_pdu_id >= 0 || ul_pdcch_pdu_id >= 0) {
LOG_D(PHY, "[gNB %d] Frame %d slot %d Calling nr_generate_dci_top (number of UL/DL DCI %d/%d)\n",
gNB->Mod_id, frame, slot,
ul_pdcch_pdu_id==0?0:gNB->ul_pdcch_pdu[ul_pdcch_pdu_id].pdcch_pdu.pdcch_pdu.pdcch_pdu_rel15.numDlDci,
pdcch_pdu_id==0?0:gNB->pdcch_pdu[pdcch_pdu_id].pdcch_pdu.pdcch_pdu_rel15.numDlDci);
gNB->ul_pdcch_pdu[ul_pdcch_pdu_id].pdcch_pdu.pdcch_pdu.pdcch_pdu_rel15.numDlDci,
gNB->pdcch_pdu[pdcch_pdu_id].pdcch_pdu.pdcch_pdu_rel15.numDlDci);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_PDCCH_TX,1);
@@ -191,23 +191,23 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
if (ul_pdcch_pdu_id >= 0) gNB->ul_pdcch_pdu[ul_pdcch_pdu_id].frame = -1;
}
for (int i=0; i<gNB->num_pdsch_rnti; i++) {
for (int i=0; i<gNB->num_pdsch_rnti[slot]; i++) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,1);
LOG_D(PHY, "PDSCH generation started (%d)\n", gNB->num_pdsch_rnti);
LOG_D(PHY, "PDSCH generation started (%d) in frame %d.%d\n", gNB->num_pdsch_rnti[slot],frame,slot);
nr_generate_pdsch(gNB->dlsch[i][0],
gNB->nr_gold_pdsch_dmrs[slot],
gNB->common_vars.txdataF,
AMP, frame, slot, fp, 0,
&gNB->dlsch_encoding_stats,
&gNB->dlsch_scrambling_stats,
&gNB->dlsch_modulation_stats,
&gNB->tinput,
&gNB->tprep,
&gNB->tparity,
&gNB->toutput,
&gNB->dlsch_rate_matching_stats,
&gNB->dlsch_interleaving_stats,
&gNB->dlsch_segmentation_stats);
gNB->nr_gold_pdsch_dmrs[slot],
gNB->common_vars.txdataF,
AMP, frame, slot, fp, 0,
&gNB->dlsch_encoding_stats,
&gNB->dlsch_scrambling_stats,
&gNB->dlsch_modulation_stats,
&gNB->tinput,
&gNB->tprep,
&gNB->tparity,
&gNB->toutput,
&gNB->dlsch_rate_matching_stats,
&gNB->dlsch_interleaving_stats,
&gNB->dlsch_segmentation_stats);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,0);
}
@@ -361,7 +361,8 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
gNB->crc_pdu_list[num_crc].num_cb = pusch_pdu->pusch_data.num_cb;
gNB->crc_pdu_list[num_crc].ul_cqi = cqi;
gNB->crc_pdu_list[num_crc].timing_advance = timing_advance_update;
gNB->crc_pdu_list[num_crc].rssi = 0xffff; // invalid value as this is not yet computed
// in terms of dBFS range -128 to 0 with 0.1 step
gNB->crc_pdu_list[num_crc].rssi = 1280 - (10*dB_fixed(2047*2047)-dB_fixed_times10(gNB->pusch_vars[ULSCH_id]->ulsch_power[0]));
gNB->UL_INFO.crc_ind.number_crcs++;
@@ -375,7 +376,7 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
gNB->rx_pdu_list[num_rx].harq_id = harq_pid;
gNB->rx_pdu_list[num_rx].ul_cqi = cqi;
gNB->rx_pdu_list[num_rx].timing_advance = timing_advance_update;
gNB->rx_pdu_list[num_rx].rssi = 0xffff; // invalid value as this is not yet computed
gNB->rx_pdu_list[num_rx].rssi = 1280 - (10*dB_fixed(2047*2047)-dB_fixed_times10(gNB->pusch_vars[ULSCH_id]->ulsch_power[0]));
if (crc_flag)
gNB->rx_pdu_list[num_rx].pdu_length = 0;
else {
+25 -7
View File
@@ -106,6 +106,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
dlsch0_harq->start_symbol = dlsch_config_pdu->start_symbol;
dlsch0_harq->dlDmrsSymbPos = dlsch_config_pdu->dlDmrsSymbPos;
dlsch0_harq->dmrsConfigType = dlsch_config_pdu->dmrsConfigType;
dlsch0_harq->n_dmrs_cdm_groups = dlsch_config_pdu->n_dmrs_cdm_groups;
dlsch0_harq->mcs = dlsch_config_pdu->mcs;
dlsch0_harq->rvidx = dlsch_config_pdu->rv;
dlsch0->g_pucch = dlsch_config_pdu->accumulated_delta_PUCCH;
@@ -147,12 +148,32 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
// pusch config pdu
pusch_config_pdu = &ul_config->ul_config_list[i].pusch_config_pdu;
current_harq_pid = pusch_config_pdu->pusch_data.harq_process_id;
nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &ulsch0->harq_processes[current_harq_pid]->pusch_pdu;
NR_UL_UE_HARQ_t *harq_process_ul_ue = ulsch0->harq_processes[current_harq_pid];
memcpy(pusch_pdu, pusch_config_pdu, sizeof(nfapi_nr_ue_pusch_pdu_t));
if (harq_process_ul_ue){
nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &harq_process_ul_ue->pusch_pdu;
memcpy(pusch_pdu, pusch_config_pdu, sizeof(nfapi_nr_ue_pusch_pdu_t));
ulsch0->f_pusch = pusch_config_pdu->absolute_delta_PUSCH;
if (scheduled_response->tx_request){
fapi_nr_tx_request_body_t *tx_req_body = scheduled_response->tx_request->tx_request_body;
//harq_process_ul_ue->a = (unsigned char*)calloc(TBS/8, sizeof(unsigned char));
memcpy(harq_process_ul_ue->a, tx_req_body->pdu, tx_req_body->pdu_length);
harq_process_ul_ue->status = ACTIVE;
}
} else {
LOG_E(PHY, "[phy_procedures_nrUE_TX] harq_process_ul_ue is NULL !!\n");
return -1;
}
ulsch0->f_pusch = pusch_config_pdu->absolute_delta_PUSCH;
ulsch0->harq_processes[current_harq_pid]->status = ACTIVE;
break;
case (FAPI_NR_UL_CONFIG_TYPE_PUCCH):
@@ -214,9 +235,6 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
} else {
}
if (scheduled_response->tx_request != NULL){
} else {
}
}
return 0;
+9 -1
View File
@@ -62,10 +62,18 @@ int set_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms);
* @param frame_parms NR DL Frame parameters
* @param nr_frame : frame number
* @param nr_tti : slot number
@returns nr_slot_t : downlink or uplink */
@returns int : downlink or uplink */
int slot_select_nr(NR_DL_FRAME_PARMS *frame_parms, int nr_frame, int nr_tti);
/** \brief This function checks nr UE slot direction : downlink or uplink
* @param cfg : FAPI Config Request
* @param nr_frame : frame number
* @param nr_tti : slot number
@returns int : downlink, uplink or mixed slot type */
int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_tti);
/** \brief This function frees tdd configuration for nr
* @param frame_parms NR DL Frame parameters
@returns none */
@@ -0,0 +1,99 @@
/*
* 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
*/
/***********************************************************************
*
* FILENAME : phy_frame_configuration_nr_ue.c
*
* DESCRIPTION : functions related to FDD/TDD configuration for NR
* see TS 38.213 11.1 Slot configuration
* and TS 38.331 for RRC configuration
*
************************************************************************/
#include "PHY/defs_nr_UE.h"
/*******************************************************************
*
* NAME : nr_ue_slot_select
*
* DESCRIPTION : function for the UE equivalent to nr_slot_select
*
*********************************************************************/
int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_tti) {
/* for FFD all slot can be considered as an uplink */
int mu = cfg->ssb_config.scs_common, check_slot = 0;
if (cfg->cell_config.frame_duplex_type == FDD) {
return (NR_UPLINK_SLOT | NR_DOWNLINK_SLOT);
}
if (nr_frame%2 == 0) {
for(int symbol_count=0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
if (cfg->tdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 1) {
check_slot++;
}
}
if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
return (NR_UPLINK_SLOT);
}
check_slot = 0;
for(int symbol_count=0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
if (cfg->tdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 0) {
check_slot++;
}
}
if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
return (NR_DOWNLINK_SLOT);
} else {
return (NR_MIXED_SLOT);
}
} else {
for(int symbol_count=0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
if (cfg->tdd_table.max_tdd_periodicity_list[((1<<mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME) + nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 1) {
check_slot++;
}
}
if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
return (NR_UPLINK_SLOT);
}
check_slot = 0;
for(int symbol_count=0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
if (cfg->tdd_table.max_tdd_periodicity_list[((1<<mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME) + nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 0) {
check_slot++;
}
}
if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
return (NR_DOWNLINK_SLOT);
} else {
return (NR_MIXED_SLOT);
}
}
}
+12 -4
View File
@@ -2269,7 +2269,7 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
/* RACH */
if (get_softmodem_params()->do_ra==1) {
if ((ue->UE_mode[gNB_id] == PRACH) && (ue->prach_vars[gNB_id]->prach_Config_enabled == 1)) {
if ((ue->UE_mode[gNB_id] < PUSCH) && (ue->prach_vars[gNB_id]->prach_Config_enabled == 1)) {
nr_ue_prach_procedures(ue, proc, gNB_id, mode);
}
}
@@ -3289,9 +3289,8 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
NR_UE_PDSCH *pdsch_vars;
uint8_t is_cw0_active = 0;
uint8_t is_cw1_active = 0;
uint8_t dmrs_type = dlsch0->harq_processes[harq_pid]->dmrsConfigType;
uint8_t nb_re_dmrs = (dmrs_type==NFAPI_NR_DMRS_TYPE1)?6:4; // TODO: should changed my mac
uint16_t length_dmrs = 1; //cfg->pdsch_config.dmrs_max_length.value;
uint8_t dmrs_type, nb_re_dmrs;
uint16_t length_dmrs = 1;
uint16_t nb_symb_sch = 9;
nr_downlink_indication_t dl_indication;
fapi_nr_rx_indication_t rx_ind;
@@ -3316,6 +3315,13 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
is_cw0_active = dlsch0->harq_processes[harq_pid]->status;
nb_symb_sch = dlsch0->harq_processes[harq_pid]->nb_symbols;
start_symbol = dlsch0->harq_processes[harq_pid]->start_symbol;
dmrs_type = dlsch0->harq_processes[harq_pid]->dmrsConfigType;
if (dmrs_type==NFAPI_NR_DMRS_TYPE1) {
nb_re_dmrs = 6*dlsch0->harq_processes[harq_pid]->n_dmrs_cdm_groups;
}
else {
nb_re_dmrs = 4*dlsch0->harq_processes[harq_pid]->n_dmrs_cdm_groups;
}
if(dlsch1)
is_cw1_active = dlsch1->harq_processes[harq_pid]->status;
@@ -4608,6 +4614,8 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
if (ue->prach_cnt == 3)
ue->prach_cnt = 0;
} else if (nr_prach == 2) {
nr_ra_succeeded(mod_id, ue->CC_id, gNB_id);
}
// if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue
+2 -1
View File
@@ -478,8 +478,9 @@ int main(int argc, char **argv)
harq_process->Qm = mod_order;
harq_process->rvidx = rvidx;
harq_process->R = rate;
harq_process->dmrsConfigType = 1;
harq_process->dmrsConfigType = NFAPI_NR_DMRS_TYPE1;
harq_process->dlDmrsSymbPos = 4;
harq_process->n_dmrs_cdm_groups = 1;
printf("harq process ue mcs = %d Qm = %d, symb %d\n", harq_process->mcs, harq_process->Qm, nb_symb_sch);
unsigned char *test_input;
test_input = (unsigned char *) malloc16(sizeof(unsigned char) * TBS / 8);
+1 -1
View File
@@ -124,7 +124,7 @@ int generate_dlsch_header(unsigned char *mac_header,
unsigned char *ue_cont_res_id,
unsigned char short_padding,
unsigned short post_padding){return 0;}
void nr_ip_over_LTE_DRB_preconfiguration(void){}
void nr_DRB_preconfiguration(void){}
// needed for some functions
openair0_config_t openair0_cfg[MAX_CARDS];
+1 -1
View File
@@ -76,7 +76,7 @@ boolean_t pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP,
const sdu_size_t sdu_buffer_sizeP,
mem_block_t *const sdu_buffer_pP) {return(false);}
void nr_ip_over_LTE_DRB_preconfiguration(void){}
void nr_DRB_preconfiguration(void){}
void pdcp_layer_init(void) {}
int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) {return 0;}
+3 -2
View File
@@ -97,7 +97,7 @@ boolean_t pdcp_data_ind(
) { return(false);}
void pdcp_run (const protocol_ctxt_t *const ctxt_pP) { return;}
void nr_ip_over_LTE_DRB_preconfiguration(void){}
void nr_DRB_preconfiguration(void){}
int rrc_init_nr_global_param(void){return(0);}
@@ -814,7 +814,8 @@ int main(int argc, char **argv)
scheduled_response.slot = slot;
scheduled_response.dl_config = NULL;
scheduled_response.ul_config = &ul_config;
scheduled_response.dl_config = NULL;
scheduled_response.tx_request = (fapi_nr_tx_request_t *) malloc(sizeof(fapi_nr_tx_request_t));
scheduled_response.tx_request->tx_request_body = (fapi_nr_tx_request_body_t *) malloc(sizeof(fapi_nr_tx_request_body_t));
ul_config.slot = slot;
ul_config.number_pdus = 1;
+194 -42
View File
@@ -45,8 +45,12 @@ static mapping channelmod_names[] = {
};
static int channelmod_show_cmd(char *buff, int debug, telnet_printfunc_t prnt);
static int channelmod_modify_cmd(char *buff, int debug, telnet_printfunc_t prnt);
static int channelmod_print_help(char *buff, int debug, telnet_printfunc_t prnt);
static telnetshell_cmddef_t channelmod_cmdarray[] = {
{"show","",channelmod_show_cmd},
{"help","",channelmod_print_help},
{"show","<predef,current>",channelmod_show_cmd},
{"modify","<channelid> <param> <value>",channelmod_modify_cmd},
{"","",NULL},
};
@@ -56,14 +60,15 @@ static telnetshell_vardef_t channelmod_vardef[] = {
static double snr_dB=25;
static double sinr_dB=0;
static unsigned int max_chan;
static channel_desc_t** defined_channels;
void fill_channel_desc(channel_desc_t *chan_desc,
uint8_t nb_tx,
uint8_t nb_rx,
uint8_t nb_taps,
uint8_t channel_length,
double *amps,
double *delays,
double *delays,
struct complex **R_sqrt,
double Td,
double sampling_rate,
@@ -88,6 +93,7 @@ void fill_channel_desc(channel_desc_t *chan_desc,
if (delays==NULL) {
chan_desc->delays = (double *) malloc(nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_DELAY ;
delta_tau = Td/nb_taps;
for (i=0; i<nb_taps; i++)
@@ -129,10 +135,9 @@ void fill_channel_desc(channel_desc_t *chan_desc,
if (R_sqrt == NULL) {
chan_desc->R_sqrt = (struct complex **) calloc(nb_taps,sizeof(struct complex *));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_NTAPS ;
for (i = 0; i<nb_taps; i++) {
chan_desc->R_sqrt[i] = (struct complex *) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex));
chan_desc->R_sqrt[i] = (struct complex *) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex));
for (j = 0; j<nb_tx*nb_rx*nb_tx*nb_rx; j+=(nb_tx*nb_rx+1)) {
chan_desc->R_sqrt[i][j].x = 1.0;
chan_desc->R_sqrt[i][j].y = 0.0;
@@ -140,7 +145,7 @@ void fill_channel_desc(channel_desc_t *chan_desc,
}
} else {
chan_desc->R_sqrt = (struct complex **) calloc(nb_taps,sizeof(struct complex *));
for (i = 0; i<nb_taps; i++) {
//chan_desc->R_sqrt[i] = (struct complex*) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex));
//chan_desc->R_sqrt = (struct complex*)&R_sqrt[i][0];
@@ -170,7 +175,7 @@ void fill_channel_desc(channel_desc_t *chan_desc,
double mbsfn_delays[] = {0,.03,.15,.31,.37,1.09,12.490,12.52,12.64,12.80,12.86,13.58,27.49,27.52,27.64,27.80,27.86,28.58};
double mbsfn_amps_dB[] = {0,-1.5,-1.4,-3.6,-0.6,-7.0,-10,-11.5,-11.4,-13.6,-10.6,-17.0,-20,-21.5,-21.4,-23.6,-20.6,-27};
double scm_c_delays[] = {0, 0.0125, 0.0250, 0.3625, 0.3750, 0.3875, 0.2500, 0.2625, 0.2750, 1.0375, 1.0500, 1.0625, 2.7250, 2.7375, 2.7500, 4.6000, 4.6125, 4.6250};
double scm_c_delays[] = {0, 0.0125, 0.0250, 0.3625, 0.3750, 0.3875, 0.2500, 0.2625, 0.2750, 1.0375, 1.0500, 1.0625, 2.7250, 2.7375, 2.7500, 4.6000, 4.6125, 4.6250};
double scm_c_amps_dB[] = {0.00, -2.22, -3.98, -1.86, -4.08, -5.84, -1.08, -3.30, -5.06, -9.08, -11.30, -13.06, -15.14, -17.36, -19.12, -20.64, -22.85, -24.62};
double tdl_a_delays[] = {0.0000,
@@ -498,12 +503,24 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
double forgetting_factor,
int32_t channel_offset,
double path_loss_dB) {
channel_desc_t *chan_desc = (channel_desc_t *)malloc(sizeof(channel_desc_t));
channel_desc_t *chan_desc = (channel_desc_t *)calloc(1,sizeof(channel_desc_t));
for(int i=0; i<max_chan;i++) {
if (defined_channels[i] == NULL) {
defined_channels[i]=chan_desc;
chan_desc->chan_idx=i;
break;
}
else {
AssertFatal(i<(max_chan-1),
"No more channel descriptors available, increase channelmod.max_chan parameter above %u\n",max_chan);
}
}
uint16_t i,j;
double sum_amps;
double aoa,ricean_factor,Td,maxDoppler;
int channel_length,nb_taps;
chan_desc->modelid = channel_model;
chan_desc->nb_tx = nb_tx;
chan_desc->nb_rx = nb_rx;
chan_desc->sampling_rate = sampling_rate;
@@ -537,7 +554,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
for (i = 0; i<chan_desc->nb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]);
sum_amps += chan_desc->amps[i];
@@ -575,9 +592,10 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
for (i = 0; i<6; i++)
chan_desc->R_sqrt[i] = (struct complex *) &R12_sqrt[i][0];
} else {
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ;
for (i = 0; i<6; i++) {
chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
for (j = 0; j<nb_tx*nb_rx*nb_tx*nb_rx; j+=(nb_tx*nb_rx+1)) {
chan_desc->R_sqrt[i][j].x = 1.0;
chan_desc->R_sqrt[i][j].y = 0.0;
@@ -596,7 +614,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
for (i = 0; i<chan_desc->nb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]);
sum_amps += chan_desc->amps[i];
@@ -634,6 +652,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
for (i = 0; i<6; i++)
chan_desc->R_sqrt[i] = (struct complex *) &R12_sqrt[i][0];
} else {
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ;
for (i = 0; i<6; i++) {
chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
@@ -652,7 +671,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
case TDL_B:
case TDL_C:
case TDL_D:
case TDL_E:
case TDL_E:
if (channel_model == TDL_A) {
tdl_paths=TDL_A_PATHS;
tdl_delays=tdl_a_delays;
@@ -748,7 +767,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
for (i = 0; i<chan_desc->nb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]);
sum_amps += chan_desc->amps[i];
@@ -767,7 +786,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
for (i = 0; i<nb_tx*nb_rx; i++)
chan_desc->ch[i] = (struct complex *) malloc(chan_desc->channel_length * sizeof(struct complex));
for (i = 0; i<nb_tx*nb_rx; i++)
chan_desc->chF[i] = (struct complex *) malloc(1200 * sizeof(struct complex));
@@ -781,7 +800,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->R_sqrt[i] = (struct complex *) &R22_sqrt[i][0];
} else {
chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ;
for (i = 0; i<6; i++) {
chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
@@ -802,7 +821,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
for (i = 0; i<chan_desc->nb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]);
sum_amps += chan_desc->amps[i];
@@ -848,7 +867,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n");
}
}*/
break;
break;
case EPA_high:
chan_desc->nb_taps = 7;
@@ -856,7 +875,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
for (i = 0; i<chan_desc->nb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]);
sum_amps += chan_desc->amps[i];
@@ -910,7 +929,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
for (i = 0; i<chan_desc->nb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]);
sum_amps += chan_desc->amps[i];
@@ -964,7 +983,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
for (i = 0; i<chan_desc->nb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*eva_amps_dB[i]);
sum_amps += chan_desc->amps[i];
@@ -997,8 +1016,8 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->R_sqrt[i] = (struct complex *) &R22_sqrt[i][0];
} else {
chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **));
for (i = 0; i<6; i++) {
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ;
for (i = 0; i<6; i++) {
chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
for (j = 0; j<nb_tx*nb_rx*nb_tx*nb_rx; j+=(nb_tx*nb_rx+1)) {
@@ -1018,7 +1037,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
for (i = 0; i<chan_desc->nb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*etu_amps_dB[i]);
sum_amps += chan_desc->amps[i];
@@ -1051,7 +1070,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->R_sqrt[i] = (struct complex *) &R22_sqrt[i][0];
} else {
chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ;
for (i = 0; i<6; i++) {
chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
@@ -1072,7 +1091,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
for (i = 0; i<chan_desc->nb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*mbsfn_amps_dB[i]);
sum_amps += chan_desc->amps[i];
@@ -1099,7 +1118,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->a[i] = (struct complex *) malloc(nb_tx*nb_rx * sizeof(struct complex));
chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex *));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6;
for (i = 0; i<6; i++) {
chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
@@ -1610,10 +1629,37 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->nb_paths = 10;
return(chan_desc);
}
void free_channel_desc_scm(channel_desc_t *ch) {
// Must be made cleanly, a lot of leaks...
free(ch);
defined_channels[ch->chan_idx]=NULL;
if(ch->free_flags&CHANMODEL_FREE_AMPS)
free(ch->amps);
for (int i = 0; i<ch->nb_tx*ch->nb_rx; i++) {
free(ch->ch[i]);
free(ch->chF[i]);
}
for (int i = 0; i<ch->nb_taps; i++) {
free(ch->a[i]);
}
if(ch->free_flags&CHANMODEL_FREE_DELAY)
free(ch->delays);
if(ch->free_flags&CHANMODEL_FREE_RSQRT_6)
for (int i = 0; i<6; i++)
free(ch->R_sqrt[i]);
if(ch->free_flags&CHANMODEL_FREE_RSQRT_NTAPS)
for (int i = 0; i<ch->nb_taps;i++)
free(ch->R_sqrt[i]);
free(ch->R_sqrt);
free(ch->ch);
free(ch->chF);
free(ch->a);
free(ch);
}
void set_channeldesc_owner(channel_desc_t *cdesc, uint32_t module_id) {
cdesc->module_id=module_id;
}
int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) {
@@ -1726,11 +1772,11 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) {
desc->ch[aarx+(aatx*desc->nb_rx)][k].y = 0.0;
for (l=0; l<desc->nb_taps; l++) {
if ((k - (desc->delays[l]*desc->sampling_rate) - NB_SAMPLES_CHANNEL_OFFSET) == 0)
if ((k - (desc->delays[l]*desc->sampling_rate) - desc->channel_offset) == 0)
s = 1.0;
else
s = sin(M_PI*(k - (desc->delays[l]*desc->sampling_rate) - NB_SAMPLES_CHANNEL_OFFSET))/
(M_PI*(k - (desc->delays[l]*desc->sampling_rate) - NB_SAMPLES_CHANNEL_OFFSET));
s = sin(M_PI*(k - (desc->delays[l]*desc->sampling_rate) - desc->channel_offset))/
(M_PI*(k - (desc->delays[l]*desc->sampling_rate) - desc->channel_offset));
desc->ch[aarx+(aatx*desc->nb_rx)][k].x += s*desc->a[l][aarx+(aatx*desc->nb_rx)].x;
desc->ch[aarx+(aatx*desc->nb_rx)][k].y += s*desc->a[l][aarx+(aatx*desc->nb_rx)].y;
@@ -1753,7 +1799,7 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) {
return (0);
}
double N_RB2sampling_rate(uint16_t N_RB) {
double sampling_rate;
@@ -1805,22 +1851,125 @@ double N_RB2channel_bandwidth(uint16_t N_RB) {
LOG_E(PHY,"Unknown N_PRB\n");
return(-1);
}
return(channel_bandwidth);
}
static int channelmod_print_help(char *buff, int debug, telnet_printfunc_t prnt ) {
prnt("channelmod commands can be used to display or modify channel models parameters\n");
prnt("channelmod show predef: display predefined model algorithms available in oai\n");
prnt("channelmod show current: display the currently used models in the running executable\n");
prnt("channelmod modify <model index> <param name> <param value>: set the specified parameters in a current model to the given value\n");
prnt(" <model index> specifies the model, the show current model command can be used to list the current models indexes\n");
prnt(" <param name> can be one of \"riceanf\", \"aoa\", \"randaoa\", \"ploss\", \"offset\", \"forgetf\"\n");
return CMDSTATUS_FOUND;
}
static void display_channelmodel(channel_desc_t *cd,int debug, telnet_printfunc_t prnt) {
char *module_id_str[]=MODULEID_STR_INIT;
if (cd->module_id != 0) {
prnt("model owner: %s\n",module_id_str[cd->module_id]);
}
prnt("nb_tx: %i nb_rx: %i taps: %i bandwidth: %lf sampling: %lf\n",cd->nb_tx, cd->nb_rx, cd->nb_taps, cd->channel_bandwidth, cd->sampling_rate);
prnt("channel length: %i Max path delay: %lf ricean fact.: %lf angle of arrival: %lf (randomized:%s)\n",
cd->channel_length, cd->Td, cd->ricean_factor, cd->aoa, (cd->random_aoa?"Yes":"No"));
prnt("max Doppler: %lf path loss: %lf rchannel offset: %i forget factor; %lf\n",
cd->max_Doppler, cd->path_loss_dB, cd->channel_offset, cd->forgetting_factor);
prnt("Initial phase: %lf nb_path: %i \n",
cd->ip, cd->nb_paths);
for (int i=0; i<cd->nb_taps ; i++) {
prnt("taps: %i lin. ampli. : %lf delay: %lf \n",i,cd->amps[i], cd->delays[i]);
}
}
static int channelmod_show_cmd(char *buff, int debug, telnet_printfunc_t prnt) {
for(int i=0; channelmod_names[i].name != NULL ; i++) {
prnt(" %i %s\n", i, map_int_to_str(channelmod_names,i ));
}
char *subcmd=NULL;
int s = sscanf(buff,"%ms\n",&subcmd);
return 0;
if (s>0) {
if ( strcmp(subcmd,"predef") == 0) {
for (int i=0; channelmod_names[i].name != NULL ; i++) {
prnt(" %i %s\n", i, map_int_to_str(channelmod_names,i ));
}
} else if ( strcmp(subcmd,"current") == 0) {
for (int i=0; i < max_chan ; i++) {
if (defined_channels[i] != NULL) {
prnt("model %i %s: \n----------------\n", i, map_int_to_str(channelmod_names,defined_channels[i]->modelid));
display_channelmodel(defined_channels[i],debug,prnt);
}
}
} else {
channelmod_print_help(buff, debug, prnt);
}
free(subcmd);
}
return CMDSTATUS_FOUND;
}
int modelid_fromname(char *modelname) {
int modelid=map_str_to_int(channelmod_names,modelname);
AssertFatal(modelid>0,
"random_channel.c: Error channel model %s unknown\n",modelname);
static int channelmod_modify_cmd(char *buff, int debug, telnet_printfunc_t prnt) {
char *param=NULL, *value=NULL;
int cd_id= -1;
int s = sscanf(buff,"%i %ms %ms \n",&cd_id,&param, &value);
if (cd_id<0 || cd_id >= max_chan) {
prnt("ERROR, %i: Channel model id outof range (0-%i)\n",cd_id,max_chan-1);
return CMDSTATUS_FOUND;
}
if (defined_channels[cd_id]==NULL) {
prnt("ERROR, %i: Channel model has not been set\n",cd_id);
return CMDSTATUS_FOUND;
}
if (s==3) {
if ( strcmp(param,"riceanf") == 0) {
double dbl = atof(value);
if (dbl <0 || dbl > 1)
prnt("ERROR: ricean factor range: 0 to 1, %lf is outof range\n",dbl);
else
defined_channels[cd_id]->ricean_factor=dbl;
} else if ( strcmp(param,"aoa") == 0) {
double dbl = atof(value);
if (dbl <0 || dbl >6.28)
prnt("ERROR: angle of arrival range: 0 to 2*Pi, %lf is outof range\n",dbl);
else
defined_channels[cd_id]->aoa=dbl;
} else if ( strcmp(param,"randaoa") == 0) {
int i = atoi(value);
if (i!=0 && i!=1)
prnt("ERROR: randaoa is a boolean, must be 0 or 1\n");
else
defined_channels[cd_id]->random_aoa=i;
} else if ( strcmp(param,"ploss") == 0) {
double dbl = atof(value);
defined_channels[cd_id]->path_loss_dB=dbl;
} else if ( strcmp(param,"offset") == 0) {
int i = atoi(value);
defined_channels[cd_id]->channel_offset=i;
} else if ( strcmp(param,"forgetf") == 0) {
double dbl = atof(value);
if (dbl <0 || dbl > 1)
prnt("ERROR: forgetting factor range: 0 to 1 (disable variation), %lf is outof range\n",dbl);
else
defined_channels[cd_id]->forgetting_factor=dbl;
} else {
prnt("ERROR: %s, unknown channel parameter\n",param);
return CMDSTATUS_FOUND;
}
display_channelmodel(defined_channels[cd_id],debug,prnt);
free(param);
free(value);
random_channel(defined_channels[cd_id],false);
}
return CMDSTATUS_FOUND;
}
int modelid_fromname(char *modelname) {
int modelid=map_str_to_int(channelmod_names,modelname);
if (modelid < 0)
LOG_E(OCM,"random_channel.c: Error channel model %s unknown\n",modelname);
return modelid;
}
@@ -1836,6 +1985,9 @@ void init_channelmod(void) {
paramdef_t channelmod_params[] = CHANNELMOD_PARAMS_DESC;
int ret = config_get( channelmod_params,sizeof(channelmod_params)/sizeof(paramdef_t),CHANNELMOD_SECTION);
AssertFatal(ret >= 0, "configuration couldn't be performed");
defined_channels=calloc(max_chan,sizeof( channel_desc_t*));
AssertFatal(defined_channels!=NULL, "couldn't allocate %u channel descriptors\n",max_chan);
/* look for telnet server, if it is loaded, add the channel modeling commands to it */
add_telnetcmd_func_t addcmd = (add_telnetcmd_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_ADDCMD_FNAME);
+32 -4
View File
@@ -40,6 +40,16 @@ The present clause specifies several numerical functions for testing of digital
#define NB_SAMPLES_CHANNEL_OFFSET 4
typedef enum {
UNSPECIFIED_MODID=0,
RFSIMU_MODULEID=1
} channelmod_moduleid_t;
#define MODULEID_STR_INIT {"","rfsimulator"}
#define CHANMODEL_FREE_DELAY 1<<0
#define CHANMODEL_FREE_RSQRT_6 1<<1
#define CHANMODEL_FREE_RSQRT_NTAPS 1<<2
#define CHANMODEL_FREE_AMPS 1<<3
typedef struct {
///Number of tx antennas
uint8_t nb_tx;
@@ -92,6 +102,14 @@ typedef struct {
time_stats_t interp_time;
time_stats_t interp_freq;
time_stats_t convolution;
/// index in the channel descriptors array
unsigned int chan_idx;
/// id of the channel modeling algorithm
int modelid;
/// identifies channel descriptor owner (the module which created this descriptor)
channelmod_moduleid_t module_id;
/// flags to properly trigger memory free
unsigned int free_flags;
} channel_desc_t;
typedef struct {
@@ -224,8 +242,9 @@ typedef enum {
#define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\n"
#define CHANNELMOD_SECTION "channelmod"
#define CHANNELMOD_PARAMS_DESC { \
{"s" , CONFIG_HLP_SNR, PARAMFLAG_CMDLINE_NOPREFIXENABLED, dblptr:&snr_dB , defdblval:25, TYPE_DOUBLE, 0},\
{"sinr_dB", NULL , 0 , dblptr:&sinr_dB, defdblval:0 , TYPE_DOUBLE, 0},\
{"s" , CONFIG_HLP_SNR, PARAMFLAG_CMDLINE_NOPREFIXENABLED, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0},\
{"sinr_dB", NULL, 0 , dblptr:&sinr_dB, defdblval:0 , TYPE_DOUBLE, 0},\
{"max_chan, CONFIG_HLP_MAX_CHAN", 0, uptr:&max_chan, defintval:10, TYPE_UINT, 0},\
}
#include "platform_constants.h"
@@ -262,9 +281,18 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
double forgetting_factor,
int32_t channel_offset,
double path_loss_dB);
/**
\brief free memory allocated for a model descriptor
\param ch points to the model, which cannot be used after calling this fuction
*/
void free_channel_desc_scm(channel_desc_t *ch);
/**
\brief This set the ownerid of a model descriptor, can be later used to check what module created a channel model
\param cdesc points to the model descriptor
\param module_id identifies the channel model. should be define as a macro in simu.h
*/
void set_channeldesc_owner(channel_desc_t *cdesc, channelmod_moduleid_t module_id);
/** \fn void random_channel(channel_desc_t *desc)
\brief This routine generates a random channel response (time domain) according to a tapped delay line model.
\param desc Pointer to the channel descriptor
@@ -49,18 +49,13 @@ struct lfds700_misc_prng_state ps[NUM_MAX_ENB];
struct lfds700_ringbuffer_element *dl_mac_config_array[NUM_MAX_ENB];
struct lfds700_ringbuffer_state ringbuffer_state[NUM_MAX_ENB];
/* the slice config as kept in the underlying system */
Protocol__FlexSliceConfig *slice_config[MAX_NUM_SLICES];
/* a structure that keeps updates which will be reflected in slice_config later */
Protocol__FlexSliceConfig *sc_update[MAX_NUM_SLICES];
/* indicates whether sc_update contains new data */
int perform_slice_config_update_count = 1;
/* queue of incoming new UE<>slice association commands */
Protocol__FlexUeConfig *ue_slice_assoc_update[MAX_NUM_SLICES];
int n_ue_slice_assoc_updates = 0;
/* mutex for sc_update: do not receive new config and write it at the same time */
pthread_mutex_t sc_update_mtx = PTHREAD_MUTEX_INITIALIZER;
/* Ringbuffer-related to slice configuration */
struct lfds700_ringbuffer_element *slice_config_array[NUM_MAX_ENB];
struct lfds700_ringbuffer_state slice_config_ringbuffer_state[NUM_MAX_ENB];
/* Ringbuffer-related to slice configuration */
struct lfds700_ringbuffer_element *ue_assoc_array[NUM_MAX_ENB];
struct lfds700_ringbuffer_state ue_assoc_ringbuffer_state[NUM_MAX_ENB];
int flexran_agent_mac_stats_reply_ue(mid_t mod_id,
Protocol__FlexUeStatsReport **ue_report,
@@ -1354,6 +1349,33 @@ void flexran_agent_init_mac_agent(mid_t mod_id) {
AssertFatal(i == 0, "posix_memalign(): could not allocate aligned memory for lfds library\n");
lfds700_ringbuffer_init_valid_on_current_logical_core(&ringbuffer_state[mod_id],
dl_mac_config_array[mod_id], num_elements, &ps[mod_id], NULL);
struct lfds700_misc_prng_state scrng;
i = posix_memalign((void **) &slice_config_array[mod_id],
LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES,
sizeof(struct lfds700_ringbuffer_element) * num_elements);
AssertFatal(i == 0,
"posix_memalign(): could not allocate aligned memory\n");
lfds700_ringbuffer_init_valid_on_current_logical_core(
&slice_config_ringbuffer_state[mod_id],
slice_config_array[mod_id],
num_elements,
&scrng,
NULL);
struct lfds700_misc_prng_state uarng;
i = posix_memalign((void **) &ue_assoc_array[mod_id],
LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES,
sizeof(struct lfds700_ringbuffer_element) * num_elements);
AssertFatal(i == 0,
"posix_memalign(): could not allocate aligned memory\n");
lfds700_ringbuffer_init_valid_on_current_logical_core(
&ue_assoc_ringbuffer_state[mod_id],
ue_assoc_array[mod_id],
num_elements,
&uarng,
NULL);
for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
for (j = 0; j < 8; j++) {
if (RC.mac && RC.mac[mod_id])
@@ -1465,9 +1487,74 @@ void flexran_agent_fill_mac_cell_config(mid_t mod_id, uint8_t cc_id,
conf->si_config->has_sfn = 1;
}
/* get a pointer to the config which is maintained in the agent throughout
* its lifetime */
conf->slice_config = flexran_agent_get_slice_config(mod_id);
conf->slice_config = malloc(sizeof(Protocol__FlexSliceConfig));
if (conf->slice_config) {
protocol__flex_slice_config__init(conf->slice_config);
Protocol__FlexSliceConfig *sc = conf->slice_config;
sc->dl = malloc(sizeof(Protocol__FlexSliceDlUlConfig));
DevAssert(sc->dl);
protocol__flex_slice_dl_ul_config__init(sc->dl);
sc->dl->algorithm = flexran_get_dl_slice_algo(mod_id);
sc->dl->has_algorithm = 1;
sc->dl->n_slices = flexran_get_num_dl_slices(mod_id);
if (sc->dl->n_slices > 0) {
sc->dl->slices = calloc(sc->dl->n_slices, sizeof(Protocol__FlexSlice *));
DevAssert(sc->dl->slices);
for (int i = 0; i < sc->dl->n_slices; ++i) {
sc->dl->slices[i] = malloc(sizeof(Protocol__FlexSlice));
DevAssert(sc->dl->slices[i]);
protocol__flex_slice__init(sc->dl->slices[i]);
flexran_get_dl_slice(mod_id, i, sc->dl->slices[i], sc->dl->algorithm);
}
} else {
sc->dl->scheduler = flexran_get_dl_scheduler_name(mod_id);
}
sc->ul = malloc(sizeof(Protocol__FlexSliceDlUlConfig));
DevAssert(sc->ul);
protocol__flex_slice_dl_ul_config__init(sc->ul);
sc->ul->algorithm = flexran_get_ul_slice_algo(mod_id);
sc->ul->has_algorithm = 1;
sc->ul->n_slices = flexran_get_num_ul_slices(mod_id);
if (sc->ul->n_slices > 0) {
sc->ul->slices = calloc(sc->ul->n_slices, sizeof(Protocol__FlexSlice *));
DevAssert(sc->ul->slices);
for (int i = 0; i < sc->ul->n_slices; ++i) {
sc->ul->slices[i] = malloc(sizeof(Protocol__FlexSlice));
DevAssert(sc->ul->slices[i]);
protocol__flex_slice__init(sc->ul->slices[i]);
flexran_get_ul_slice(mod_id, i, sc->ul->slices[i], sc->ul->algorithm);
}
} else {
sc->ul->scheduler = flexran_get_ul_scheduler_name(mod_id);
}
}
}
void flexran_agent_destroy_mac_slice_config(Protocol__FlexCellConfig *conf) {
Protocol__FlexSliceConfig *sc = conf->slice_config;
for (int i = 0; i < sc->dl->n_slices; ++i) {
free(sc->dl->slices[i]);
sc->dl->slices[i] = NULL;
/* scheduler names are not freed: we assume we read them directly from the
* underlying memory and do not dispose it */
}
free(sc->dl->slices);
/* scheduler name is not freed */
free(sc->dl);
sc->dl = NULL;
for (int i = 0; i < sc->ul->n_slices; ++i) {
free(sc->ul->slices[i]);
sc->ul->slices[i] = NULL;
/* scheduler names are not freed */
}
free(sc->ul->slices);
/* scheduler name is not freed */
free(sc->ul);
sc->ul = NULL;
free(conf->slice_config);
conf->slice_config = NULL;
}
void flexran_agent_fill_mac_ue_config(mid_t mod_id, mid_t ue_id,
@@ -1481,10 +1568,12 @@ void flexran_agent_fill_mac_ue_config(mid_t mod_id, mid_t ue_id,
ue_conf->rnti = flexran_get_mac_ue_crnti(mod_id, ue_id);
ue_conf->has_rnti = 1;
ue_conf->dl_slice_id = flexran_get_ue_dl_slice_id(mod_id, ue_id);
ue_conf->has_dl_slice_id = 1;
ue_conf->ul_slice_id = flexran_get_ue_ul_slice_id(mod_id, ue_id);
ue_conf->has_ul_slice_id = 1;
int dl_id = flexran_get_ue_dl_slice_id(mod_id, ue_id);
ue_conf->dl_slice_id = dl_id;
ue_conf->has_dl_slice_id = dl_id >= 0;
int ul_id = flexran_get_ue_ul_slice_id(mod_id, ue_id);
ue_conf->ul_slice_id = ul_id;
ue_conf->has_ul_slice_id = ul_id >= 0;
ue_conf->ue_aggregated_max_bitrate_ul = flexran_get_ue_aggregated_max_bitrate_ul(mod_id, ue_id);
ue_conf->has_ue_aggregated_max_bitrate_ul = 1;
@@ -1565,6 +1654,15 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id)
LOG_E(FLEXRAN_AGENT, "MAC agent CM for eNB %d is not registered\n", mod_id);
return -1;
}
lfds700_ringbuffer_cleanup(&ringbuffer_state[mod_id], NULL );
free(dl_mac_config_array[mod_id]);
lfds700_ringbuffer_cleanup(&slice_config_ringbuffer_state[mod_id], NULL );
free(slice_config_array[mod_id]);
lfds700_ringbuffer_cleanup(&ue_assoc_ringbuffer_state[mod_id], NULL );
free(ue_assoc_array[mod_id]);
lfds700_misc_library_cleanup();
AGENT_MAC_xface *xface = agent_mac_xface[mod_id];
xface->flexran_agent_send_sr_info = NULL;
xface->flexran_agent_send_sf_trigger = NULL;
@@ -1579,230 +1677,91 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id)
return 0;
}
void flexran_create_config_structures(mid_t mod_id)
{
int i;
int n_dl = flexran_get_num_dl_slices(mod_id);
int m_ul = flexran_get_num_ul_slices(mod_id);
slice_config[mod_id] = flexran_agent_create_slice_config(n_dl, m_ul);
sc_update[mod_id] = flexran_agent_create_slice_config(n_dl, m_ul);
if (!slice_config[mod_id] || !sc_update[mod_id]) return;
flexran_agent_read_slice_config(mod_id, slice_config[mod_id]);
flexran_agent_read_slice_config(mod_id, sc_update[mod_id]);
for (i = 0; i < n_dl; i++) {
flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]);
flexran_agent_read_slice_dl_config(mod_id, i, sc_update[mod_id]->dl[i]);
void helper_destroy_mac_slice_config(Protocol__FlexSliceConfig *slice_config) {
if (slice_config->dl) {
if (slice_config->dl->scheduler)
free(slice_config->dl->scheduler);
for (int i = 0; i < slice_config->dl->n_slices; i++)
if (slice_config->dl->slices[i]->scheduler)
free(slice_config->dl->slices[i]->scheduler);
}
for (i = 0; i < m_ul; i++) {
flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]);
flexran_agent_read_slice_ul_config(mod_id, i, sc_update[mod_id]->ul[i]);
if (slice_config->ul) {
if (slice_config->ul->scheduler)
free(slice_config->ul->scheduler);
for (int i = 0; i < slice_config->ul->n_slices; i++)
if (slice_config->ul->slices[i]->scheduler)
free(slice_config->ul->slices[i]->scheduler);
}
Protocol__FlexCellConfig helper;
helper.slice_config = slice_config;
flexran_agent_destroy_mac_slice_config(&helper);
}
void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig **slice_config) {
if (!*slice_config) return;
/* just use the memory and set to NULL in original */
Protocol__FlexSliceConfig *sc = *slice_config;
*slice_config = NULL;
struct lfds700_misc_prng_state ls;
LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
lfds700_misc_prng_init(&ls);
enum lfds700_misc_flag overwrite_occurred_flag;
Protocol__FlexSliceConfig *overwritten_sc;
lfds700_ringbuffer_write(&slice_config_ringbuffer_state[mod_id],
NULL,
(void *)sc,
&overwrite_occurred_flag,
NULL,
(void **)&overwritten_sc,
&ls);
if (overwrite_occurred_flag == LFDS700_MISC_FLAG_RAISED) {
helper_destroy_mac_slice_config(overwritten_sc);
LOG_E(FLEXRAN_AGENT, "lost slice config: too many reconfigurations at once\n");
}
}
void flexran_check_and_remove_slices(mid_t mod_id)
{
Protocol__FlexDlSlice **dl = sc_update[mod_id]->dl;
Protocol__FlexDlSlice **dlreal = slice_config[mod_id]->dl;
int i = 0;
while (i < sc_update[mod_id]->n_dl) {
/* remove slices whose percentage is zero */
if (dl[i]->percentage > 0) {
++i;
continue;
}
if (flexran_remove_dl_slice(mod_id, i) < 1) {
LOG_W(FLEXRAN_AGENT, "[%d] can not remove slice index %d ID %d\n",
mod_id, i, dl[i]->id);
++i;
continue;
}
LOG_I(FLEXRAN_AGENT, "[%d] removed slice index %d ID %d\n",
mod_id, i, dl[i]->id);
if (dl[i]->n_sorting > 0) free(dl[i]->sorting);
free(dl[i]->scheduler_name);
if (dlreal[i]->n_sorting > 0) {
dlreal[i]->n_sorting = 0;
free(dlreal[i]->sorting);
}
free(dlreal[i]->scheduler_name);
--sc_update[mod_id]->n_dl;
--slice_config[mod_id]->n_dl;
const size_t last = sc_update[mod_id]->n_dl;
/* we need to memcpy the higher slice to the position we just deleted */
memcpy(dl[i], dl[last], sizeof(*dl[last]));
memset(dl[last], 0, sizeof(*dl[last]));
memcpy(dlreal[i], dlreal[last], sizeof(*dlreal[last]));
memset(dlreal[last], 0, sizeof(*dlreal[last]));
/* dont increase i but recheck the slice which has been copied to here */
}
Protocol__FlexUlSlice **ul = sc_update[mod_id]->ul;
Protocol__FlexUlSlice **ulreal = slice_config[mod_id]->ul;
i = 0;
while (i < sc_update[mod_id]->n_ul) {
if (ul[i]->percentage > 0) {
++i;
continue;
}
if (flexran_remove_ul_slice(mod_id, i) < 1) {
LOG_W(FLEXRAN_AGENT, "[%d] can not remove slice index %d ID %d\n",
mod_id, i, ul[i]->id);
++i;
continue;
}
LOG_I(FLEXRAN_AGENT, "[%d] removed slice index %d ID %d\n",
mod_id, i, ul[i]->id);
free(ul[i]->scheduler_name);
free(ulreal[i]->scheduler_name);
--sc_update[mod_id]->n_ul;
--slice_config[mod_id]->n_ul;
const size_t last = sc_update[mod_id]->n_ul;
/* see DL remarks */
memcpy(ul[i], ul[last], sizeof(*ul[last]));
memset(ul[last], 0, sizeof(*ul[last]));
memcpy(ulreal[i], ulreal[last], sizeof(*ulreal[last]));
memset(ulreal[last], 0, sizeof(*ulreal[last]));
/* dont increase i but recheck the slice which has been copied to here */
void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig **ue_config) {
struct lfds700_misc_prng_state ls;
LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
lfds700_misc_prng_init(&ls);
enum lfds700_misc_flag overwrite_occurred_flag;
Protocol__FlexUeConfig *overwritten_ue_config;
lfds700_ringbuffer_write(&ue_assoc_ringbuffer_state[mod_id],
NULL,
(void *) *ue_config,
&overwrite_occurred_flag,
NULL,
(void **)&overwritten_ue_config,
&ls);
if (overwrite_occurred_flag == LFDS700_MISC_FLAG_RAISED) {
free(overwritten_ue_config);
LOG_E(FLEXRAN_AGENT, "lost UE-slice association: too many UE-slice associations at once\n");
}
}
void flexran_agent_slice_update(mid_t mod_id)
{
int i;
int changes = 0;
void flexran_agent_slice_update(mid_t mod_id) {
struct lfds700_misc_prng_state ls;
LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
lfds700_misc_prng_init(&ls);
if (perform_slice_config_update_count <= 0) return;
perform_slice_config_update_count--;
pthread_mutex_lock(&sc_update_mtx);
if (!slice_config[mod_id]) {
/* if the configuration does not exist for agent, create from eNB structure
* and exit */
flexran_create_config_structures(mod_id);
pthread_mutex_unlock(&sc_update_mtx);
return;
Protocol__FlexSliceConfig *sc = NULL;
struct lfds700_ringbuffer_state *state = &slice_config_ringbuffer_state[mod_id];
if (lfds700_ringbuffer_read(state, NULL, (void **) &sc, &ls) != 0) {
apply_update_dl_slice_config(mod_id, sc->dl);
apply_update_ul_slice_config(mod_id, sc->ul);
helper_destroy_mac_slice_config(sc);
}
/********* read existing config *********/
/* simply update slice_config all the time and write new config
* (apply_new_slice_dl_config() only updates if changes are necessary) */
slice_config[mod_id]->n_dl = flexran_get_num_dl_slices(mod_id);
slice_config[mod_id]->n_ul = flexran_get_num_ul_slices(mod_id);
for (i = 0; i < slice_config[mod_id]->n_dl; i++) {
flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]);
Protocol__FlexUeConfig *ue_config = NULL;
state = &ue_assoc_ringbuffer_state[mod_id];
if (lfds700_ringbuffer_read(state, NULL, (void **) &ue_config, &ls) != 0) {
apply_ue_slice_assoc_update(mod_id, ue_config);
free(ue_config);
}
for (i = 0; i < slice_config[mod_id]->n_ul; i++) {
flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]);
}
/********* write new config *********/
/* check for removal (sc_update[X]->dl[Y].percentage == 0)
* and update sc_update & slice_config accordingly */
flexran_check_and_remove_slices(mod_id);
/* create new DL and UL slices if necessary */
for (i = slice_config[mod_id]->n_dl; i < sc_update[mod_id]->n_dl; i++) {
flexran_create_dl_slice(mod_id, sc_update[mod_id]->dl[i]->id);
}
for (i = slice_config[mod_id]->n_ul; i < sc_update[mod_id]->n_ul; i++) {
flexran_create_ul_slice(mod_id, sc_update[mod_id]->ul[i]->id);
}
slice_config[mod_id]->n_dl = flexran_get_num_dl_slices(mod_id);
slice_config[mod_id]->n_ul = flexran_get_num_ul_slices(mod_id);
changes += apply_new_slice_config(mod_id, slice_config[mod_id], sc_update[mod_id]);
for (i = 0; i < slice_config[mod_id]->n_dl; i++) {
changes += apply_new_slice_dl_config(mod_id,
slice_config[mod_id]->dl[i],
sc_update[mod_id]->dl[i]);
flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]);
}
for (i = 0; i < slice_config[mod_id]->n_ul; i++) {
changes += apply_new_slice_ul_config(mod_id,
slice_config[mod_id]->ul[i],
sc_update[mod_id]->ul[i]);
flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]);
}
flexran_agent_read_slice_config(mod_id, slice_config[mod_id]);
if (n_ue_slice_assoc_updates > 0) {
changes += apply_ue_slice_assoc_update(mod_id);
}
if (changes > 0)
LOG_I(FLEXRAN_AGENT, "[%d] slice configuration: applied %d changes\n", mod_id, changes);
pthread_mutex_unlock(&sc_update_mtx);
}
Protocol__FlexSliceConfig *flexran_agent_get_slice_config(mid_t mod_id)
{
if (!slice_config[mod_id]) return NULL;
Protocol__FlexSliceConfig *config = NULL;
pthread_mutex_lock(&sc_update_mtx);
config = flexran_agent_create_slice_config(slice_config[mod_id]->n_dl,
slice_config[mod_id]->n_ul);
if (!config) {
pthread_mutex_unlock(&sc_update_mtx);
return NULL;
}
config->has_intraslice_share_active = 1;
config->intraslice_share_active = slice_config[mod_id]->intraslice_share_active;
config->has_interslice_share_active = 1;
config->interslice_share_active = slice_config[mod_id]->interslice_share_active;
for (int i = 0; i < slice_config[mod_id]->n_dl; ++i) {
if (!config->dl[i]) continue;
config->dl[i]->has_id = 1;
config->dl[i]->id = slice_config[mod_id]->dl[i]->id;
config->dl[i]->has_label = 1;
config->dl[i]->label = slice_config[mod_id]->dl[i]->label;
config->dl[i]->has_percentage = 1;
config->dl[i]->percentage = slice_config[mod_id]->dl[i]->percentage;
config->dl[i]->has_isolation = 1;
config->dl[i]->isolation = slice_config[mod_id]->dl[i]->isolation;
config->dl[i]->has_priority = 1;
config->dl[i]->priority = slice_config[mod_id]->dl[i]->priority;
config->dl[i]->has_position_low = 1;
config->dl[i]->position_low = slice_config[mod_id]->dl[i]->position_low;
config->dl[i]->has_position_high = 1;
config->dl[i]->position_high = slice_config[mod_id]->dl[i]->position_high;
config->dl[i]->has_maxmcs = 1;
config->dl[i]->maxmcs = slice_config[mod_id]->dl[i]->maxmcs;
config->dl[i]->n_sorting = slice_config[mod_id]->dl[i]->n_sorting;
config->dl[i]->sorting = calloc(config->dl[i]->n_sorting, sizeof(Protocol__FlexDlSorting));
if (!config->dl[i]->sorting) config->dl[i]->n_sorting = 0;
for (int j = 0; j < config->dl[i]->n_sorting; ++j)
config->dl[i]->sorting[j] = slice_config[mod_id]->dl[i]->sorting[j];
config->dl[i]->has_accounting = 1;
config->dl[i]->accounting = slice_config[mod_id]->dl[i]->accounting;
config->dl[i]->scheduler_name = strdup(slice_config[mod_id]->dl[i]->scheduler_name);
}
for (int i = 0; i < slice_config[mod_id]->n_ul; ++i) {
if (!config->ul[i]) continue;
config->ul[i]->has_id = 1;
config->ul[i]->id = slice_config[mod_id]->ul[i]->id;
config->ul[i]->has_label = 1;
config->ul[i]->label = slice_config[mod_id]->ul[i]->label;
config->ul[i]->has_percentage = 1;
config->ul[i]->percentage = slice_config[mod_id]->ul[i]->percentage;
config->ul[i]->has_isolation = 1;
config->ul[i]->isolation = slice_config[mod_id]->ul[i]->isolation;
config->ul[i]->has_priority = 1;
config->ul[i]->priority = slice_config[mod_id]->ul[i]->priority;
config->ul[i]->has_first_rb = 1;
config->ul[i]->first_rb = slice_config[mod_id]->ul[i]->first_rb;
config->ul[i]->has_maxmcs = 1;
config->ul[i]->maxmcs = slice_config[mod_id]->ul[i]->maxmcs;
config->ul[i]->n_sorting = slice_config[mod_id]->ul[i]->n_sorting;
config->ul[i]->sorting = calloc(config->ul[i]->n_sorting, sizeof(Protocol__FlexUlSorting));
if (!config->ul[i]->sorting) config->ul[i]->n_sorting = 0;
for (int j = 0; j < config->ul[i]->n_sorting; ++j)
config->ul[i]->sorting[j] = slice_config[mod_id]->ul[i]->sorting[j];
config->ul[i]->has_accounting = 1;
config->ul[i]->accounting = slice_config[mod_id]->ul[i]->accounting;
config->ul[i]->scheduler_name = strdup(slice_config[mod_id]->ul[i]->scheduler_name);
}
pthread_mutex_unlock(&sc_update_mtx);
return config;
}
@@ -115,7 +115,16 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id);
/* Inform controller about possibility to update slice configuration */
void flexran_agent_slice_update(mid_t mod_id);
/* return a pointer to the current config */
Protocol__FlexSliceConfig *flexran_agent_get_slice_config(mid_t mod_id);
/* marks slice_config so that it can be applied later. Takes ownership of the
* FlexSliceConfig message */
void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig **slice);
/* inserts a new ue_config into the structure keeping ue to slice association
* updates and marks so it can be applied. Takes ownership of the FlexUeConfig message */
void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig **ue_config);
/* free slice_config part of flexCellConfig, filled in
* flexran_agent_fill_mac_cell_config() */
void flexran_agent_destroy_mac_slice_config(Protocol__FlexCellConfig *conf);
#endif
@@ -33,14 +33,6 @@
#include "flexran_agent_mac_internal.h"
#include "flexran_agent_mac_slice_verification.h"
/* from flexran_agent_mac.c */
extern Protocol__FlexSliceConfig *slice_config[MAX_NUM_SLICES];
extern Protocol__FlexSliceConfig *sc_update[MAX_NUM_SLICES];
extern int perform_slice_config_update_count;
extern Protocol__FlexUeConfig *ue_slice_assoc_update[MAX_NUM_SLICES];
extern int n_ue_slice_assoc_updates;
extern pthread_mutex_t sc_update_mtx;
Protocol__FlexranMessage * flexran_agent_generate_diff_mac_stats_report(Protocol__FlexranMessage *new_message,
Protocol__FlexranMessage *old_message) {
@@ -1033,724 +1025,166 @@ int load_dl_scheduler_function(mid_t mod_id, const char *function_name) {
}
Protocol__FlexSliceConfig *flexran_agent_create_slice_config(int n_dl, int m_ul)
{
int i;
Protocol__FlexSliceConfig *fsc = malloc(sizeof(Protocol__FlexSliceConfig));
if (!fsc) return NULL;
protocol__flex_slice_config__init(fsc);
/* say there are n_dl slices but reserve memory for up to MAX_NUM_SLICES so
* we don't need to reserve again later */
fsc->n_dl = n_dl;
fsc->dl = calloc(MAX_NUM_SLICES, sizeof(Protocol__FlexDlSlice *));
if (!fsc->dl) fsc->n_dl = 0;
for (i = 0; i < MAX_NUM_SLICES; i++) {
fsc->dl[i] = malloc(sizeof(Protocol__FlexDlSlice));
if (!fsc->dl[i]) continue;
protocol__flex_dl_slice__init(fsc->dl[i]);
}
/* as above */
fsc->n_ul = m_ul;
fsc->ul = calloc(MAX_NUM_SLICES, sizeof(Protocol__FlexUlSlice *));
if (!fsc->ul) fsc->n_ul = 0;
for (i = 0; i < MAX_NUM_SLICES; i++) {
fsc->ul[i] = malloc(sizeof(Protocol__FlexUlSlice));
if (!fsc->ul[i]) continue;
protocol__flex_ul_slice__init(fsc->ul[i]);
}
return fsc;
}
void flexran_agent_read_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *s)
{
s->intraslice_share_active = flexran_get_intraslice_sharing_active(mod_id);
s->has_intraslice_share_active = 1;
s->interslice_share_active = flexran_get_interslice_sharing_active(mod_id);
s->has_interslice_share_active = 1;
}
void flexran_agent_read_slice_dl_config(mid_t mod_id, int slice_idx, Protocol__FlexDlSlice *dl_slice)
{
dl_slice->id = flexran_get_dl_slice_id(mod_id, slice_idx);
dl_slice->has_id = 1;
/* read label from corresponding sc_update entry or give default */
dl_slice->label = PROTOCOL__FLEX_SLICE_LABEL__xMBB;
dl_slice->has_label = 1;
for (int i = 0; i < sc_update[mod_id]->n_dl; i++) {
if (sc_update[mod_id]->dl[i]->id == dl_slice->id
&& sc_update[mod_id]->dl[i]->has_label) {
dl_slice->label = sc_update[mod_id]->dl[i]->label;
break;
}
}
dl_slice->percentage = flexran_get_dl_slice_percentage(mod_id, slice_idx);
dl_slice->has_percentage = 1;
dl_slice->isolation = flexran_get_dl_slice_isolation(mod_id, slice_idx);
dl_slice->has_isolation = 1;
dl_slice->priority = flexran_get_dl_slice_priority(mod_id, slice_idx);
dl_slice->has_priority = 1;
dl_slice->position_low = flexran_get_dl_slice_position_low(mod_id, slice_idx);
dl_slice->has_position_low = 1;
dl_slice->position_high = flexran_get_dl_slice_position_high(mod_id, slice_idx);
dl_slice->has_position_high = 1;
dl_slice->maxmcs = flexran_get_dl_slice_maxmcs(mod_id, slice_idx);
dl_slice->has_maxmcs = 1;
dl_slice->n_sorting = flexran_get_dl_slice_sorting(mod_id, slice_idx, &dl_slice->sorting);
if (dl_slice->n_sorting < 1) dl_slice->sorting = NULL;
dl_slice->accounting = flexran_get_dl_slice_accounting_policy(mod_id, slice_idx);
dl_slice->has_accounting = 1;
const char *s_name = flexran_get_dl_slice_scheduler(mod_id, slice_idx);
if (!dl_slice->scheduler_name
|| strcmp(dl_slice->scheduler_name, s_name) != 0) {
dl_slice->scheduler_name = realloc(dl_slice->scheduler_name, strlen(s_name) + 1);
strcpy(dl_slice->scheduler_name, s_name);
}
}
void flexran_agent_read_slice_ul_config(mid_t mod_id, int slice_idx, Protocol__FlexUlSlice *ul_slice)
{
ul_slice->id = flexran_get_ul_slice_id(mod_id, slice_idx);
ul_slice->has_id = 1;
/* read label from corresponding sc_update entry or give default */
ul_slice->label = PROTOCOL__FLEX_SLICE_LABEL__xMBB;
ul_slice->has_label = 1;
for (int i = 0; i < sc_update[mod_id]->n_ul; i++) {
if (sc_update[mod_id]->ul[i]->id == ul_slice->id
&& sc_update[mod_id]->ul[i]->has_label) {
ul_slice->label = sc_update[mod_id]->ul[i]->label;
break;
}
}
ul_slice->percentage = flexran_get_ul_slice_percentage(mod_id, slice_idx);
ul_slice->has_percentage = 1;
/*ul_slice->isolation = flexran_get_ul_slice_isolation(mod_id, slice_idx);*/
ul_slice->has_isolation = 0;
/*ul_slice->priority = flexran_get_ul_slice_priority(mod_id, slice_idx);*/
ul_slice->has_priority = 0;
ul_slice->first_rb = flexran_get_ul_slice_first_rb(mod_id, slice_idx);
ul_slice->has_first_rb = 1;
/*ul_slice-> = flexran_get_ul_slice_length_rb(mod_id, slice_idx);
ul_slice->has_length_rb = 0;*/
ul_slice->maxmcs = flexran_get_ul_slice_maxmcs(mod_id, slice_idx);
ul_slice->has_maxmcs = 1;
ul_slice->n_sorting = 0;
/*if (ul_slice->sorting) {
free(ul_slice->sorting);
ul_slice->sorting = NULL;
}
ul_slice->n_sorting = flexran_get_ul_slice_sorting(mod_id, slice_idx, &ul_slice->sorting);
if (ul_slice->n_sorting < 1) ul_slice->sorting = NULL;*/
/*ul_slice->accounting = flexran_get_ul_slice_accounting_policy(mod_id, slice_idx);*/
ul_slice->has_accounting = 0;
const char *s_name = flexran_get_ul_slice_scheduler(mod_id, slice_idx);
if (!ul_slice->scheduler_name
|| strcmp(ul_slice->scheduler_name, s_name) != 0) {
ul_slice->scheduler_name = realloc(ul_slice->scheduler_name, strlen(s_name) + 1);
strcpy(ul_slice->scheduler_name, s_name);
}
}
int check_dl_sorting_update(Protocol__FlexDlSlice *old, Protocol__FlexDlSlice *new)
{
/* sorting_update => true when old->n_sorting == 0 or different numbers of
* elements; otherwise will check * element-wise */
int sorting_update = old->n_sorting == 0 || (old->n_sorting != new->n_sorting);
for (int i = 0; i < old->n_sorting && !sorting_update; ++i) {
sorting_update = sorting_update || (new->sorting[i] != old->sorting[i]);
}
return sorting_update;
}
int check_ul_sorting_update(Protocol__FlexUlSlice *old, Protocol__FlexUlSlice *new)
{
/* sorting_update => true when old->n_sorting == 0 or different numbers of
* elements; otherwise will check * element-wise */
int sorting_update = old->n_sorting == 0 || (old->n_sorting != new->n_sorting);
for (int i = 0; i < old->n_sorting && !sorting_update; ++i) {
sorting_update = sorting_update || (new->sorting[i] != old->sorting[i]);
}
return sorting_update;
}
void overwrite_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *exist, Protocol__FlexSliceConfig *update)
{
if (update->has_intraslice_share_active
&& exist->intraslice_share_active != update->intraslice_share_active) {
LOG_I(FLEXRAN_AGENT, "[%d] update intraslice_share_active: %d -> %d\n",
mod_id, exist->intraslice_share_active, update->intraslice_share_active);
exist->intraslice_share_active = update->intraslice_share_active;
exist->has_intraslice_share_active = 1;
}
if (update->has_interslice_share_active
&& exist->interslice_share_active != update->interslice_share_active) {
LOG_I(FLEXRAN_AGENT, "[%d] update interslice_share_active: %d -> %d\n",
mod_id, exist->interslice_share_active, update->interslice_share_active);
exist->interslice_share_active = update->interslice_share_active;
exist->has_interslice_share_active = 1;
}
}
void overwrite_slice_config_dl(mid_t mod_id, Protocol__FlexDlSlice *exist, Protocol__FlexDlSlice *update)
{
if (update->label != exist->label) {
LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update label: %d -> %d\n",
mod_id, update->id, exist->label, update->label);
exist->label = update->label;
exist->has_label = 1;
}
if (update->percentage != exist->percentage) {
LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update percentage: %d -> %d\n",
mod_id, update->id, exist->percentage, update->percentage);
exist->percentage = update->percentage;
exist->has_percentage = 1;
}
if (update->isolation != exist->isolation) {
LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update isolation: %d -> %d\n",
mod_id, update->id, exist->isolation, update->isolation);
exist->isolation = update->isolation;
exist->has_isolation = 1;
}
if (update->priority != exist->priority) {
LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update priority: %d -> %d\n",
mod_id, update->id, exist->priority, update->priority);
exist->priority = update->priority;
exist->has_priority = 1;
}
if (update->position_low != exist->position_low) {
LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update position_low: %d -> %d\n",
mod_id, update->id, exist->position_low, update->position_low);
exist->position_low = update->position_low;
exist->has_position_low = 1;
}
if (update->position_high != exist->position_high) {
LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update position_high: %d -> %d\n",
mod_id, update->id, exist->position_high, update->position_high);
exist->position_high = update->position_high;
exist->has_position_high = 1;
}
if (update->maxmcs != exist->maxmcs) {
LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update maxmcs: %d -> %d\n",
mod_id, update->id, exist->maxmcs, update->maxmcs);
exist->maxmcs = update->maxmcs;
exist->has_maxmcs = 1;
}
if (check_dl_sorting_update(exist, update)) {
LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update sorting array\n", mod_id, update->id);
if (exist->n_sorting != update->n_sorting) {
exist->n_sorting = update->n_sorting;
exist->sorting = realloc(exist->sorting, exist->n_sorting * sizeof(Protocol__FlexDlSorting));
if (!exist->sorting) exist->n_sorting = 0;
}
for (int i = 0; i < exist->n_sorting; i++)
exist->sorting[i] = update->sorting[i];
}
if (update->accounting != exist->accounting) {
LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update accounting: %d -> %d\n",
mod_id, update->id, exist->accounting, update->accounting);
exist->accounting = update->accounting;
exist->has_accounting = 1;
}
if (!exist->scheduler_name
|| strcmp(update->scheduler_name, exist->scheduler_name) != 0) {
LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update scheduler: %s -> %s\n",
mod_id, update->id, exist->scheduler_name, update->scheduler_name);
if (exist->scheduler_name) free(exist->scheduler_name);
exist->scheduler_name = strdup(update->scheduler_name);
}
}
void overwrite_slice_config_ul(mid_t mod_id, Protocol__FlexUlSlice *exist, Protocol__FlexUlSlice *update)
{
if (update->label != exist->label) {
LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update label: %d -> %d\n",
mod_id, update->id, exist->label, update->label);
exist->label = update->label;
exist->has_label = 1;
}
if (update->percentage != exist->percentage) {
LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update percentage: %d -> %d\n",
mod_id, update->id, exist->percentage, update->percentage);
exist->percentage = update->percentage;
exist->has_percentage = 1;
}
if (update->isolation != exist->isolation) {
LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update isolation: %d -> %d\n",
mod_id, update->id, exist->isolation, update->isolation);
exist->isolation = update->isolation;
exist->has_isolation = 1;
}
if (update->priority != exist->priority) {
LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update priority: %d -> %d\n",
mod_id, update->id, exist->priority, update->priority);
exist->priority = update->priority;
exist->has_priority = 1;
}
if (update->first_rb != exist->first_rb) {
LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update first_rb: %d -> %d\n",
mod_id, update->id, exist->first_rb, update->first_rb);
exist->first_rb = update ->first_rb;
exist->has_first_rb = 1;
}
/*if (update->lenght_rb != exist->lenght_rb) {
LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update lenght_rb: %d -> %d\n",
mod_id, update->id, exist->lenght_rb, update->lenght_rb);
exist->lenght_rb = update->lenght_rb;
}*/
if (update->maxmcs != exist->maxmcs) {
LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update maxmcs: %d -> %d\n",
mod_id, update->id, exist->maxmcs, update->maxmcs);
exist->maxmcs = update->maxmcs;
exist->has_maxmcs = 1;
}
/* TODO
int sorting_update = 0;
int n = min(exist->n_sorting, update->n_sorting);
int i = 0;
while (i < n && !sorting_update) {
sorting_update = sorting_update || (update->sorting[i] != exist->sorting[i]);
i++;
}
if (sorting_update) {
LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update sorting array\n", update->id, mod_id);
if (exist->n_sorting != update->n_sorting)
LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] only writing %d elements\n",
mod_id, update->id, n);
for (i = 0; i < n; i++)
exist->sorting[i] = update->sorting[i];
}
*/
if (update->accounting != exist->accounting) {
LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update accounting: %d -> %d\n",
mod_id, update->id, exist->accounting, update->accounting);
exist->accounting = update->accounting;
exist->has_accounting = 1;
}
if (!exist->scheduler_name
|| strcmp(update->scheduler_name, exist->scheduler_name) != 0) {
LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update scheduler: %s -> %s\n",
mod_id, update->id, exist->scheduler_name, update->scheduler_name);
if (exist->scheduler_name) free(exist->scheduler_name);
exist->scheduler_name = strdup(update->scheduler_name);
}
}
void fill_dl_slice(mid_t mod_id, Protocol__FlexDlSlice *s, Protocol__FlexDlSlice *from)
{
/* function fills slice with information from another slice or with default
* values (currently slice 0) if from is NULL */
/* TODO fill the slice depending on the chosen label */
if (!s->has_label) {
s->has_label = 1;
s->label = from ? from->label : sc_update[mod_id]->dl[0]->label;
}
if (!s->has_percentage) {
s->has_percentage = 1;
s->percentage = from ? from->percentage : sc_update[mod_id]->dl[0]->percentage;
}
if (!s->has_isolation) {
s->has_isolation = 1;
s->isolation = from ? from->isolation : sc_update[mod_id]->dl[0]->isolation;
}
if (!s->has_priority) {
s->has_priority = 1;
s->priority = from ? from->priority : sc_update[mod_id]->dl[0]->priority;
}
if (!s->has_position_low) {
s->has_position_low = 1;
s->position_low = from ? from->position_low : sc_update[mod_id]->dl[0]->position_low;
}
if (!s->has_position_high) {
s->has_position_high = 1;
s->position_high = from ? from->position_high : sc_update[mod_id]->dl[0]->position_high;
}
if (!s->has_maxmcs) {
s->has_maxmcs = 1;
s->maxmcs = from ? from->maxmcs : sc_update[mod_id]->dl[0]->maxmcs;
}
if (s->n_sorting == 0) {
s->n_sorting = from ? from->n_sorting : sc_update[mod_id]->dl[0]->n_sorting;
s->sorting = calloc(s->n_sorting, sizeof(Protocol__FlexDlSorting));
if (!s->sorting) s->n_sorting = 0;
for (int i = 0; i < s->n_sorting; ++i)
s->sorting[i] = from ? from->sorting[i] : sc_update[0]->dl[0]->sorting[i];
}
if (!s->has_accounting) {
s->accounting = from ? from->accounting : sc_update[mod_id]->dl[0]->accounting;
}
if (!s->scheduler_name) {
s->scheduler_name = strdup(from ? from->scheduler_name : sc_update[mod_id]->dl[0]->scheduler_name);
}
}
Protocol__FlexDlSlice *get_existing_dl_slice(mid_t mod_id, int id)
{
for (int i = 0; i < sc_update[mod_id]->n_dl; ++i) {
if (id == sc_update[mod_id]->dl[i]->id) {
return sc_update[mod_id]->dl[i];
}
}
return NULL;
}
Protocol__FlexDlSlice *create_new_dl_slice(mid_t mod_id, int id)
{
LOG_I(FLEXRAN_AGENT,
"[%d] Creating DL slice with ID %d, taking default values from DL slice 0\n",
mod_id, id);
Protocol__FlexDlSlice *to = sc_update[mod_id]->dl[sc_update[mod_id]->n_dl];
sc_update[mod_id]->n_dl++;
AssertFatal(sc_update[mod_id]->n_dl <= MAX_NUM_SLICES,
"cannot create more than MAX_NUM_SLICES\n");
to->id = id;
return to;
}
void fill_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *s, Protocol__FlexUlSlice *from)
{
/* function fills slice with information from another slice or with default
* values (currently slice 0) if from is NULL */
/* TODO fill the slice depending on the chosen label */
if (!s->has_label) {
s->has_label = 1;
s->label = from ? from->label : sc_update[mod_id]->ul[0]->label;
}
if (!s->has_percentage) {
s->has_percentage = 1;
s->percentage = from ? from->percentage : sc_update[mod_id]->ul[0]->percentage;
}
if (!s->has_isolation) {
s->has_isolation = 1;
s->isolation = from ? from->isolation : sc_update[mod_id]->ul[0]->isolation;
}
if (!s->has_priority) {
s->has_priority = 1;
s->priority = from ? from->priority : sc_update[mod_id]->ul[0]->priority;
}
if (!s->has_first_rb) {
s->has_first_rb = 1;
s->first_rb = from ? from->first_rb : sc_update[mod_id]->ul[0]->first_rb;
}
if (!s->has_maxmcs) {
s->has_maxmcs = 1;
s->maxmcs = from ? from->maxmcs : sc_update[mod_id]->ul[0]->maxmcs;
}
if (s->n_sorting == 0) {
s->n_sorting = from ? from->n_sorting : sc_update[0]->ul[0]->n_sorting;
s->sorting = calloc(s->n_sorting, sizeof(Protocol__FlexUlSorting));
if (!s->sorting) s->n_sorting = 0;
for (int i = 0; i < s->n_sorting; ++i)
s->sorting[i] = from ? from->sorting[i] : sc_update[0]->ul[0]->sorting[i];
}
if (!s->has_accounting) {
s->accounting = from ? from->accounting : sc_update[0]->ul[0]->accounting;
}
if (!s->scheduler_name) {
s->scheduler_name = strdup(from ? from->scheduler_name : sc_update[mod_id]->ul[0]->scheduler_name);
}
}
Protocol__FlexUlSlice *get_existing_ul_slice(mid_t mod_id, int id)
{
for (int i = 0; i < sc_update[mod_id]->n_ul; ++i) {
if (id == sc_update[mod_id]->ul[i]->id) {
return sc_update[mod_id]->ul[i];
}
}
return NULL;
}
Protocol__FlexUlSlice *create_new_ul_slice(mid_t mod_id, int id)
{
LOG_I(FLEXRAN_AGENT,
"[%d] Creating UL slice with ID %d, taking default values from UL slice 0\n",
mod_id, id);
Protocol__FlexUlSlice *to = sc_update[mod_id]->ul[sc_update[mod_id]->n_ul];
sc_update[mod_id]->n_ul++;
AssertFatal(sc_update[mod_id]->n_ul <= MAX_NUM_SLICES,
"cannot create more than MAX_NUM_SLICES\n");
to->id = id;
return to;
}
void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *sup)
{
int verified = 1;
if (!sc_update[mod_id]) {
LOG_E(FLEXRAN_AGENT, "Can not update slice policy (no existing slice profile)\n");
return;
}
pthread_mutex_lock(&sc_update_mtx);
/* no need for tests in the current state as there are only two protobuf
* bools for intra-/interslice sharing. The function applies new values if
* applicable */
overwrite_slice_config(mod_id, sc_update[mod_id], sup);
if (sup->n_dl == 0) {
LOG_I(FLEXRAN_AGENT, "[%d] no DL slice configuration in flex_slice_config message\n", mod_id);
void update_or_remove_dl(mid_t mod_id, Protocol__FlexSlice *s) {
if (s->params_case == PROTOCOL__FLEX_SLICE__PARAMS__NOT_SET
&& !s->label && !s->scheduler) {
LOG_I(FLEXRAN_AGENT, "remove DL slice ID %d\n", s->id);
const int rc = flexran_remove_dl_slice(mod_id, s);
if (!rc)
LOG_W(FLEXRAN_AGENT, "error while removing slice ID %d\n", s->id);
} else {
/* verify slice parameters */
for (int i = 0; i < sup->n_dl; i++) {
if (!sup->dl[i]->has_id) {
verified = 0;
break;
}
Protocol__FlexDlSlice *dls = get_existing_dl_slice(mod_id, sup->dl[i]->id);
/* fill up so that the slice is complete. This way, we don't need to
* worry about it later */
fill_dl_slice(mod_id, sup->dl[i], dls);
verified = verified && flexran_verify_dl_slice(mod_id, sup->dl[i]);
if (!verified) break;
}
/* verify group-based parameters (e.g. sum percentage should not exceed
* 100%). Can be used to perform admission control */
verified = verified && flexran_verify_group_dl_slices(mod_id,
sc_update[mod_id]->dl, sc_update[mod_id]->n_dl, sup->dl, sup->n_dl);
if (verified) {
for (int i = 0; i < sup->n_dl; i++) {
/* if all verifications were successful, get existing slice for ID or
* create new one and overwrite with the update */
Protocol__FlexDlSlice *dls = get_existing_dl_slice(mod_id, sup->dl[i]->id);
if (!dls) dls = create_new_dl_slice(mod_id, sup->dl[i]->id);
overwrite_slice_config_dl(mod_id, dls, sup->dl[i]);
}
} else {
LOG_E(FLEXRAN_AGENT, "[%d] DL slice verification failed, refusing application\n", mod_id);
}
LOG_I(FLEXRAN_AGENT, "updating DL slice ID %d\n", s->id);
const int rc = flexran_create_dl_slice(mod_id, s);
if (rc < 0)
LOG_W(FLEXRAN_AGENT,
"error while update slice ID %d: flexran_create_dl_slice() -> %d\n",
s->id, rc);
}
}
verified = 1;
if (sup->n_ul == 0) {
LOG_I(FLEXRAN_AGENT, "[%d] no UL slice configuration in flex_slice_config message\n", mod_id);
void update_or_remove_ul(mid_t mod_id, Protocol__FlexSlice *s) {
if (s->params_case == PROTOCOL__FLEX_SLICE__PARAMS__NOT_SET
&& !s->label && !s->scheduler) {
LOG_I(FLEXRAN_AGENT, "remove UL slice ID %d\n", s->id);
const int rc = flexran_remove_ul_slice(mod_id, s);
if (!rc)
LOG_W(FLEXRAN_AGENT, "error while removing slice ID %d\n", s->id);
} else {
/* verify slice parameters */
for (int i = 0; i < sup->n_ul; i++) {
if (!sup->ul[i]->has_id) {
verified = 0;
break;
}
Protocol__FlexUlSlice *uls = get_existing_ul_slice(mod_id, sup->ul[i]->id);
/* fill up so that the slice is complete. This way, we don't need to
* worry about it later */
fill_ul_slice(mod_id, sup->ul[i], uls);
verified = verified && flexran_verify_ul_slice(mod_id, sup->ul[i]);
if (!verified) break;
}
/* verify group-based parameters (e.g. sum percentage should not exceed
* 100%). Can be used to perform admission control */
verified = verified && flexran_verify_group_ul_slices(mod_id,
sc_update[mod_id]->ul, sc_update[mod_id]->n_ul, sup->ul, sup->n_ul);
if (verified) {
for (int i = 0; i < sup->n_ul; i++) {
/* if all verifications were successful, get existing slice for ID or
* create new one and overwrite with the update */
Protocol__FlexUlSlice *uls = get_existing_ul_slice(mod_id, sup->ul[i]->id);
if (!uls) uls = create_new_ul_slice(mod_id, sup->ul[i]->id);
overwrite_slice_config_ul(mod_id, uls, sup->ul[i]);
}
} else {
LOG_E(FLEXRAN_AGENT, "[%d] UL slice verification failed, refusing application\n", mod_id);
}
LOG_I(FLEXRAN_AGENT, "updating UL slice ID %d\n", s->id);
const int rc = flexran_create_ul_slice(mod_id, s);
if (rc < 0)
LOG_W(FLEXRAN_AGENT,
"error while updating slice ID %d: flexran_create_ul_slice() -> %d)\n",
s->id, rc);
}
pthread_mutex_unlock(&sc_update_mtx);
perform_slice_config_update_count = 1;
}
int apply_new_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *olds, Protocol__FlexSliceConfig *news)
{
/* not setting the old configuration is intentional, as it will be picked up
* later when reading the configuration. There is thus a direct feedback
* whether it has been set. */
int changes = 0;
if (olds->intraslice_share_active != news->intraslice_share_active) {
flexran_set_intraslice_sharing_active(mod_id, news->intraslice_share_active);
changes++;
}
if (olds->interslice_share_active != news->interslice_share_active) {
flexran_set_interslice_sharing_active(mod_id, news->interslice_share_active);
changes++;
}
return changes;
}
int apply_new_slice_dl_config(mid_t mod_id, Protocol__FlexDlSlice *oldc, Protocol__FlexDlSlice *newc)
{
/* not setting the old configuration is intentional, as it will be picked up
* later when reading the configuration. There is thus a direct feedback
* whether it has been set. */
int changes = 0;
int slice_idx = flexran_find_dl_slice(mod_id, newc->id);
if (slice_idx < 0) {
LOG_W(FLEXRAN_AGENT, "[%d] cannot find index for slice ID %d\n", mod_id, newc->id);
return 0;
}
if (oldc->percentage != newc->percentage) {
flexran_set_dl_slice_percentage(mod_id, slice_idx, newc->percentage);
changes++;
}
if (oldc->isolation != newc->isolation) {
flexran_set_dl_slice_isolation(mod_id, slice_idx, newc->isolation);
changes++;
}
if (oldc->priority != newc->priority) {
flexran_set_dl_slice_priority(mod_id, slice_idx, newc->priority);
changes++;
}
if (oldc->position_low != newc->position_low) {
flexran_set_dl_slice_position_low(mod_id, slice_idx, newc->position_low);
changes++;
}
if (oldc->position_high != newc->position_high) {
flexran_set_dl_slice_position_high(mod_id, slice_idx, newc->position_high);
changes++;
}
if (oldc->maxmcs != newc->maxmcs) {
flexran_set_dl_slice_maxmcs(mod_id, slice_idx, newc->maxmcs);
changes++;
}
if (check_dl_sorting_update(oldc, newc)) {
flexran_set_dl_slice_sorting(mod_id, slice_idx, newc->sorting, newc->n_sorting);
changes++;
}
if (oldc->accounting != newc->accounting) {
flexran_set_dl_slice_accounting_policy(mod_id, slice_idx, newc->accounting);
changes++;
}
if (!oldc->scheduler_name
|| strcmp(oldc->scheduler_name, newc->scheduler_name) != 0) {
int ret = flexran_set_dl_slice_scheduler(mod_id, slice_idx, newc->scheduler_name);
AssertFatal(ret, "could not set DL slice scheduler for slice %d idx %d\n",
newc->id, slice_idx);
changes++;
}
return changes;
}
int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protocol__FlexUlSlice *newc)
{
/* not setting the old configuration is intentional, as it will be picked up
* later when reading the configuration. There is thus a direct feedback
* whether it has been set. */
int changes = 0;
int slice_idx = flexran_find_ul_slice(mod_id, newc->id);
if (slice_idx < 0) {
LOG_W(FLEXRAN_AGENT, "[%d] cannot find index for slice ID %d\n", mod_id, newc->id);
return 0;
}
if (oldc->percentage != newc->percentage) {
flexran_set_ul_slice_percentage(mod_id, slice_idx, newc->percentage);
changes++;
}
if (oldc->isolation != newc->isolation) {
/*flexran_set_ul_slice_isolation(mod_id, slice_idx, newc->isolation);
*changes++;*/
LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting isolation is not supported\n",
mod_id, newc->id);
}
if (oldc->priority != newc->priority) {
/*flexran_set_ul_slice_priority(mod_id, slice_idx, newc->priority);
*changes++;*/
LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the priority is not supported\n",
mod_id, newc->id);
}
if (oldc->first_rb != newc->first_rb) {
flexran_set_ul_slice_first_rb(mod_id, slice_idx, newc->first_rb);
changes++;
}
/*if (oldc->length_rb != newc->length_rb) {
flexran_set_ul_slice_length_rb(mod_id, slice_idx, newc->length_rb);
changes++;
LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting length_rb is not supported\n",
mod_id, newc->id);
}*/
if (oldc->maxmcs != newc->maxmcs) {
flexran_set_ul_slice_maxmcs(mod_id, slice_idx, newc->maxmcs);
changes++;
}
/*if (check_ul_sorting_update(oldc, newc)) {
flexran_set_ul_slice_sorting(mod_id, slice_idx, newc->sorting, n);
changes++;
LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the sorting is not supported\n",
mod_id, newc->id);
}*/
if (oldc->accounting != newc->accounting) {
/*flexran_set_ul_slice_accounting_policy(mod_id, slice_idx, newc->accounting);
*changes++;*/
LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the accounting is not supported\n",
mod_id, newc->id);
}
if (!oldc->scheduler_name
|| strcmp(oldc->scheduler_name, newc->scheduler_name) != 0) {
int ret = flexran_set_ul_slice_scheduler(mod_id, slice_idx, newc->scheduler_name);
AssertFatal(ret, "could not set DL slice scheduler for slice %d idx %d\n",
newc->id, slice_idx);
changes++;
}
return changes;
}
void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config)
{
if (n_ue_slice_assoc_updates == MAX_NUM_SLICES) {
LOG_E(FLEXRAN_AGENT,
"[%d] can not handle flex_ue_config message, buffer is full; try again later\n",
mod_id);
void apply_update_dl_slice_config(mid_t mod_id, Protocol__FlexSliceDlUlConfig *dl) {
if (!dl)
return;
Protocol__FlexSliceAlgorithm dl_algo = flexran_get_dl_slice_algo(mod_id);
if (dl->has_algorithm && dl_algo != dl->algorithm) {
LOG_I(FLEXRAN_AGENT, "loading new DL slice algorithm %d\n", dl->algorithm);
dl_algo = dl->algorithm;
flexran_set_dl_slice_algo(mod_id, dl_algo);
}
/* first update existing slices, then create new. Thus, we go through the
* list twice. First round, if a slice exists, handle and mark as such. Then,
* apply all others in the second round */
if (dl->n_slices > 0) {
if (dl_algo == PROTOCOL__FLEX_SLICE_ALGORITHM__None) {
LOG_E(FLEXRAN_AGENT, "cannot update slices: no algorithm loaded\n");
return;
}
int handled_dl[dl->n_slices];
for (int i = 0; i < dl->n_slices; ++i) {
if (flexran_find_dl_slice(mod_id, dl->slices[i]->id) < 0) {
handled_dl[i] = 0;
continue;
}
update_or_remove_dl(mod_id, dl->slices[i]);
handled_dl[i] = 1;
}
for (int i = 0; i < dl->n_slices; ++i) {
if (handled_dl[i])
continue;
update_or_remove_dl(mod_id, dl->slices[i]);
}
}
if (dl->scheduler) {
if (dl_algo != PROTOCOL__FLEX_SLICE_ALGORITHM__None) {
LOG_E(FLEXRAN_AGENT, "cannot update scheduling algorithm: slice algorithm loaded\n");
return;
}
LOG_I(FLEXRAN_AGENT, "loading DL new scheduling algorithm '%s'\n", dl->scheduler);
const int rc = flexran_set_dl_scheduler(mod_id, dl->scheduler);
if (rc < 0) {
LOG_E(FLEXRAN_AGENT,
"error while updating scheduling algorithm: "
"flexran_update_dl_sched_algo() -> %d)\n",
rc);
return;
}
}
}
void apply_update_ul_slice_config(mid_t mod_id, Protocol__FlexSliceDlUlConfig *ul) {
if (!ul)
return;
Protocol__FlexSliceAlgorithm ul_algo = flexran_get_ul_slice_algo(mod_id);
if (ul->has_algorithm && ul_algo != ul->algorithm) {
LOG_I(FLEXRAN_AGENT, "loading new UL slice algorithm %d\n", ul->algorithm);
ul_algo = ul->algorithm;
flexran_set_ul_slice_algo(mod_id, ul_algo);
}
if (ul->n_slices > 0) {
if (ul_algo == PROTOCOL__FLEX_SLICE_ALGORITHM__None) {
LOG_E(FLEXRAN_AGENT, "cannot update slices: no algorithm loaded\n");
return;
}
int handled_ul[ul->n_slices];
for (int i = 0; i < ul->n_slices; ++i) {
if (flexran_find_ul_slice(mod_id, ul->slices[i]->id) < 0) {
handled_ul[i] = 0;
continue;
}
update_or_remove_ul(mod_id, ul->slices[i]);
handled_ul[i] = 1;
}
for (int i = 0; i < ul->n_slices; ++i) {
if (handled_ul[i])
continue;
update_or_remove_ul(mod_id, ul->slices[i]);
}
}
if (ul->scheduler) {
if (ul_algo != PROTOCOL__FLEX_SLICE_ALGORITHM__None) {
LOG_E(FLEXRAN_AGENT, "cannot update scheduling algorithm: slice algorithm loaded\n");
return;
}
LOG_I(FLEXRAN_AGENT, "loading new UL scheduling algorithm '%s'\n", ul->scheduler);
const int rc = flexran_set_ul_scheduler(mod_id, ul->scheduler);
if (rc < 0) {
LOG_E(FLEXRAN_AGENT,
"error while updating scheduling algorithm: "
"flexran_update_dl_sched_algo() -> %d)\n",
rc);
return;
}
}
}
int apply_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config)
{
if (!ue_config->has_rnti) {
LOG_E(FLEXRAN_AGENT,
"[%d] cannot update UE to slice association, no RNTI in flex_ue_config message\n",
mod_id);
return;
return 0;
}
if (ue_config->has_dl_slice_id)
LOG_I(FLEXRAN_AGENT, "[%d] associating UE RNTI %#x to DL slice ID %d\n",
mod_id, ue_config->rnti, ue_config->dl_slice_id);
if (ue_config->has_ul_slice_id)
LOG_I(FLEXRAN_AGENT, "[%d] associating UE RNTI %#x to UL slice ID %d\n",
mod_id, ue_config->rnti, ue_config->ul_slice_id);
ue_slice_assoc_update[n_ue_slice_assoc_updates++] = ue_config;
perform_slice_config_update_count = 2;
}
int apply_ue_slice_assoc_update(mid_t mod_id)
{
int i;
int changes = 0;
for (i = 0; i < n_ue_slice_assoc_updates; i++) {
int ue_id = find_UE_id(mod_id, ue_slice_assoc_update[i]->rnti);
if (ue_id < 0 || ue_id > MAX_MOBILES_PER_ENB){
LOG_E(FLEXRAN_AGENT,"UE_id %d is wrong!!\n",ue_id);
continue;
}
if (ue_slice_assoc_update[i]->has_dl_slice_id) {
int slice_idx = flexran_find_dl_slice(mod_id, ue_slice_assoc_update[i]->dl_slice_id);
if (flexran_dl_slice_exists(mod_id, slice_idx)) {
flexran_set_ue_dl_slice_idx(mod_id, ue_id, slice_idx);
changes++;
} else {
LOG_W(FLEXRAN_AGENT, "[%d] DL slice %d does not exist, refusing change\n",
mod_id, ue_slice_assoc_update[i]->dl_slice_id);
}
}
if (ue_slice_assoc_update[i]->has_ul_slice_id) {
int slice_idx = flexran_find_ul_slice(mod_id, ue_slice_assoc_update[i]->ul_slice_id);
if (flexran_ul_slice_exists(mod_id, slice_idx)) {
flexran_set_ue_ul_slice_idx(mod_id, ue_id, slice_idx);
changes++;
} else {
LOG_W(FLEXRAN_AGENT, "[%d] UL slice %d does not exist, refusing change\n",
mod_id, ue_slice_assoc_update[i]->ul_slice_id);
}
int UE_id = flexran_get_mac_ue_id_rnti(mod_id, ue_config->rnti);
if (ue_config->has_dl_slice_id) {
if (flexran_get_dl_slice_algo(mod_id) == PROTOCOL__FLEX_SLICE_ALGORITHM__None) {
LOG_E(FLEXRAN_AGENT, "no DL slice algorithm loaded\n");
} else {
LOG_I(FLEXRAN_AGENT, "[%d] associating UE RNTI %04x - %d/UE %d to DL slice ID %d\n",
mod_id, ue_config->rnti, ue_config->rnti, UE_id, ue_config->dl_slice_id);
flexran_set_ue_dl_slice_id(mod_id, UE_id, ue_config->dl_slice_id);
}
}
n_ue_slice_assoc_updates = 0;
return changes;
if (ue_config->has_ul_slice_id) {
if (flexran_get_ul_slice_algo(mod_id) == PROTOCOL__FLEX_SLICE_ALGORITHM__None) {
LOG_E(FLEXRAN_AGENT, "no UL slice algorithm loaded\n");
} else {
LOG_I(FLEXRAN_AGENT, "[%d] associating UE RNTI %04x - %d/UE %d to UL slice ID %d\n",
mod_id, ue_config->rnti, ue_config->rnti, UE_id, ue_config->ul_slice_id);
flexran_set_ue_ul_slice_id(mod_id, UE_id, ue_config->ul_slice_id);
}
}
return 0;
}
@@ -103,43 +103,11 @@ int load_dl_scheduler_function(mid_t mod_id, const char *function_name);
/*** Functions for handling a slice config ***/
/* allocate memory for a Protocol__FlexSliceConfig structure with n_dl DL slice
* configs and m_ul UL slice configs */
Protocol__FlexSliceConfig *flexran_agent_create_slice_config(int n_dl, int m_ul);
/* read the general slice parameters via RAN into the given
* Protocol__FlexSliceConfig struct */
void flexran_agent_read_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *s);
/* read the DL slice config via the RAN into a given Protocol__FlexDlSlice
* struct */
void flexran_agent_read_slice_dl_config(mid_t mod_id, int slice_idx, Protocol__FlexDlSlice *dl_slice);
/* read the UL slice config via the RAN into a given Protocol__FlexUlSlice
* struct */
void flexran_agent_read_slice_ul_config(mid_t mod_id, int slice_idx, Protocol__FlexUlSlice *ul_slice);
/* reads content of slice over the sc_update structure, so that it can be
* applied later by performing a diff between slice_config and sc_update */
void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *slice);
/* apply generic slice parameters (e.g. intra-/interslice sharing activated or
* not) if there are changes. Returns the number of changed parameters. */
int apply_new_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *olds, Protocol__FlexSliceConfig *news);
/* apply new configuration of slice in DL if there are changes between the
* parameters. Returns the number of changed parameters. */
int apply_new_slice_dl_config(mid_t mod_id, Protocol__FlexDlSlice *oldc, Protocol__FlexDlSlice *newc);
/* apply new configuration of slice in UL if there are changes between the
* parameters. Returns the number of changed parameters. */
int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protocol__FlexUlSlice *newc);
/* inserts a new ue_config into the structure keeping ue to slice association
* updates and marks so it can be applied */
void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config);
/* Prepare the application of a slicing config */
void apply_update_dl_slice_config(mid_t mod_id, Protocol__FlexSliceDlUlConfig *slice);
void apply_update_ul_slice_config(mid_t mod_id, Protocol__FlexSliceDlUlConfig *slice);
/* apply a new association between a UE and a slice (both DL and UL) */
int apply_ue_slice_assoc_update(mid_t mod_id);
int apply_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config);
#endif /*FLEXRAN_AGENT_MAC_INTERNAL_H_*/
@@ -28,346 +28,3 @@
#include "flexran_agent_mac_slice_verification.h"
/* overlap check for UL slices, helper type */
struct sregion_s {
int start;
int length;
};
/* forward declaration of locally-used verification functions */
int flexran_dl_slice_verify_pct(int pct);
int flexran_dl_slice_verify_priority(int prio);
int flexran_dl_slice_verify_position(int pos_low, int pos_high);
int flexran_dl_slice_verify_maxmcs(int maxmcs);
int flexran_ul_slice_verify_pct(int pct);
int flexran_ul_slice_verify_priority(int prio);
int flexran_ul_slice_verify_first_rb(int first_rb);
int flexran_ul_slice_verify_maxmcs(int maxmcs);
int check_ul_slice_overlap(mid_t mod_id, struct sregion_s *sr, int n);
int flexran_verify_dl_slice(mid_t mod_id, Protocol__FlexDlSlice *dls)
{
/* check mandatory parameters */
if (!dls->has_id) {
LOG_E(FLEXRAN_AGENT, "[%d] Incoming DL slice configuration has no ID\n", mod_id);
return 0;
}
/* verify parameters individualy */
/* label is enum */
if (!flexran_dl_slice_verify_pct(dls->percentage)) {
LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] illegal DL slice percentage (%d)\n",
mod_id, dls->id, dls->percentage);
return 0;
}
/* isolation is a protobuf bool */
if (!flexran_dl_slice_verify_priority(dls->priority)) {
LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] illegal DL slice priority (%d)\n",
mod_id, dls->id, dls->priority);
return 0;
}
if (!flexran_dl_slice_verify_position(dls->position_low, dls->position_high)) {
LOG_E(FLEXRAN_AGENT,
"[%d][DL slice %d] illegal DL slice position low (%d) and/or high (%d)\n",
mod_id, dls->id, dls->position_low, dls->position_high);
return 0;
}
if (!flexran_dl_slice_verify_maxmcs(dls->maxmcs)) {
LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] illegal DL slice max mcs %d\n",
mod_id, dls->id, dls->maxmcs);
return 0;
}
if (dls->n_sorting == 0) {
LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] no sorting in DL slice\n",
mod_id, dls->id);
return 0;
}
if (!dls->sorting) {
LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] no sorting found in DL slice\n",
mod_id, dls->id);
return 0;
}
/* sorting is an enum */
/* accounting is an enum */
if (!dls->scheduler_name) {
LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] no scheduler name found\n",
mod_id, dls->id);
return 0;
}
if (strcmp(dls->scheduler_name, "schedule_ue_spec") != 0) {
LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] setting the scheduler to something "
"different than schedule_ue_spec is currently not allowed\n",
mod_id, dls->id);
return 0;
}
return 1;
}
int flexran_verify_group_dl_slices(mid_t mod_id, Protocol__FlexDlSlice **existing,
int n_ex, Protocol__FlexDlSlice **update, int n_up)
{
int i, j, n;
int pct, pct_orig;
/* for every update, array points to existing slice, or NULL if update
* creates new slice */
Protocol__FlexDlSlice *s[n_up];
for (i = 0; i < n_up; i++) {
s[i] = NULL;
for (j = 0; j < n_ex; j++) {
if (existing[j]->id == update[i]->id)
s[i] = existing[j];
}
}
/* check that number of created and number of added slices in total matches
* [1,10] */
n = n_ex;
for (i = 0; i < n_up; i++) {
/* new slice */
if (!s[i]) n += 1;
/* slice will be deleted */
else if (s[i]->percentage == 0) n -= 1;
/* else "only" an update */
}
if (n < 1 || n > MAX_NUM_SLICES) {
LOG_E(FLEXRAN_AGENT, "[%d] Illegal number of resulting DL slices (%d -> %d)\n",
mod_id, n_ex, n);
return 0;
}
/* check that the sum of all slices percentages (including removed/added
* slices) matches [1,100] */
pct = 0;
for (i = 0; i < n_ex; i++) {
pct += existing[i]->percentage;
}
pct_orig = pct;
for (i = 0; i < n_up; i++) {
/* if there is an existing slice, subtract its percentage and add the
* update's percentage */
if (s[i])
pct -= s[i]->percentage;
pct += update[i]->percentage;
}
if (pct < 1 || pct > 100) {
LOG_E(FLEXRAN_AGENT,
"[%d] invalid total RB share for DL slices (%d%% -> %d%%)\n",
mod_id, pct_orig, pct);
return 0;
}
return 1;
}
int flexran_verify_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *uls)
{
/* check mandatory parameters */
if (!uls->has_id) {
LOG_E(FLEXRAN_AGENT, "[%d] Incoming UL slice configuration has no ID\n", mod_id);
return 0;
}
/* verify parameters individually */
/* label is enum */
if (!flexran_ul_slice_verify_pct(uls->percentage)) {
LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] illegal UL slice percentage (%d)\n",
mod_id, uls->id, uls->percentage);
return 0;
}
/* isolation is a protobuf bool */
if (!flexran_ul_slice_verify_priority(uls->priority)) {
LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] illegal UL slice percentage (%d)\n",
mod_id, uls->id, uls->priority);
return 0;
}
if (!flexran_ul_slice_verify_first_rb(uls->first_rb)) {
LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] illegal UL slice first RB (%d)\n",
mod_id, uls->id, uls->first_rb);
return 0;
}
if (!flexran_ul_slice_verify_maxmcs(uls->maxmcs)) {
LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] illegal UL slice max mcs (%d)\n",
mod_id, uls->id, uls->maxmcs);
return 0;
}
/* TODO
if (uls->n_sorting == 0) {
LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] no sorting in UL slice\n",
mod_id, uls->id);
return 0;
}
if (!uls->sorting) {
LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] no sorting found in UL slice\n",
mod_id, uls->id);
return 0;
}
*/
/* sorting is an enum */
/* accounting is an enum */
if (!uls->scheduler_name) {
LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] no scheduler name found\n",
mod_id, uls->id);
return 0;
}
if (strcmp(uls->scheduler_name, "schedule_ulsch_rnti") != 0) {
LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] setting the scheduler to something "
"different than schedule_ulsch_rnti is currently not allowed\n",
mod_id, uls->id);
return 0;
}
return 1;
}
int flexran_verify_group_ul_slices(mid_t mod_id, Protocol__FlexUlSlice **existing,
int n_ex, Protocol__FlexUlSlice **update, int n_up)
{
int i, j, n;
int pct, pct_orig;
/* for every update, array "s" points to existing slice, or NULL if update
* creates new slice; array "offs" gives the offset of this slice */
Protocol__FlexUlSlice *s[n_up];
int offs[n_up];
for (i = 0; i < n_up; i++) {
s[i] = NULL;
offs[i] = 0;
for (j = 0; j < n_ex; j++) {
if (existing[j]->id == update[i]->id) {
s[i] = existing[j];
offs[i] = j;
}
}
}
/* check that number of created and number of added slices in total matches
* [1,10] */
n = n_ex;
for (i = 0; i < n_up; i++) {
/* new slice */
if (!s[i]) n += 1;
/* slice will be deleted */
else if (s[i]->percentage == 0) n -= 1;
/* else "only" an update */
}
if (n < 1 || n > MAX_NUM_SLICES) {
LOG_E(FLEXRAN_AGENT, "[%d] Illegal number of resulting UL slices (%d -> %d)\n",
mod_id, n_ex, n);
return 0;
}
/* check that the sum of all slices percentages (including removed/added
* slices) matches [1,100] */
pct = 0;
for (i = 0; i < n_ex; i++) {
pct += existing[i]->percentage;
}
pct_orig = pct;
for (i = 0; i < n_up; i++) {
/* if there is an existing slice, subtract its percentage and add the
* update's percentage */
if (s[i])
pct -= s[i]->percentage;
pct += update[i]->percentage;
}
if (pct < 1 || pct > 100) {
LOG_E(FLEXRAN_AGENT, "[%d] invalid total RB share (%d%% -> %d%%)\n",
mod_id, pct_orig, pct);
return 0;
}
/* check that there is no overlap in slices resulting as the combination of
* first_rb and percentage */
struct sregion_s sregion[n];
const int N_RB = flexran_get_N_RB_UL(mod_id, 0); /* assume PCC */
int k = n_ex;
for (i = 0; i < n_ex; i++) {
sregion[i].start = existing[i]->first_rb;
sregion[i].length = existing[i]->percentage * N_RB / 100;
}
for (i = 0; i < n_up; i++) {
ptrdiff_t d = s[i] ? offs[i] : k++;
AssertFatal(d >= 0 && d < k, "illegal pointer offset (%ld, k=%d)\n", d, k);
sregion[d].start = update[i]->first_rb;
sregion[d].length = update[i]->percentage * N_RB / 100;
}
AssertFatal(k == n, "illegal number of slices while calculating overlap\n");
if (!check_ul_slice_overlap(mod_id, sregion, k)) {
LOG_E(FLEXRAN_AGENT, "[%d] UL slices are overlapping\n", mod_id);
return 0;
}
return 1;
}
int flexran_dl_slice_verify_pct(int pct)
{
return pct >= 0 && pct <= 100;
}
int flexran_dl_slice_verify_priority(int prio)
{
return prio >= 0;
}
int flexran_dl_slice_verify_position(int pos_low, int pos_high)
{
return pos_low < pos_high && pos_low >= 0 && pos_high <= N_RBG_MAX;
}
int flexran_dl_slice_verify_maxmcs(int maxmcs)
{
return maxmcs >= 0 && maxmcs <= 28;
}
int flexran_ul_slice_verify_pct(int pct)
{
return pct >= 0 && pct <= 100;
}
int flexran_ul_slice_verify_priority(int prio)
{
return prio >= 0;
}
int flexran_ul_slice_verify_first_rb(int first_rb)
{
return first_rb >= 0 && first_rb < 100;
}
int flexran_ul_slice_verify_maxmcs(int maxmcs)
{
return maxmcs >= 0 && maxmcs <= 20;
}
int sregion_compare(const void *_a, const void *_b)
{
const struct sregion_s *a = (const struct sregion_s *)_a;
const struct sregion_s *b = (const struct sregion_s *)_b;
const int res = a->start - b->start;
if (res < 0) return -1;
else if (res == 0) return 0;
else return 1;
}
int check_ul_slice_overlap(mid_t mod_id, struct sregion_s *sr, int n)
{
int i;
int overlap, op, u;
const int N_RB = flexran_get_N_RB_UL(mod_id, 0); /* assume PCC */
qsort(sr, n, sizeof(sr[0]), sregion_compare);
for (i = 0; i < n; i++) {
u = i == n-1 ? N_RB : sr[i+1].start;
AssertFatal(sr[i].start <= u, "unsorted slice list\n");
overlap = sr[i].start + sr[i].length - u;
if (overlap <= 0) continue;
op = overlap * 100 / sr[i].length;
LOG_W(FLEXRAN_AGENT, "[%d] slice overlap of %d%% detected\n", mod_id, op);
if (op >= 10) /* more than 10% overlap -> refuse */
return 0;
}
return 1;
}
@@ -29,9 +29,3 @@
#include "flexran_agent_common_internal.h"
#include "flexran_agent_mac_internal.h"
int flexran_verify_dl_slice(mid_t mod_id, Protocol__FlexDlSlice *dls);
int flexran_verify_group_dl_slices(mid_t mod_id, Protocol__FlexDlSlice **existing,
int n_ex, Protocol__FlexDlSlice **update, int n_up);
int flexran_verify_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *uls);
int flexran_verify_group_ul_slices(mid_t mod_id, Protocol__FlexUlSlice **existing,
int n_ex, Protocol__FlexUlSlice **update, int n_up);
@@ -125,6 +125,63 @@ void flexran_agent_s1ap_destroy_stats_reply(Protocol__FlexStatsReply *reply) {
}
}
void flexran_agent_handle_mme_update(mid_t mod_id,
size_t n_mme,
Protocol__FlexS1apMme **mme) {
if (n_mme == 0 || n_mme > 1) {
LOG_E(FLEXRAN_AGENT, "cannot handle %lu MMEs yet\n", n_mme);
return;
}
if (!mme[0]->s1_ip) {
LOG_E(FLEXRAN_AGENT, "no S1 IP present, cannot handle request\n");
return;
}
if (mme[0]->has_state
&& mme[0]->state == PROTOCOL__FLEX_MME_STATE__FLMMES_DISCONNECTED) {
int rc = flexran_remove_s1ap_mme(mod_id, 1, &mme[0]->s1_ip);
if (rc == 0)
LOG_I(FLEXRAN_AGENT, "remove MME at IP %s\n", mme[0]->s1_ip);
else
LOG_W(FLEXRAN_AGENT,
"could not remove MME: flexran_remove_s1ap_mme() returned %d\n",
rc);
} else {
int rc = flexran_add_s1ap_mme(mod_id, 1, &mme[0]->s1_ip);
if (rc == 0)
LOG_I(FLEXRAN_AGENT, "add MME at IP %s\n", mme[0]->s1_ip);
else
LOG_W(FLEXRAN_AGENT,
"could not add MME: flexran_add_s1ap_mme() returned %d\n",
rc);
}
}
void flexran_agent_handle_plmn_update(mid_t mod_id,
int CC_id,
size_t n_plmn,
Protocol__FlexPlmn **plmn_id) {
if (n_plmn < 1 || n_plmn > 6) {
LOG_E(FLEXRAN_AGENT, "cannot handle %lu PLMNs\n", n_plmn);
return;
}
/* We assume the controller has checked all the parameters within each
* plmn_id */
int rc = flexran_set_new_plmn_id(mod_id, CC_id, n_plmn, plmn_id);
if (rc == 0) {
LOG_I(FLEXRAN_AGENT, "set %lu new PLMNs:\n", n_plmn);
for (int i = 0; i < (int)n_plmn; ++i)
LOG_I(FLEXRAN_AGENT, " MCC %d MNC %d MNC length %d\n",
plmn_id[i]->mcc, plmn_id[i]->mnc, plmn_id[0]->mnc_length);
} else {
LOG_W(FLEXRAN_AGENT,
"could not set new PLMN configuration: flexran_set_new_plmn_id() returned %d\n",
rc);
}
}
int flexran_agent_register_s1ap_xface(mid_t mod_id) {
if (agent_s1ap_xface[mod_id]) {
LOG_E(FLEXRAN_AGENT, "S1AP agent CM for eNB %d is already registered\n", mod_id);
@@ -60,6 +60,17 @@ int flexran_agent_s1ap_stats_reply(mid_t mod_id,
/* Free allocated S1AP stats message */
void flexran_agent_s1ap_destroy_stats_reply(Protocol__FlexStatsReply *reply);
/* Add or remove MME updates */
void flexran_agent_handle_mme_update(mid_t mod_id,
size_t n_mme,
Protocol__FlexS1apMme **mme);
/* Set a new PLMN configuration */
void flexran_agent_handle_plmn_update(mid_t mod_id,
int CC_id,
size_t n_plmn,
Protocol__FlexPlmn **plmn_id);
/* Register technology specific interface callbacks */
int flexran_agent_register_s1ap_xface(mid_t mod_id);
+3
View File
@@ -58,6 +58,7 @@
#define CONFIG_STRING_MACRLC_SCHED_MODE "scheduler_mode"
#define CONFIG_MACRLC_PUSCH10xSNR "puSch10xSnr"
#define CONFIG_MACRLC_PUCCH10xSNR "puCch10xSnr"
#define CONFIG_STRING_MACRLC_DEFAULT_SCHED_DL_ALGO "default_sched_dl_algo"
/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* MacRLC configuration parameters */
@@ -84,6 +85,7 @@
{CONFIG_STRING_MACRLC_SCHED_MODE, NULL, 0, strptr:NULL, defstrval:"default", TYPE_STRING, 0}, \
{CONFIG_MACRLC_PUSCH10xSNR, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \
{CONFIG_MACRLC_PUCCH10xSNR, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \
{CONFIG_STRING_MACRLC_DEFAULT_SCHED_DL_ALGO, NULL, 0, strptr:NULL, defstrval:"round_robin_dl", TYPE_STRING, 0}, \
}
#define MACRLC_CC_IDX 0
#define MACRLC_TRANSPORT_N_PREFERENCE_IDX 1
@@ -105,6 +107,7 @@
#define MACRLC_SCHED_MODE_IDX 17
#define MACRLC_PUSCH10xSNR_IDX 18
#define MACRLC_PUCCH10xSNR_IDX 19
#define MACRLC_DEFAULT_SCHED_DL_ALGO_IDX 20
/*---------------------------------------------------------------------------------------------------------------------------------------------------------*/
#endif
@@ -61,82 +61,30 @@ enum flex_qam {
//
// Slice config related structures and enums
//
enum flex_dl_sorting {
CR_ROUND = 0; // Highest HARQ first
CR_SRB12 = 1; // Highest SRB1+2 first
CR_HOL = 2; // Highest HOL first
CR_LC = 3; // Greatest RLC buffer first
CR_CQI = 4; // Highest CQI first
CR_LCP = 5; // Highest LC priority first
enum flex_slice_algorithm {
None = 0;
Static = 1;
NVS = 2;
}
enum flex_ul_sorting {
CRU_ROUND = 0; // Highest HARQ first
CRU_BUF = 1; // Highest BSR first
CRU_BTS = 2; // More bytes to schedule first
CRU_MCS = 3; // Highest MCS first
CRU_LCP = 4; // Highest LC priority first
CRU_HOL = 5; // Highest HOL first
message flex_slice_static {
optional uint32 posLow = 1;
optional uint32 posHigh = 2;
}
enum flex_dl_accounting_policy {
POL_FAIR = 0;
POL_GREEDY = 1;
POL_NUM = 2;
message flex_slice {
optional uint32 id = 1;
optional string label = 2;
optional string scheduler = 3;
oneof params {
flex_slice_static static = 10;
}
}
enum flex_ul_accounting_policy {
POLU_FAIR = 0;
POLU_GREEDY = 1;
POLU_NUM = 2;
}
enum flex_slice_label {
xMBB = 0;
URLLC = 1;
mMTC = 2;
xMTC = 3;
Other = 4;
}
message flex_dl_slice {
optional uint32 id = 1;
optional flex_slice_label label = 2;
// should be between 0 and 100
optional uint32 percentage = 3;
// whether this slice should be exempted form interslice sharing
optional bool isolation = 4;
// increasing value means increasing prio
optional uint32 priority = 5;
// min and max RB to use (in frequency) in the range [0, N_RBG_MAX]
optional uint32 position_low = 6;
optional uint32 position_high = 7;
// maximum MCS to be allowed in this slice
optional uint32 maxmcs = 8;
repeated flex_dl_sorting sorting = 9;
optional flex_dl_accounting_policy accounting = 10;
optional string scheduler_name = 11;
}
message flex_ul_slice {
optional uint32 id = 1;
optional flex_slice_label label = 2;
// should be between 0 and 100
optional uint32 percentage = 3;
// whether this slice should be exempted form interslice sharing
optional bool isolation = 4;
// increasing value means increasing prio
optional uint32 priority = 5;
// RB start to use (in frequency) in the range [0, N_RB_MAX]
optional uint32 first_rb = 6;
// TODO RB number
//optional uint32 length_rb = 7;
// maximum MCS to be allowed in this slice
optional uint32 maxmcs = 8;
repeated flex_ul_sorting sorting = 9;
optional flex_ul_accounting_policy accounting = 10;
optional string scheduler_name = 11;
message flex_slice_dl_ul_config {
optional flex_slice_algorithm algorithm = 1;
repeated flex_slice slices = 2;
optional string scheduler = 3; // if no slicing
}
//
@@ -49,14 +49,8 @@ message flex_cell_config {
}
message flex_slice_config {
// whether remaining RBs after first intra-slice allocation will
// be allocated to UEs of the same slice
optional bool intraslice_share_active = 3;
// whether remaining RBs after slice allocation will be allocated
// to UEs of another slice. Isolated slices will be ignored.
optional bool interslice_share_active = 4;
repeated flex_dl_slice dl = 1;
repeated flex_ul_slice ul = 2;
optional flex_slice_dl_ul_config dl = 6;
optional flex_slice_dl_ul_config ul = 7;
}
message flex_ue_config {
-1
View File
@@ -273,7 +273,6 @@ void *eNB_app_task(void *args_p) {
if (EPC_MODE_ENABLED) {
LOG_I(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p),
S1AP_REGISTER_ENB_CNF(msg_p).nb_mme);
DevAssert(register_enb_pending > 0);
register_enb_pending--;
/* Check if at least eNB is registered with one MME */
+11
View File
@@ -29,6 +29,7 @@
#include <string.h>
#include <inttypes.h>
#include <dlfcn.h>
#include "common/utils/LOG/log.h"
#include "assertions.h"
@@ -260,6 +261,16 @@ void RCconfig_macrlc(int macrlc_has_f1[MAX_MAC_INST]) {
global_scheduler_mode=SCHED_MODE_DEFAULT;
printf("sched mode = default %d [%s]\n",global_scheduler_mode,*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr));
}
char *s = *MacRLC_ParamList.paramarray[j][MACRLC_DEFAULT_SCHED_DL_ALGO_IDX].strptr;
void *d = dlsym(NULL, s);
AssertFatal(d, "%s(): no default scheduler DL algo '%s' found\n", __func__, s);
// release default, add new
pp_impl_param_t *dl_pp = &RC.mac[j]->pre_processor_dl;
dl_pp->dl_algo.unset(&dl_pp->dl_algo.data);
dl_pp->dl_algo = *(default_sched_dl_algo_t *) d;
dl_pp->dl_algo.data = dl_pp->dl_algo.setup();
LOG_I(ENB_APP, "using default scheduler DL algo '%s'\n", dl_pp->dl_algo.name);
}// j=0..num_inst
} /*else {// MacRLC_ParamList.numelt > 0 // ignore it
+38 -43
View File
@@ -306,6 +306,7 @@ int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) {
if (reply->cell_config[i]->mbsfn_subframe_config_sfalloc)
free(reply->cell_config[i]->mbsfn_subframe_config_sfalloc);
/* si_config is shared between MAC and RRC, free here */
if (reply->cell_config[i]->si_config) {
for(int j = 0; j < reply->cell_config[i]->si_config->n_si_message; j++) {
free(reply->cell_config[i]->si_config->si_message[j]);
@@ -316,26 +317,7 @@ int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) {
}
if (reply->cell_config[i]->slice_config) {
for (int j = 0; j < reply->cell_config[i]->slice_config->n_dl; ++j) {
if (reply->cell_config[i]->slice_config->dl[j]->n_sorting > 0)
free(reply->cell_config[i]->slice_config->dl[j]->sorting);
free(reply->cell_config[i]->slice_config->dl[j]->scheduler_name);
free(reply->cell_config[i]->slice_config->dl[j]);
}
free(reply->cell_config[i]->slice_config->dl);
for (int j = 0; j < reply->cell_config[i]->slice_config->n_ul; ++j) {
if (reply->cell_config[i]->slice_config->ul[j]->n_sorting > 0)
free(reply->cell_config[i]->slice_config->ul[j]->sorting);
free(reply->cell_config[i]->slice_config->ul[j]->scheduler_name);
free(reply->cell_config[i]->slice_config->ul[j]);
}
free(reply->cell_config[i]->slice_config->ul);
free(reply->cell_config[i]->slice_config);
flexran_agent_destroy_mac_slice_config(reply->cell_config[i]);
}
free(reply->cell_config[i]);
@@ -893,31 +875,40 @@ int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void *params, Prot
Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
Protocol__FlexEnbConfigReply *enb_config = input->enb_config_reply_msg;
if (enb_config->n_cell_config == 0) {
LOG_W(FLEXRAN_AGENT,
"received enb_config_reply message does not contain a cell_config\n");
*msg = NULL;
return 0;
}
if (enb_config->n_cell_config > 1)
LOG_W(FLEXRAN_AGENT, "ignoring slice configs for other cell except cell 0\n");
if (flexran_agent_get_mac_xface(mod_id) && enb_config->cell_config[0]->slice_config) {
prepare_update_slice_config(mod_id, enb_config->cell_config[0]->slice_config);
} else if (enb_config->cell_config[0]->has_eutra_band
&& enb_config->cell_config[0]->has_dl_freq
&& enb_config->cell_config[0]->has_ul_freq
&& enb_config->cell_config[0]->has_dl_bandwidth) {
initiate_soft_restart(mod_id, enb_config->cell_config[0]);
} else if (flexran_agent_get_rrc_xface(mod_id)
&& enb_config->cell_config[0]->has_x2_ho_net_control) {
LOG_I(FLEXRAN_AGENT,
"setting X2 HO NetControl to %d\n",
enb_config->cell_config[0]->x2_ho_net_control);
const int rc = flexran_set_x2_ho_net_control(mod_id, enb_config->cell_config[0]->x2_ho_net_control);
if (rc < 0)
LOG_E(FLEXRAN_AGENT, "Error in configuring X2 handover controlled by network");
if (enb_config->n_cell_config > 0) {
if (flexran_agent_get_mac_xface(mod_id) && enb_config->cell_config[0]->slice_config) {
prepare_update_slice_config(mod_id, &enb_config->cell_config[0]->slice_config);
}
if (enb_config->cell_config[0]->has_eutra_band
&& enb_config->cell_config[0]->has_dl_freq
&& enb_config->cell_config[0]->has_ul_freq
&& enb_config->cell_config[0]->has_dl_bandwidth) {
initiate_soft_restart(mod_id, enb_config->cell_config[0]);
}
if (flexran_agent_get_rrc_xface(mod_id)
&& enb_config->cell_config[0]->has_x2_ho_net_control) {
LOG_I(FLEXRAN_AGENT,
"setting X2 HO NetControl to %d\n",
enb_config->cell_config[0]->x2_ho_net_control);
const int rc = flexran_set_x2_ho_net_control(mod_id, enb_config->cell_config[0]->x2_ho_net_control);
if (rc < 0)
LOG_E(FLEXRAN_AGENT, "Error in configuring X2 handover controlled by network");
}
if (flexran_agent_get_rrc_xface(mod_id) && enb_config->cell_config[0]->n_plmn_id > 0) {
flexran_agent_handle_plmn_update(mod_id,
0,
enb_config->cell_config[0]->n_plmn_id,
enb_config->cell_config[0]->plmn_id);
}
}
if (flexran_agent_get_s1ap_xface(mod_id) && enb_config->s1ap) {
flexran_agent_handle_mme_update(mod_id,
enb_config->s1ap->n_mme,
enb_config->s1ap->mme);
}
*msg = NULL;
@@ -930,7 +921,11 @@ int flexran_agent_handle_ue_config_reply(mid_t mod_id, const void *params, Proto
Protocol__FlexUeConfigReply *ue_config_reply = input->ue_config_reply_msg;
for (i = 0; flexran_agent_get_mac_xface(mod_id) && i < ue_config_reply->n_ue_config; i++)
prepare_ue_slice_assoc_update(mod_id, ue_config_reply->ue_config[i]);
prepare_ue_slice_assoc_update(mod_id, &ue_config_reply->ue_config[i]);
/* prepare_ue_slice_assoc_update takes ownership of the individual
* FlexUeConfig messages. Therefore, mark zero messages to not accidentally
* free them twice */
ue_config_reply->n_ue_config = 0;
*msg = NULL;
return 0;
-2
View File
@@ -44,8 +44,6 @@ AGENT_PHY_xface *flexran_agent_get_phy_xface(mid_t mod_id);
extern AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB];
#define flexran_agent_get_mac_xface(mod_id) (agent_mac_xface[mod_id])
/* Control module interface for the communication of the RRC Control Module with the agent */
/* Control module interface for the communication of the RRC Control Module with the agent */
// AGENT_RRC_xface *flexran_agent_get_rrc_xface(mid_t mod_id);
extern AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB];
+407 -422
View File
@@ -30,6 +30,7 @@
#include "flexran_agent_ran_api.h"
#include "s1ap_eNB_ue_context.h"
#include "s1ap_eNB_management_procedures.h"
#include "openair2/LAYER2/MAC/slicing/slicing.h"
static inline int phy_is_present(mid_t mod_id, uint8_t cc_id) {
return RC.eNB && RC.eNB[mod_id] && RC.eNB[mod_id][cc_id];
@@ -3013,471 +3014,293 @@ uint32_t flexran_get_rrc_enb_ue_s1ap_id(mid_t mod_id, rnti_t rnti)
}
/**************************** SLICING ****************************/
int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id) {
if (!mac_is_present(mod_id)) return -1;
Protocol__FlexSliceAlgorithm flexran_get_dl_slice_algo(mid_t mod_id) {
if (!mac_is_present(mod_id)) return PROTOCOL__FLEX_SLICE_ALGORITHM__None;
int slice_idx = 0; //RC.mac[mod_id]->UE_info.assoc_dl_slice_idx[ue_id];
if (slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_dl)
return RC.mac[mod_id]->slice_info.dl[slice_idx].id;
return 0;
switch (RC.mac[mod_id]->pre_processor_dl.algorithm) {
case STATIC_SLICING:
return PROTOCOL__FLEX_SLICE_ALGORITHM__Static;
default:
return PROTOCOL__FLEX_SLICE_ALGORITHM__None;
}
}
void flexran_set_ue_dl_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx) {
int flexran_set_dl_slice_algo(mid_t mod_id, Protocol__FlexSliceAlgorithm algo) {
if (!mac_is_present(mod_id)) return 0;
eNB_MAC_INST *mac = RC.mac[mod_id];
const int cc_id = 0;
pp_impl_param_t dl = mac->pre_processor_dl;
switch (algo) {
case PROTOCOL__FLEX_SLICE_ALGORITHM__Static:
mac->pre_processor_dl = static_dl_init(mod_id, cc_id);
break;
default:
mac->pre_processor_dl.algorithm = 0;
mac->pre_processor_dl.dl = dlsch_scheduler_pre_processor;
mac->pre_processor_dl.dl_algo.data = mac->pre_processor_dl.dl_algo.setup();
mac->pre_processor_dl.slices = NULL;
break;
}
if (dl.slices)
dl.destroy(&dl.slices);
if (dl.dl_algo.data)
dl.dl_algo.unset(&dl.dl_algo.data);
return 1;
}
Protocol__FlexSliceAlgorithm flexran_get_ul_slice_algo(mid_t mod_id) {
if (!mac_is_present(mod_id)) return PROTOCOL__FLEX_SLICE_ALGORITHM__None;
switch (RC.mac[mod_id]->pre_processor_ul.algorithm) {
case STATIC_SLICING:
return PROTOCOL__FLEX_SLICE_ALGORITHM__Static;
default:
return PROTOCOL__FLEX_SLICE_ALGORITHM__None;
}
}
int flexran_set_ul_slice_algo(mid_t mod_id, Protocol__FlexSliceAlgorithm algo) {
if (!mac_is_present(mod_id)) return 0;
eNB_MAC_INST *mac = RC.mac[mod_id];
const int cc_id = 0;
pp_impl_param_t ul = mac->pre_processor_ul;
switch (algo) {
case PROTOCOL__FLEX_SLICE_ALGORITHM__Static:
mac->pre_processor_ul = static_ul_init(mod_id, cc_id);
break;
default:
mac->pre_processor_ul.algorithm = 0;
mac->pre_processor_ul.ul = ulsch_scheduler_pre_processor;
mac->pre_processor_ul.ul_algo.data = mac->pre_processor_ul.ul_algo.setup();
mac->pre_processor_ul.slices = NULL;
break;
}
if (ul.slices)
ul.destroy(&ul.slices);
if (ul.ul_algo.data)
ul.ul_algo.unset(&ul.ul_algo.data);
return 1;
}
int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id) {
if (!mac_is_present(mod_id)) return -1;
slice_info_t *slices = RC.mac[mod_id]->pre_processor_dl.slices;
if (!slices) return -1;
const int idx = slices->UE_assoc_slice[ue_id];
return slices->s[idx]->id;
}
void flexran_set_ue_dl_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id) {
if (!mac_is_present(mod_id)) return;
if (flexran_get_mac_ue_crnti(mod_id, ue_id) == NOT_A_RNTI) return;
if (!flexran_dl_slice_exists(mod_id, slice_idx)) return;
//RC.mac[mod_id]->UE_info.assoc_dl_slice_idx[ue_id] = slice_idx;
int idx = flexran_find_dl_slice(mod_id, slice_id);
if (idx < 0) return;
pp_impl_param_t *dl = &RC.mac[mod_id]->pre_processor_dl;
dl->move_UE(dl->slices, ue_id, idx);
}
int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id) {
if (!mac_is_present(mod_id)) return -1;
int slice_idx = 0; //RC.mac[mod_id]->UE_info.assoc_ul_slice_idx[ue_id];
if (slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_ul)
return RC.mac[mod_id]->slice_info.ul[slice_idx].id;
return 0;
slice_info_t *slices = RC.mac[mod_id]->pre_processor_ul.slices;
if (!slices) return -1;
const int idx = slices->UE_assoc_slice[ue_id];
return slices->s[idx]->id;
}
void flexran_set_ue_ul_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx) {
void flexran_set_ue_ul_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id) {
if (!mac_is_present(mod_id)) return;
if (flexran_get_mac_ue_crnti(mod_id, ue_id) == NOT_A_RNTI) return;
if (!flexran_ul_slice_exists(mod_id, slice_idx)) return;
//RC.mac[mod_id]->UE_info.assoc_ul_slice_idx[ue_id] = slice_idx;
int idx = flexran_find_ul_slice(mod_id, slice_id);
if (idx < 0) return;
pp_impl_param_t *ul = &RC.mac[mod_id]->pre_processor_ul;
ul->move_UE(ul->slices, ue_id, idx);
}
int flexran_dl_slice_exists(mid_t mod_id, int slice_idx) {
if (!mac_is_present(mod_id)) return -1;
return slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_dl;
int flexran_create_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s) {
if (!mac_is_present(mod_id)) return 0;
void *params = NULL;
switch (s->params_case) {
case PROTOCOL__FLEX_SLICE__PARAMS_STATIC:
params = malloc(sizeof(static_slice_param_t));
if (!params) return 0;
((static_slice_param_t *)params)->posLow = s->static_->poslow;
((static_slice_param_t *)params)->posHigh = s->static_->poshigh;
break;
default:
break;
}
pp_impl_param_t *dl = &RC.mac[mod_id]->pre_processor_dl;
char *l = s->label ? strdup(s->label) : NULL;
void *algo = &dl->dl_algo; // default scheduler
if (s->scheduler) {
algo = dlsym(NULL, s->scheduler);
if (!algo) {
free(params);
LOG_E(FLEXRAN_AGENT, "cannot locate scheduler '%s'\n", s->scheduler);
return -15;
}
}
return dl->addmod_slice(dl->slices, s->id, l, algo, params);
}
int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id) {
if (!mac_is_present(mod_id)) return -1;
int newidx = RC.mac[mod_id]->slice_info.n_dl;
if (newidx >= MAX_NUM_SLICES) return -1;
++RC.mac[mod_id]->slice_info.n_dl;
flexran_set_dl_slice_id(mod_id, newidx, slice_id);
return newidx;
int flexran_remove_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s) {
if (!mac_is_present(mod_id)) return 0;
const int idx = flexran_find_dl_slice(mod_id, s->id);
if (idx < 0) return 0;
pp_impl_param_t *dl = &RC.mac[mod_id]->pre_processor_dl;
return dl->remove_slice(dl->slices, idx);
}
int flexran_find_dl_slice(mid_t mod_id, slice_id_t slice_id) {
if (!mac_is_present(mod_id)) return -1;
slice_info_t *sli = &RC.mac[mod_id]->slice_info;
int n = sli->n_dl;
for (int i = 0; i < n; i++) {
if (sli->dl[i].id == slice_id) return i;
}
slice_info_t *si = RC.mac[mod_id]->pre_processor_dl.slices;
for (int i = 0; i < si->num; ++i)
if (si->s[i]->id == slice_id)
return i;
return -1;
}
int flexran_remove_dl_slice(mid_t mod_id, int slice_idx) {
if (!mac_is_present(mod_id)) return -1;
slice_info_t *sli = &RC.mac[mod_id]->slice_info;
if (sli->n_dl <= 1) return -1;
if (sli->dl[slice_idx].sched_name) free(sli->dl[slice_idx].sched_name);
--sli->n_dl;
/* move last element to the position of the removed one */
if (slice_idx != sli->n_dl)
memcpy(&sli->dl[slice_idx], &sli->dl[sli->n_dl], sizeof(sli->dl[sli->n_dl]));
memset(&sli->dl[sli->n_dl], 0, sizeof(sli->dl[sli->n_dl]));
/* all UEs that have been in the old slice are put into slice index 0 */
//int *assoc_list = RC.mac[mod_id]->UE_info.assoc_dl_slice_idx;
//for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) {
// if (assoc_list[i] == slice_idx)
// assoc_list[i] = 0;
//}
return 1;
void flexran_get_dl_slice(mid_t mod_id,
int slice_idx,
Protocol__FlexSlice *slice,
Protocol__FlexSliceAlgorithm algo) {
if (!mac_is_present(mod_id)) return;
slice_t *s_ = RC.mac[mod_id]->pre_processor_dl.slices->s[slice_idx];
slice->has_id = 1;
slice->id = s_->id;
slice->label = s_->label;
slice->scheduler = s_->dl_algo.name;
slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS__NOT_SET;
switch (algo) {
case PROTOCOL__FLEX_SLICE_ALGORITHM__Static:
slice->static_ = malloc(sizeof(Protocol__FlexSliceStatic));
if (!slice->static_) return;
protocol__flex_slice_static__init(slice->static_);
slice->static_->has_poslow = 1;
slice->static_->poslow = ((static_slice_param_t *)s_->algo_data)->posLow;
slice->static_->has_poshigh = 1;
slice->static_->poshigh = ((static_slice_param_t *)s_->algo_data)->posHigh;
slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS_STATIC;
break;
default:
break;
}
}
int flexran_get_num_dl_slices(mid_t mod_id) {
if (!mac_is_present(mod_id)) return -1;
return RC.mac[mod_id]->slice_info.n_dl;
}
int flexran_get_intraslice_sharing_active(mid_t mod_id) {
if (!mac_is_present(mod_id)) return -1;
return RC.mac[mod_id]->slice_info.intraslice_share_active;
}
void flexran_set_intraslice_sharing_active(mid_t mod_id, int intraslice_active) {
if (!mac_is_present(mod_id)) return;
RC.mac[mod_id]->slice_info.intraslice_share_active = intraslice_active;
}
int flexran_get_interslice_sharing_active(mid_t mod_id) {
if (!mac_is_present(mod_id)) return -1;
return RC.mac[mod_id]->slice_info.interslice_share_active;
}
void flexran_set_interslice_sharing_active(mid_t mod_id, int interslice_active) {
if (!mac_is_present(mod_id)) return;
RC.mac[mod_id]->slice_info.interslice_share_active = interslice_active;
}
slice_id_t flexran_get_dl_slice_id(mid_t mod_id, int slice_idx) {
if (!mac_is_present(mod_id)) return -1;
return RC.mac[mod_id]->slice_info.dl[slice_idx].id;
}
void flexran_set_dl_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id) {
if (!mac_is_present(mod_id)) return;
RC.mac[mod_id]->slice_info.dl[slice_idx].id = slice_id;
}
int flexran_get_dl_slice_percentage(mid_t mod_id, int slice_idx) {
if (!mac_is_present(mod_id)) return -1;
return RC.mac[mod_id]->slice_info.dl[slice_idx].pct * 100.0f;
}
void flexran_set_dl_slice_percentage(mid_t mod_id, int slice_idx, int percentage) {
if (!mac_is_present(mod_id)) return;
RC.mac[mod_id]->slice_info.dl[slice_idx].pct = percentage / 100.0f;
}
int flexran_get_dl_slice_isolation(mid_t mod_id, int slice_idx) {
if (!mac_is_present(mod_id)) return -1;
return RC.mac[mod_id]->slice_info.dl[slice_idx].isol;
}
void flexran_set_dl_slice_isolation(mid_t mod_id, int slice_idx, int is_isolated) {
if (!mac_is_present(mod_id)) return;
RC.mac[mod_id]->slice_info.dl[slice_idx].isol = is_isolated;
}
int flexran_get_dl_slice_priority(mid_t mod_id, int slice_idx) {
if (!mac_is_present(mod_id)) return -1;
return RC.mac[mod_id]->slice_info.dl[slice_idx].prio;
}
void flexran_set_dl_slice_priority(mid_t mod_id, int slice_idx, int priority) {
if (!mac_is_present(mod_id)) return;
RC.mac[mod_id]->slice_info.dl[slice_idx].prio = priority;
}
int flexran_get_dl_slice_position_low(mid_t mod_id, int slice_idx) {
if (!mac_is_present(mod_id)) return -1;
return RC.mac[mod_id]->slice_info.dl[slice_idx].pos_low;
}
void flexran_set_dl_slice_position_low(mid_t mod_id, int slice_idx, int poslow) {
if (!mac_is_present(mod_id)) return;
RC.mac[mod_id]->slice_info.dl[slice_idx].pos_low = poslow;
}
int flexran_get_dl_slice_position_high(mid_t mod_id, int slice_idx) {
if (!mac_is_present(mod_id)) return -1;
return RC.mac[mod_id]->slice_info.dl[slice_idx].pos_high;
}
void flexran_set_dl_slice_position_high(mid_t mod_id, int slice_idx, int poshigh) {
if (!mac_is_present(mod_id)) return;
RC.mac[mod_id]->slice_info.dl[slice_idx].pos_high = poshigh;
}
int flexran_get_dl_slice_maxmcs(mid_t mod_id, int slice_idx) {
if (!mac_is_present(mod_id)) return -1;
return RC.mac[mod_id]->slice_info.dl[slice_idx].maxmcs;
}
void flexran_set_dl_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs) {
if (!mac_is_present(mod_id)) return;
RC.mac[mod_id]->slice_info.dl[slice_idx].maxmcs = maxmcs;
}
int flexran_get_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting **sorting_list) {
if (!mac_is_present(mod_id)) return -1;
if (!(*sorting_list)) {
*sorting_list = calloc(CR_NUM, sizeof(Protocol__FlexDlSorting));
if (!(*sorting_list)) return -1;
}
uint32_t policy = RC.mac[mod_id]->slice_info.dl[slice_idx].sorting;
for (int i = 0; i < CR_NUM; i++) {
switch (policy >> 4 * (CR_NUM - 1 - i) & 0xF) {
case CR_ROUND:
(*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_ROUND;
break;
case CR_SRB12:
(*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_SRB12;
break;
case CR_HOL:
(*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_HOL;
break;
case CR_LC:
(*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_LC;
break;
case CR_CQI:
(*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_CQI;
break;
case CR_LCP:
(*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_LCP;
break;
default:
/* this should not happen, but a "default" */
(*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_ROUND;
break;
}
}
return CR_NUM;
}
void flexran_set_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting *sorting_list, int n) {
if (!mac_is_present(mod_id)) return;
uint32_t policy = 0;
for (int i = 0; i < n && i < CR_NUM; i++) {
switch (sorting_list[i]) {
case PROTOCOL__FLEX_DL_SORTING__CR_ROUND:
policy = policy << 4 | CR_ROUND;
break;
case PROTOCOL__FLEX_DL_SORTING__CR_SRB12:
policy = policy << 4 | CR_SRB12;
break;
case PROTOCOL__FLEX_DL_SORTING__CR_HOL:
policy = policy << 4 | CR_HOL;
break;
case PROTOCOL__FLEX_DL_SORTING__CR_LC:
policy = policy << 4 | CR_LC;
break;
case PROTOCOL__FLEX_DL_SORTING__CR_CQI:
policy = policy << 4 | CR_CQI;
break;
case PROTOCOL__FLEX_DL_SORTING__CR_LCP:
policy = policy << 4 | CR_LCP;
break;
default: /* suppresses warnings */
policy = policy << 4 | CR_ROUND;
break;
}
}
/* fill up with 0 == CR_ROUND */
if (CR_NUM > n) policy = policy << 4 * (CR_NUM - n);
RC.mac[mod_id]->slice_info.dl[slice_idx].sorting = policy;
}
Protocol__FlexDlAccountingPolicy flexran_get_dl_slice_accounting_policy(mid_t mod_id, int slice_idx) {
if (!mac_is_present(mod_id)) return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR;
switch (RC.mac[mod_id]->slice_info.dl[slice_idx].accounting) {
case POL_FAIR:
return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR;
case POL_GREEDY:
return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_GREEDY;
default:
return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR;
}
}
void flexran_set_dl_slice_accounting_policy(mid_t mod_id, int slice_idx, Protocol__FlexDlAccountingPolicy accounting) {
if (!mac_is_present(mod_id)) return;
switch (accounting) {
case PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR:
RC.mac[mod_id]->slice_info.dl[slice_idx].accounting = POL_FAIR;
return;
case PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_GREEDY:
RC.mac[mod_id]->slice_info.dl[slice_idx].accounting = POL_GREEDY;
return;
default:
RC.mac[mod_id]->slice_info.dl[slice_idx].accounting = POL_FAIR;
return;
}
}
char *flexran_get_dl_slice_scheduler(mid_t mod_id, int slice_idx) {
if (!mac_is_present(mod_id)) return NULL;
return RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name;
}
int flexran_set_dl_slice_scheduler(mid_t mod_id, int slice_idx, char *name) {
if (!mac_is_present(mod_id)) return 0;
if (RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name)
free(RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name);
RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name = strdup(name);
RC.mac[mod_id]->slice_info.dl[slice_idx].sched_cb = dlsym(NULL, name);
return RC.mac[mod_id]->slice_info.dl[slice_idx].sched_cb != NULL;
if (!RC.mac[mod_id]->pre_processor_dl.slices) return 0;
return RC.mac[mod_id]->pre_processor_dl.slices->num;
}
int flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id) {
int flexran_create_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s) {
if (!mac_is_present(mod_id)) return -1;
void *params = NULL;
switch (s->params_case) {
case PROTOCOL__FLEX_SLICE__PARAMS_STATIC:
params = malloc(sizeof(static_slice_param_t));
if (!params) return 0;
((static_slice_param_t *)params)->posLow = s->static_->poslow;
((static_slice_param_t *)params)->posHigh = s->static_->poshigh;
break;
default:
break;
}
pp_impl_param_t *ul = &RC.mac[mod_id]->pre_processor_ul;
char *l = s->label ? strdup(s->label) : NULL;
void *algo = &ul->ul_algo; // default scheduler
if (s->scheduler) {
algo = dlsym(NULL, s->scheduler);
if (!algo) {
free(params);
LOG_E(FLEXRAN_AGENT, "cannot locate scheduler '%s'\n", s->scheduler);
return -15;
}
}
return ul->addmod_slice(ul->slices, s->id, l, algo, params);
}
int newidx = RC.mac[mod_id]->slice_info.n_ul;
if (newidx >= MAX_NUM_SLICES) return -1;
++RC.mac[mod_id]->slice_info.n_ul;
flexran_set_ul_slice_id(mod_id, newidx, slice_id);
return newidx;
int flexran_remove_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s) {
if (!mac_is_present(mod_id)) return 0;
const int idx = flexran_find_ul_slice(mod_id, s->id);
if (idx < 0) return 0;
pp_impl_param_t *ul = &RC.mac[mod_id]->pre_processor_ul;
return ul->remove_slice(ul->slices, idx);
}
int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id) {
if (!mac_is_present(mod_id)) return -1;
slice_info_t *sli = &RC.mac[mod_id]->slice_info;
int n = sli->n_ul;
for (int i = 0; i < n; i++) {
if (sli->ul[i].id == slice_id) return i;
}
slice_info_t *si = RC.mac[mod_id]->pre_processor_ul.slices;
for (int i = 0; i < si->num; ++i)
if (si->s[i]->id == slice_id)
return i;
return -1;
}
int flexran_remove_ul_slice(mid_t mod_id, int slice_idx) {
if (!mac_is_present(mod_id)) return -1;
void flexran_get_ul_slice(mid_t mod_id,
int slice_idx,
Protocol__FlexSlice *slice,
Protocol__FlexSliceAlgorithm algo) {
if (!mac_is_present(mod_id)) return;
slice_t *s_ = RC.mac[mod_id]->pre_processor_ul.slices->s[slice_idx];
slice->has_id = 1;
slice->id = s_->id;
slice->label = s_->label;
slice->scheduler = s_->ul_algo.name;
slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS__NOT_SET;
switch (algo) {
case PROTOCOL__FLEX_SLICE_ALGORITHM__Static:
slice->static_ = malloc(sizeof(Protocol__FlexSliceStatic));
if (!slice->static_) return;
protocol__flex_slice_static__init(slice->static_);
slice->static_->has_poslow = 1;
slice->static_->poslow = ((static_slice_param_t *)s_->algo_data)->posLow;
slice->static_->has_poshigh = 1;
slice->static_->poshigh = ((static_slice_param_t *)s_->algo_data)->posHigh;
slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS_STATIC;
break;
default:
break;
}
slice_info_t *sli = &RC.mac[mod_id]->slice_info;
if (sli->n_ul <= 1) return -1;
if (sli->ul[slice_idx].sched_name) free(sli->ul[slice_idx].sched_name);
--sli->n_ul;
/* move last element to the position of the removed one */
if (slice_idx != sli->n_ul)
memcpy(&sli->ul[slice_idx], &sli->ul[sli->n_ul], sizeof(sli->ul[sli->n_ul]));
memset(&sli->ul[sli->n_ul], 0, sizeof(sli->ul[sli->n_ul]));
/* all UEs that have been in the old slice are put into slice index 0 */
//int *assoc_list = RC.mac[mod_id]->UE_info.assoc_ul_slice_idx;
//for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) {
// if (assoc_list[i] == slice_idx)
// assoc_list[i] = 0;
//}
return sli->n_ul;
}
int flexran_get_num_ul_slices(mid_t mod_id) {
if (!mac_is_present(mod_id)) return -1;
return RC.mac[mod_id]->slice_info.n_ul;
}
int flexran_ul_slice_exists(mid_t mod_id, int slice_idx) {
if (!mac_is_present(mod_id)) return -1;
return slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_ul;
}
slice_id_t flexran_get_ul_slice_id(mid_t mod_id, int slice_idx) {
if (!mac_is_present(mod_id)) return -1;
return RC.mac[mod_id]->slice_info.ul[slice_idx].id;
}
void flexran_set_ul_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id) {
if (!mac_is_present(mod_id)) return;
RC.mac[mod_id]->slice_info.ul[slice_idx].id = slice_id;
}
int flexran_get_ul_slice_percentage(mid_t mod_id, int slice_idx) {
if (!mac_is_present(mod_id)) return -1;
return RC.mac[mod_id]->slice_info.ul[slice_idx].pct * 100.0f;
}
void flexran_set_ul_slice_percentage(mid_t mod_id, int slice_idx, int percentage) {
if (!mac_is_present(mod_id)) return;
RC.mac[mod_id]->slice_info.ul[slice_idx].pct = percentage / 100.0f;
}
int flexran_get_ul_slice_first_rb(mid_t mod_id, int slice_idx) {
if (!mac_is_present(mod_id)) return -1;
return RC.mac[mod_id]->slice_info.ul[slice_idx].first_rb;
}
void flexran_set_ul_slice_first_rb(mid_t mod_id, int slice_idx, int first_rb) {
if (!mac_is_present(mod_id)) return;
RC.mac[mod_id]->slice_info.ul[slice_idx].first_rb = first_rb;
}
int flexran_get_ul_slice_maxmcs(mid_t mod_id, int slice_idx) {
if (!mac_is_present(mod_id)) return -1;
return RC.mac[mod_id]->slice_info.ul[slice_idx].maxmcs;
}
void flexran_set_ul_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs) {
if (!mac_is_present(mod_id)) return;
RC.mac[mod_id]->slice_info.ul[slice_idx].maxmcs = maxmcs;
}
char *flexran_get_ul_slice_scheduler(mid_t mod_id, int slice_idx) {
if (!mac_is_present(mod_id)) return NULL;
return RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name;
}
int flexran_set_ul_slice_scheduler(mid_t mod_id, int slice_idx, char *name) {
if (!mac_is_present(mod_id)) return 0;
if (!RC.mac[mod_id]->pre_processor_ul.slices) return 0;
return RC.mac[mod_id]->pre_processor_ul.slices->num;
}
if (RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name)
free(RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name);
char *flexran_get_dl_scheduler_name(mid_t mod_id) {
if (!mac_is_present(mod_id)) return NULL;
return RC.mac[mod_id]->pre_processor_dl.dl_algo.name;
}
RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name = strdup(name);
RC.mac[mod_id]->slice_info.ul[slice_idx].sched_cb = dlsym(NULL, name);
return RC.mac[mod_id]->slice_info.ul[slice_idx].sched_cb != NULL;
int flexran_set_dl_scheduler(mid_t mod_id, char *sched) {
if (!mac_is_present(mod_id)) return -1;
void *d = dlsym(NULL, sched);
if (!d) return -2;
pp_impl_param_t *dl_pp = &RC.mac[mod_id]->pre_processor_dl;
dl_pp->dl_algo.unset(&dl_pp->dl_algo.data);
dl_pp->dl_algo = *(default_sched_dl_algo_t *) d;
dl_pp->dl_algo.data = dl_pp->dl_algo.setup();
return 0;
}
char *flexran_get_ul_scheduler_name(mid_t mod_id) {
if (!mac_is_present(mod_id)) return NULL;
return RC.mac[mod_id]->pre_processor_ul.ul_algo.name;
}
int flexran_set_ul_scheduler(mid_t mod_id, char *sched) {
if (!mac_is_present(mod_id)) return -1;
void *d = dlsym(NULL, sched);
if (!d) return -2;
pp_impl_param_t *ul_pp = &RC.mac[mod_id]->pre_processor_ul;
ul_pp->ul_algo.unset(&ul_pp->ul_algo.data);
ul_pp->ul_algo = *(default_sched_ul_algo_t *) d;
ul_pp->ul_algo.data = ul_pp->ul_algo.setup();
return 0;
}
/************************** S1AP **************************/
@@ -3634,6 +3457,168 @@ int flexran_get_s1ap_mme_conf(mid_t mod_id, mid_t mme_index, Protocol__FlexS1apM
return 0;
}
int flexran_add_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4) {
s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id);
if (!s1ap) return -1;
if (!rrc_is_present(mod_id)) return -2;
/* Reconstruct S1AP_REGISTER_ENB_REQ */
MessageDef *m = itti_alloc_new_message(TASK_FLEXRAN_AGENT, S1AP_REGISTER_ENB_REQ);
RCconfig_S1(m, mod_id);
const int CC_id = 0;
eNB_RRC_INST *rrc = RC.rrc[CC_id];
RrcConfigurationReq *conf = &rrc->configuration;
S1AP_REGISTER_ENB_REQ(m).num_plmn = conf->num_plmn;
for (int i = 0; i < conf->num_plmn; ++i) {
S1AP_REGISTER_ENB_REQ(m).mcc[i] = conf->mcc[i];
S1AP_REGISTER_ENB_REQ(m).mnc[i] = conf->mnc[i];
S1AP_REGISTER_ENB_REQ(m).mnc_digit_length[i] = conf->mnc_digit_length[i];
}
/* reconstruct MME list, it might have been updated since initial
* configuration */
S1AP_REGISTER_ENB_REQ(m).nb_mme = 0;
struct s1ap_eNB_mme_data_s *mme = NULL;
RB_FOREACH(mme, s1ap_mme_map, &s1ap->s1ap_mme_head) {
const int n = S1AP_REGISTER_ENB_REQ(m).nb_mme;
S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4 = mme->mme_s1_ip.ipv4;
strcpy(S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4_address, mme->mme_s1_ip.ipv4_address);
S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv6 = mme->mme_s1_ip.ipv6;
strcpy(S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv6_address, mme->mme_s1_ip.ipv6_address);
S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_num[n] = mme->broadcast_plmn_num;
for (int i = 0; i < mme->broadcast_plmn_num; ++i)
S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_index[n][i] = mme->broadcast_plmn_index[i];
S1AP_REGISTER_ENB_REQ(m).nb_mme += 1;
}
if (S1AP_REGISTER_ENB_REQ(m).nb_mme + n_mme > S1AP_MAX_NB_MME_IP_ADDRESS)
return -1;
for (int i = 0; i < n_mme; ++i) {
const int n = S1AP_REGISTER_ENB_REQ(m).nb_mme;
strcpy(S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4_address, mme_ipv4[0]);
S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4 = 1;
S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv6 = 0;
S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_num[n] = S1AP_REGISTER_ENB_REQ(m).num_plmn;
for (int i = 0; i < S1AP_REGISTER_ENB_REQ(m).num_plmn; ++i)
S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_index[n][i] = i;
S1AP_REGISTER_ENB_REQ(m).nb_mme += 1;
}
itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(mod_id), m);
return 0;
}
int flexran_remove_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4) {
s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id);
if (!s1ap) return -1;
struct s1ap_eNB_mme_data_s *mme = NULL;
RB_FOREACH(mme, s1ap_mme_map, &s1ap->s1ap_mme_head) {
if (mme->mme_s1_ip.ipv4
&& strncmp(mme->mme_s1_ip.ipv4_address, mme_ipv4[0], 16) == 0)
break;
}
if (!mme)
return -2;
MessageDef *m = itti_alloc_new_message(TASK_FLEXRAN_AGENT, SCTP_CLOSE_ASSOCIATION);
SCTP_CLOSE_ASSOCIATION(m).assoc_id = mme->assoc_id;
itti_send_msg_to_task (TASK_SCTP, ENB_MODULE_ID_TO_INSTANCE(mod_id), m);
switch (mme->state) {
case S1AP_ENB_STATE_WAITING:
s1ap->s1ap_mme_nb -= 1;
if (s1ap->s1ap_mme_pending_nb > 0)
s1ap->s1ap_mme_pending_nb -= 1;
break;
case S1AP_ENB_STATE_CONNECTED:
case S1AP_ENB_OVERLOAD: /* I am not sure the decrements are right here */
s1ap->s1ap_mme_nb -= 1;
s1ap->s1ap_mme_associated_nb -= 1;
break;
case S1AP_ENB_STATE_DISCONNECTED:
default:
break;
}
RB_REMOVE(s1ap_mme_map, &s1ap->s1ap_mme_head, mme);
return 0;
}
int flexran_set_new_plmn_id(mid_t mod_id, int CC_id, size_t n_plmn, Protocol__FlexPlmn **plmn_id) {
if (!rrc_is_present(mod_id))
return -1;
s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id);
if (!s1ap)
return -2;
eNB_RRC_INST *rrc = RC.rrc[CC_id];
RrcConfigurationReq *conf = &rrc->configuration;
uint8_t num_plmn_old = conf->num_plmn;
uint16_t mcc[PLMN_LIST_MAX_SIZE];
uint16_t mnc[PLMN_LIST_MAX_SIZE];
uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE];
for (int i = 0; i < num_plmn_old; ++i) {
mcc[i] = conf->mcc[i];
mnc[i] = conf->mnc[i];
mnc_digit_length[i] = conf->mnc_digit_length[i];
}
conf->num_plmn = (uint8_t) n_plmn;
for (int i = 0; i < conf->num_plmn; ++i) {
conf->mcc[i] = plmn_id[i]->mcc;
conf->mnc[i] = plmn_id[i]->mnc;
conf->mnc_digit_length[i] = plmn_id[i]->mnc_length;
}
rrc_eNB_carrier_data_t *carrier = &rrc->carrier[CC_id];
extern uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier,
int Mod_id,
int CC_id,
BOOLEAN_t brOption,
RrcConfigurationReq *configuration);
carrier->sizeof_SIB1 = do_SIB1(carrier, mod_id, CC_id, FALSE, conf);
if (carrier->sizeof_SIB1 < 0)
return -1337; /* SIB1 encoding failed, hell will probably break loose */
s1ap->num_plmn = (uint8_t) n_plmn;
for (int i = 0; i < conf->num_plmn; ++i) {
s1ap->mcc[i] = plmn_id[i]->mcc;
s1ap->mnc[i] = plmn_id[i]->mnc;
s1ap->mnc_digit_length[i] = plmn_id[i]->mnc_length;
}
int bpn_failed = 0;
struct s1ap_eNB_mme_data_s *mme = NULL;
RB_FOREACH(mme, s1ap_mme_map, &s1ap->s1ap_mme_head) {
for (int i = 0; i < mme->broadcast_plmn_num; ++i) {
/* search the new index and update. If we don't find, we count this using
* bpn_failed to now how many broadcast_plmns could not be updated */
int idx = mme->broadcast_plmn_index[i];
int omcc = mcc[idx];
int omnc = mnc[idx];
int omncl = mnc_digit_length[idx];
int j = 0;
for (j = 0; j < s1ap->num_plmn; ++j) {
if (s1ap->mcc[j] == omcc
&& s1ap->mnc[j] == omnc
&& s1ap->mnc_digit_length[j] == omncl) {
mme->broadcast_plmn_index[i] = j;
break;
}
}
if (j == s1ap->num_plmn) /* could not find the old PLMN in the new ones */
bpn_failed++;
}
}
if (bpn_failed > 0)
return -10000 - bpn_failed;
return 0;
}
int flexran_get_s1ap_ue(mid_t mod_id, rnti_t rnti, Protocol__FlexS1apUe * ue_conf){
if (!rrc_is_present(mod_id)) return -1;
s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id);
@@ -3644,7 +3629,7 @@ int flexran_get_s1ap_ue(mid_t mod_id, rnti_t rnti, Protocol__FlexS1apUe * ue_con
RB_FOREACH(ue, s1ap_ue_map, &s1ap->s1ap_ue_head){
if (ue->eNB_ue_s1ap_id == enb_ue_s1ap_id) break;
}
if (ue == NULL) return -1;
if (!ue) return 0; // UE does not exist: it might be connected but CN did not answer
if (ue->mme_ref->mme_s1_ip.ipv4)
ue_conf->mme_s1_ip = (char*) &ue->mme_ref->mme_s1_ip.ipv4_address[0];
+52 -133
View File
@@ -656,156 +656,66 @@ int flexran_agent_rrc_gtp_get_teid_sgw(mid_t mod_id, rnti_t rnti, int index);
uint32_t flexran_get_rrc_enb_ue_s1ap_id(mid_t mod_id, rnti_t rnti);
/************************** Slice configuration **************************/
/* Get the currently active DL slicing algorithm */
Protocol__FlexSliceAlgorithm flexran_get_dl_slice_algo(mid_t mod_id);
/* Set the active DL slicing algorithm */
int flexran_set_dl_slice_algo(mid_t mod_id, Protocol__FlexSliceAlgorithm algo);
/* Get the currently active UL slicing algorithm */
Protocol__FlexSliceAlgorithm flexran_get_ul_slice_algo(mid_t mod_id);
/* Set the active UL slicing algorithm */
int flexran_set_ul_slice_algo(mid_t mod_id, Protocol__FlexSliceAlgorithm algo);
/* Get the DL slice ID for a UE */
int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id);
/* Set the DL slice index(!) for a UE */
void flexran_set_ue_dl_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx);
/* Set the DL slice for a UE */
void flexran_set_ue_dl_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id);
/* Get the UL slice ID for a UE */
int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id);
/* Set the UL slice for a UE */
void flexran_set_ue_ul_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id);
/* Set the UL slice index(!) for a UE */
void flexran_set_ue_ul_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx);
/* Whether intraslice sharing is active, return boolean */
int flexran_get_intraslice_sharing_active(mid_t mod_id);
/* Set whether intraslice sharing is active */
void flexran_set_intraslice_sharing_active(mid_t mod_id, int intraslice_active);
/* Whether intraslice sharing is active, return boolean */
int flexran_get_interslice_sharing_active(mid_t mod_id);
/* Set whether intraslice sharing is active */
void flexran_set_interslice_sharing_active(mid_t mod_id, int interslice_active);
/* Create slice in DL, returns the new slice index */
int flexran_create_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s);
/* Remove slice in DL, returns new number of slices or -1 on error */
int flexran_remove_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s);
/* Finds slice in DL with given slice_id and returns slice index */
int flexran_find_dl_slice(mid_t mod_id, slice_id_t slice_id);
/* Return the parameters of slice at index slice_idx */
void flexran_get_dl_slice(mid_t mod_id,
int slice_idx,
Protocol__FlexSlice *slice,
Protocol__FlexSliceAlgorithm algo);
/* Get the number of slices in DL */
int flexran_get_num_dl_slices(mid_t mod_id);
/* Query slice existence in DL. Return is boolean value */
int flexran_dl_slice_exists(mid_t mod_id, int slice_idx);
/* Create slice in UL, returns the new slice index */
int flexran_create_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s);
/* Remove slice in UL */
int flexran_remove_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s);
/* Create slice in DL, returns the new slice index */
int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id);
/* Finds slice in DL with given slice_id and returns slice index */
int flexran_find_dl_slice(mid_t mod_id, slice_id_t slice_id);
/* Remove slice in DL, returns new number of slices or -1 on error */
int flexran_remove_dl_slice(mid_t mod_id, int slice_idx);
/* Get the ID of a slice in DL */
slice_id_t flexran_get_dl_slice_id(mid_t mod_id, int slice_idx);
/* Set the ID of a slice in DL */
void flexran_set_dl_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id);
/* Get the RB share a slice in DL, value 0-100 */
int flexran_get_dl_slice_percentage(mid_t mod_id, int slice_idx);
/* Set the RB share a slice in DL, value 0-100 */
void flexran_set_dl_slice_percentage(mid_t mod_id, int slice_idx, int percentage);
/* Whether a slice in DL is isolated */
int flexran_get_dl_slice_isolation(mid_t mod_id, int slice_idx);
/* Set whether a slice in DL is isolated */
void flexran_set_dl_slice_isolation(mid_t mod_id, int slice_idx, int is_isolated);
/* Get the priority of a slice in DL */
int flexran_get_dl_slice_priority(mid_t mod_id, int slice_idx);
/* Get the priority of a slice in DL */
void flexran_set_dl_slice_priority(mid_t mod_id, int slice_idx, int priority);
/* Get the lower end of the frequency range for the slice positioning in DL */
int flexran_get_dl_slice_position_low(mid_t mod_id, int slice_idx);
/* Set the lower end of the frequency range for the slice positioning in DL */
void flexran_set_dl_slice_position_low(mid_t mod_id, int slice_idx, int poslow);
/* Get the higher end of the frequency range for the slice positioning in DL */
int flexran_get_dl_slice_position_high(mid_t mod_id, int slice_idx);
/* Set the higher end of the frequency range for the slice positioning in DL */
void flexran_set_dl_slice_position_high(mid_t mod_id, int slice_idx, int poshigh);
/* Get the maximum MCS for slice in DL */
int flexran_get_dl_slice_maxmcs(mid_t mod_id, int slice_idx);
/* Set the maximum MCS for slice in DL */
void flexran_set_dl_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs);
/* Get the sorting order of a slice in DL, return value is number of elements
* in sorting_list */
int flexran_get_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting **sorting_list);
/* Set the sorting order of a slice in DL */
void flexran_set_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting *sorting_list, int n);
/* Get the accounting policy for a slice in DL */
Protocol__FlexDlAccountingPolicy flexran_get_dl_slice_accounting_policy(mid_t mod_id, int slice_idx);
/* Set the accounting policy for a slice in DL */
void flexran_set_dl_slice_accounting_policy(mid_t mod_id, int slice_idx, Protocol__FlexDlAccountingPolicy accounting);
/* Get the scheduler name for a slice in DL */
char *flexran_get_dl_slice_scheduler(mid_t mod_id, int slice_idx);
/* Set the scheduler name for a slice in DL */
int flexran_set_dl_slice_scheduler(mid_t mod_id, int slice_idx, char *name);
int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id);
/* Return the parameters of slice at index slice_idx */
void flexran_get_ul_slice(mid_t mod_id,
int slice_idx,
Protocol__FlexSlice *slice,
Protocol__FlexSliceAlgorithm algo);
/* Get the number of slices in UL */
int flexran_get_num_ul_slices(mid_t mod_id);
/* Query slice existence in UL. Return is boolean value */
int flexran_ul_slice_exists(mid_t mod_id, int slice_idx);
/* Get the name of/Set the DL scheduling algorithm. If slicing is active, this
* corresponds to the default algorithm for slices, otherwise the currently
* used one. */
char *flexran_get_dl_scheduler_name(mid_t mod_id);
int flexran_set_dl_scheduler(mid_t mod_id, char *sched);
/* Create slice in UL, returns the new slice index */
int flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id);
/* Finds slice in UL with given slice_id and returns slice index */
int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id);
/* Remove slice in UL */
int flexran_remove_ul_slice(mid_t mod_id, int slice_idx);
/* Get the ID of a slice in UL */
slice_id_t flexran_get_ul_slice_id(mid_t mod_id, int slice_idx);
/* Set the ID of a slice in UL */
void flexran_set_ul_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id);
/* Get the RB share a slice in UL, value 0-100 */
int flexran_get_ul_slice_percentage(mid_t mod_id, int slice_idx);
/* Set the RB share a slice in UL, value 0-100 */
void flexran_set_ul_slice_percentage(mid_t mod_id, int slice_idx, int percentage);
/* TODO Whether a slice in UL is isolated */
/*int flexran_get_ul_slice_isolation(mid_t mod_id, int slice_idx);*/
/* TODO Set whether a slice in UL is isolated */
/*void flexran_set_ul_slice_isolation(mid_t mod_id, int slice_idx, int is_isolated);*/
/* TODO Get the priority of a slice in UL */
/*int flexran_get_ul_slice_priority(mid_t mod_id, int slice_idx);*/
/* TODO Set the priority of a slice in UL */
/*void flexran_set_ul_slice_priority(mid_t mod_id, int slice_idx, int priority);*/
/* Get the first RB for allocation in a slice in UL */
int flexran_get_ul_slice_first_rb(mid_t mod_id, int slice_idx);
/* Set the first RB for allocation in a slice in UL */
void flexran_set_ul_slice_first_rb(mid_t mod_id, int slice_idx, int first_rb);
/* TODO Get the number of RB for the allocation in a slice in UL */
/*int flexran_get_ul_slice_length_rb(mid_t mod_id, int slice_idx);*/
/* TODO Set the of number of RB for the allocation in a slice in UL */
/*void flexran_set_ul_slice_length_rb(mid_t mod_id, int slice_idx, int poshigh);*/
/* Get the maximum MCS for slice in UL */
int flexran_get_ul_slice_maxmcs(mid_t mod_id, int slice_idx);
/* Set the maximum MCS for slice in UL */
void flexran_set_ul_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs);
/* TODO Get the sorting order of a slice in UL, return value is number of elements
* in sorting_list */
/*int flexran_get_ul_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexUlSorting **sorting_list);*/
/* TODO Set the sorting order of a slice in UL */
/*void flexran_set_ul_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexUlSorting *sorting_list, int n);*/
/* TODO Get the accounting policy for a slice in UL */
/*Protocol__UlAccountingPolicy flexran_get_ul_slice_accounting_policy(mid_t mod_id, int slice_idx);*/
/* TODO Set the accounting policy for a slice in UL */
/*void flexran_get_ul_slice_accounting_policy(mid_t mod_id, int slice_idx, Protocol__UlAccountingPolicy accountin);*/
/* Get the scheduler name for a slice in UL */
char *flexran_get_ul_slice_scheduler(mid_t mod_id, int slice_idx);
/* Set the scheduler name for a slice in UL */
int flexran_set_ul_slice_scheduler(mid_t mod_id, int slice_idx, char *name);
/* Get the name of/Set the UL scheduler algorithm. Same applies as for the DL
* case */
char *flexran_get_ul_scheduler_name(mid_t mod_id);
int flexran_set_ul_scheduler(mid_t mod_id, char *sched);
/************************** S1AP **************************/
/* Get the number of MMEs to be connected */
@@ -832,6 +742,15 @@ int flexran_get_s1ap_mme_conf(mid_t mod_id, mid_t mme_index, Protocol__FlexS1apM
/* Get the S1AP UE conf */
int flexran_get_s1ap_ue(mid_t mod_id, rnti_t rnti, Protocol__FlexS1apUe * ue_conf);
/* Add MMEs and re-issue S1AP Registration Request */
int flexran_add_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4);
/* Remove MMEs and and cut SCTP to MME */
int flexran_remove_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4);
/* Set a new PLMN configuration */
int flexran_set_new_plmn_id(mid_t mod_id, int CC_id, size_t n_plmn, Protocol__FlexPlmn **plmn_id);
/********************* general information *****************/
/* get an ID for this BS (or part of a BS) */
uint64_t flexran_get_bs_id(mid_t mod_id);
+1 -10
View File
@@ -38,10 +38,7 @@
/* cell configuration section name */
#define GNB_CONFIG_STRING_GNB_LIST "gNBs"
#define GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET "ssb_SubcarrierOffset"
#define GNB_CONFIG_STRING_PDSCHANTENNAPORTS "pdsch_AntennaPorts"
#define GNB_CONFIG_STRING_PUSCHTARGETPOWX10 "pusch_TargetSNRx10"
#define GNB_CONFIG_STRING_PUCCHTARGETPOWX10 "pucch_TargetSNRx10"
#define GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON "servingCellConfigCommon"
#define GNB_CONFIG_STRING_PHYSCELLID "physCellId"
#define GNB_CONFIG_STRING_NTIMINGADVANCEOFFSET "n_TimingAdvanceOffset"
@@ -225,12 +222,6 @@
#define GNB_CONFIG_DLCARRIERBANDWIDTH_IDX 10
#define SSBPARAMS_DESC {{GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET,NULL,0,iptr:&ssb_SubcarrierOffset,defintval:0,TYPE_INT,0}}
#define PDSCHANTENNAPARAMS_DESC {{GNB_CONFIG_STRING_PDSCHANTENNAPORTS,NULL,0,iptr:&pdsch_AntennaPorts,defintval:1,TYPE_INT,0}}
#define TARGETPOWER_DESC { \
{GNB_CONFIG_STRING_PUSCHTARGETPOWX10,NULL,0,iptr:&pusch_TargetSNRx10,defintval:200,TYPE_INT,0},\
{GNB_CONFIG_STRING_PUCCHTARGETPOWX10,NULL,0,iptr:&pucch_TargetSNRx10,defintval:200,TYPE_INT,0}}
#define SCCPARAMS_DESC(scc) { \
{GNB_CONFIG_STRING_PHYSCELLID,NULL,0,i64ptr:scc->physCellId,defint64val:0,TYPE_INT64,0/*0*/}, \
{GNB_CONFIG_STRING_NTIMINGADVANCEOFFSET,NULL,0,i64ptr:scc->n_TimingAdvanceOffset,defint64val:NR_ServingCellConfigCommon__n_TimingAdvanceOffset_n0,TYPE_INT64,0/*1*/},\
+10 -35
View File
@@ -520,21 +520,11 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0};
NR_ServingCellConfigCommon_t *scc = calloc(1,sizeof(NR_ServingCellConfigCommon_t));
int ssb_SubcarrierOffset = 31;
int pdsch_AntennaPorts = 1;
int pusch_TargetSNRx10 = 200;
int pucch_TargetSNRx10 = 200;
uint64_t ssb_bitmap=0xff;
memset((void*)scc,0,sizeof(NR_ServingCellConfigCommon_t));
prepare_scc(scc);
paramdef_t SCCsParams[] = SCCPARAMS_DESC(scc);
paramlist_def_t SCCsParamList = {GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON, NULL, 0};
paramdef_t SSBsParams[] = SSBPARAMS_DESC;
paramlist_def_t SSBsParamList = {GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET, NULL, 0};
paramdef_t PDSCHANTENNAParams[] = PDSCHANTENNAPARAMS_DESC;
paramlist_def_t PDSCHANTENNAParamList = {GNB_CONFIG_STRING_PDSCHANTENNAPORTS, NULL, 0};
paramdef_t PUSCHTARGETPOWParams[] = TARGETPOWER_DESC;
paramlist_def_t PUSCHTARGETPOWParamList = {GNB_CONFIG_STRING_PDSCHANTENNAPORTS, NULL, 0};
////////// Physical parameters
@@ -583,14 +573,6 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
}
sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0);
config_getlist(&SSBsParamList, NULL, 0, aprefix);
if (SSBsParamList.numelt > 0) config_get(SSBsParams,sizeof(SSBsParams)/sizeof(paramdef_t),aprefix);
config_getlist(&PDSCHANTENNAParamList, NULL, 0, aprefix);
if (PDSCHANTENNAParamList.numelt > 0) config_get(PDSCHANTENNAParams,sizeof(PDSCHANTENNAParams)/sizeof(paramdef_t),aprefix);
config_getlist(&PUSCHTARGETPOWParamList, NULL, 0, aprefix);
if (PUSCHTARGETPOWParamList.numelt > 0) config_get(PUSCHTARGETPOWParams,sizeof(PUSCHTARGETPOWParams)/sizeof(paramdef_t),aprefix);
config_getlist(&SCCsParamList, NULL, 0, aprefix);
if (SCCsParamList.numelt > 0) {
@@ -666,19 +648,16 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
(NRRRC_CONFIGURATION_REQ (msg_p).mnc_digit_length[l] == 3),"BAD MNC DIGIT LENGTH %d",
NRRRC_CONFIGURATION_REQ (msg_p).mnc_digit_length[l]);
}
// Parse optional physical parameters
sprintf(gnbpath,"%s.[%i]",GNB_CONFIG_STRING_GNB_LIST,k),
printf("SSB SCO %d\n",*GNBParamList.paramarray[i][GNB_SSB_SUBCARRIEROFFSET_IDX].iptr);
NRRRC_CONFIGURATION_REQ (msg_p).ssb_SubcarrierOffset = *GNBParamList.paramarray[i][GNB_SSB_SUBCARRIEROFFSET_IDX].iptr;
printf("pdsch_AntennaPorts %d\n",*GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_IDX].iptr);
NRRRC_CONFIGURATION_REQ (msg_p).pdsch_AntennaPorts = *GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_IDX].iptr;
printf("pusch_TargetSNRx10 %d\n",*GNBParamList.paramarray[i][GNB_PUSCH_TARGETPOW_X10_IDX].iptr);
NRRRC_CONFIGURATION_REQ (msg_p).pusch_TargetSNRx10 = *GNBParamList.paramarray[i][GNB_PUSCH_TARGETPOW_X10_IDX].iptr;
printf("pucch_TargetSNRx10 %d\n",*GNBParamList.paramarray[i][GNB_PUCCH_TARGETPOW_X10_IDX].iptr);
NRRRC_CONFIGURATION_REQ (msg_p).pucch_TargetSNRx10 = *GNBParamList.paramarray[i][GNB_PUCCH_TARGETPOW_X10_IDX].iptr;
NRRRC_CONFIGURATION_REQ (msg_p).scc = scc;
printf("SSB SCO %d\n",ssb_SubcarrierOffset);
NRRRC_CONFIGURATION_REQ (msg_p).ssb_SubcarrierOffset = ssb_SubcarrierOffset;
printf("pdsch_AntennaPorts %d\n",pdsch_AntennaPorts);
NRRRC_CONFIGURATION_REQ (msg_p).pdsch_AntennaPorts = pdsch_AntennaPorts;
printf("pusch_TargetSNRx10 %d\n",pusch_TargetSNRx10);
NRRRC_CONFIGURATION_REQ (msg_p).pusch_TargetSNRx10 = pusch_TargetSNRx10;
printf("pucch_TargetSNRx10 %d\n",pucch_TargetSNRx10);
NRRRC_CONFIGURATION_REQ (msg_p).pucch_TargetSNRx10 = pucch_TargetSNRx10;
NRRRC_CONFIGURATION_REQ (msg_p).scc = scc;
}//
}//End for (k=0; k <num_gnbs ; k++)
@@ -787,11 +766,7 @@ int RCconfig_NR_S1(MessageDef *msg_p, uint32_t i) {
if (GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt>0) {
// Output a list of all gNBs.
config_getlist( &GNBParamList,GNBParams,sizeof(GNBParams)/sizeof(paramdef_t),NULL);
if (GNBParamList.numelt > 0) {
for (k = 0; k < GNBParamList.numelt; k++) {
if (GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr == NULL) {
+14
View File
@@ -113,6 +113,11 @@ typedef enum {
#define GNB_CONFIG_STRING_REMOTE_S_PORTC "remote_s_portc"
#define GNB_CONFIG_STRING_LOCAL_S_PORTD "local_s_portd"
#define GNB_CONFIG_STRING_REMOTE_S_PORTD "remote_s_portd"
#define GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET "ssb_SubcarrierOffset"
#define GNB_CONFIG_STRING_PDSCHANTENNAPORTS "pdsch_AntennaPorts"
#define GNB_CONFIG_STRING_PUSCHTARGETPOWX10 "pusch_TargetSNRx10"
#define GNB_CONFIG_STRING_PUCCHTARGETPOWX10 "pucch_TargetSNRx10"
typedef struct ccparams_nr_x2 {
char *frame_type;
@@ -156,7 +161,12 @@ typedef struct ccparams_nr_x2 {
{GNB_CONFIG_STRING_REMOTE_S_PORTC, NULL, 0, uptr:NULL, defuintval:50000, TYPE_UINT, 0}, \
{GNB_CONFIG_STRING_LOCAL_S_PORTD, NULL, 0, uptr:NULL, defuintval:50001, TYPE_UINT, 0}, \
{GNB_CONFIG_STRING_REMOTE_S_PORTD, NULL, 0, uptr:NULL, defuintval:50001, TYPE_UINT, 0}, \
{GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET, NULL, 0, iptr:NULL, defintval:31, TYPE_INT, 0}, \
{GNB_CONFIG_STRING_PDSCHANTENNAPORTS, NULL, 0, iptr:NULL, defintval:1, TYPE_INT, 0}, \
{GNB_CONFIG_STRING_PUSCHTARGETPOWX10, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \
{GNB_CONFIG_STRING_PUCCHTARGETPOWX10, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \
}
#define GNB_GNB_ID_IDX 0
#define GNB_CELL_TYPE_IDX 1
#define GNB_GNB_NAME_IDX 2
@@ -171,6 +181,10 @@ typedef struct ccparams_nr_x2 {
#define GNB_REMOTE_S_PORTC_IDX 11
#define GNB_LOCAL_S_PORTD_IDX 12
#define GNB_REMOTE_S_PORTD_IDX 13
#define GNB_SSB_SUBCARRIEROFFSET_IDX 14
#define GNB_PDSCH_ANTENNAPORTS_IDX 15
#define GNB_PUSCH_TARGETPOW_X10_IDX 16
#define GNB_PUCCH_TARGETPOW_X10_IDX 17
#define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD}
#define GNBPARAMS_CHECK { \
+18 -1
View File
@@ -547,7 +547,7 @@ copy_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) {
ul_req_tmp->ul_config_request_body.number_of_pdus = 0;
if (ul_req->ul_config_request_body.number_of_pdus>0) {
LOG_D(PHY, "%s() active NOW (frameP:%d subframeP:%d) pdus:%d\n", __FUNCTION__, frameP, subframeP, ul_req->ul_config_request_body.number_of_pdus);
LOG_D(MAC, "%s() active NOW (frameP:%d subframeP:%d) pdus:%d\n", __FUNCTION__, frameP, subframeP, ul_req->ul_config_request_body.number_of_pdus);
}
memcpy((void *)ul_req->ul_config_request_body.ul_config_pdu_list,
@@ -556,6 +556,11 @@ copy_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) {
}
}
extern int16_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type);
extern int16_t find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type);
extern void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch);
extern void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch);
void
eNB_dlsch_ulsch_scheduler(module_id_t module_idP,
frame_t frameP,
@@ -843,6 +848,7 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP,
}
/* Note: This should not be done in the MAC! */
/*
for (int ii=0; ii<MAX_MOBILES_PER_ENB; ii++) {
LTE_eNB_ULSCH_t *ulsch = RC.eNB[module_idP][CC_id]->ulsch[ii];
@@ -862,6 +868,17 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP,
clean_eNb_dlsch(dlsch);
}
}
*/
int id;
// clean ULSCH entries for rnti
id = find_ulsch(rnti,RC.eNB[module_idP][CC_id],SEARCH_EXIST);
if (id>=0) clean_eNb_ulsch(RC.eNB[module_idP][CC_id]->ulsch[id]);
// clean DLSCH entries for rnti
id = find_dlsch(rnti,RC.eNB[module_idP][CC_id],SEARCH_EXIST);
if (id>=0) clean_eNb_dlsch(RC.eNB[module_idP][CC_id]->dlsch[id][0]);
for (int j = 0; j < 10; j++) {
nfapi_ul_config_request_body_t *ul_req_tmp = NULL;
+16 -12
View File
@@ -573,10 +573,7 @@ schedule_ue_spec(module_id_t module_idP,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,
VCD_FUNCTION_IN);
start_meas(&eNB->schedule_dlsch_preprocessor);
dlsch_scheduler_pre_processor(module_idP,
CC_id,
frameP,
subframeP);
eNB->pre_processor_dl.dl(module_idP, CC_id, frameP, subframeP);
stop_meas(&eNB->schedule_dlsch_preprocessor);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,
VCD_FUNCTION_OUT);
@@ -588,6 +585,7 @@ schedule_ue_spec(module_id_t module_idP,
UE_sched_ctrl_t *ue_sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
UE_TEMPLATE *ue_template = &UE_info->UE_template[CC_id][UE_id];
eNB_UE_STATS *eNB_UE_stats = &UE_info->eNB_UE_stats[CC_id][UE_id];
eNB_UE_stats->TBS = 0;
const rnti_t rnti = ue_template->rnti;
// If TDD
@@ -679,15 +677,15 @@ schedule_ue_spec(module_id_t module_idP,
const uint32_t rbc = allocate_prbs_sub(
nb_rb, N_RB_DL, N_RBG, ue_sched_ctrl->rballoc_sub_UE[CC_id]);
if (nb_rb > ue_sched_ctrl->pre_nb_available_rbs[CC_id]) {
LOG_D(MAC,
"[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n",
if (nb_rb > ue_sched_ctrl->pre_nb_available_rbs[CC_id])
LOG_W(MAC,
"[eNB %d] %d.%d CC_id %d : should not schedule UE %d, its "
"retransmission takes more resources than we have\n",
module_idP,
frameP,
subframeP,
CC_id,
UE_id);
continue;
}
/* CDRX */
ue_sched_ctrl->harq_rtt_timer[CC_id][harq_pid] = 1; // restart HARQ RTT timer
@@ -799,6 +797,7 @@ schedule_ue_spec(module_id_t module_idP,
eNB_UE_stats->rbs_used_retx = nb_rb;
eNB_UE_stats->total_rbs_used_retx += nb_rb;
eNB_UE_stats->dlsch_mcs2 = eNB_UE_stats->dlsch_mcs1;
eNB_UE_stats->TBS = TBS;
} else {
// Now check RLC information to compute number of required RBs
// get maximum TBS size for RLC request
@@ -842,13 +841,18 @@ schedule_ue_spec(module_id_t module_idP,
if (ue_sched_ctrl->dl_lc_bytes[i] == 0) // no data in this LC!
continue;
LOG_D(MAC, "[eNB %d] SFN/SF %d.%d, LC%d->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
const uint32_t data =
min(ue_sched_ctrl->dl_lc_bytes[i],
TBS - ta_len - header_length_total - sdu_length_total - 3);
LOG_D(MAC,
"[eNB %d] SFN/SF %d.%d, LC%d->DLSCH CC_id %d, Requesting %d "
"bytes from RLC (RRC message)\n",
module_idP,
frameP,
subframeP,
lcid,
CC_id,
TBS - ta_len - header_length_total - sdu_length_total - 3);
data);
sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
rnti,
@@ -857,7 +861,7 @@ schedule_ue_spec(module_id_t module_idP,
ENB_FLAG_YES,
MBMS_FLAG_NO,
lcid,
TBS - ta_len - header_length_total - sdu_length_total - 3,
data,
(char *)&dlsch_buffer[sdu_length_total],
0,
0
+1 -1
View File
@@ -2240,7 +2240,7 @@ void ulsch_scheduler_pre_ue_select_fairRR(
uint8_t first_ue_total[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_id[MAX_NUM_CCs][20]={0};
uint8_t ul_inactivity_id[MAX_NUM_CCs][20]={{0}};
// LTE_DL_FRAME_PARMS *frame_parms;
uint8_t ulsch_ue_max_num[MAX_NUM_CCs];
uint16_t saved_ulsch_dci[MAX_NUM_CCs];
+35 -20
View File
@@ -2131,33 +2131,36 @@ dump_ue_list(UE_list_t *listP) {
* Add a UE to UE_list listP
*/
inline void add_ue_list(UE_list_t *listP, int UE_id) {
if (listP->head == -1) {
listP->head = UE_id;
listP->next[UE_id] = -1;
} else {
int i = listP->head;
while (listP->next[i] >= 0)
i = listP->next[i];
listP->next[i] = UE_id;
listP->next[UE_id] = -1;
}
int *cur = &listP->head;
while (*cur >= 0)
cur = &listP->next[*cur];
*cur = UE_id;
}
//------------------------------------------------------------------------------
/*
* Remove a UE from the UE_list listP, return the previous element
* Remove a UE from the UE_list listP
*/
inline int remove_ue_list(UE_list_t *listP, int UE_id) {
listP->next[UE_id] = -1;
if (listP->head == UE_id) {
listP->head = listP->next[UE_id];
return -1;
}
int *cur = &listP->head;
while (*cur != -1 && *cur != UE_id)
cur = &listP->next[*cur];
if (*cur == -1)
return 0;
int *next = &listP->next[*cur];
*cur = listP->next[*cur];
*next = -1;
return 1;
}
int previous = prev(listP, UE_id);
if (previous != -1)
listP->next[previous] = listP->next[UE_id];
return previous;
//------------------------------------------------------------------------------
/*
* Initialize the UE_list listP
*/
inline void init_ue_list(UE_list_t *listP) {
listP->head = -1;
for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i)
listP->next[i] = -1;
}
//------------------------------------------------------------------------------
@@ -2196,6 +2199,12 @@ add_new_ue(module_id_t mod_idP,
UE_info->active[UE_id] = TRUE;
add_ue_list(&UE_info->list, UE_id);
dump_ue_list(&UE_info->list);
pp_impl_param_t* dl = &RC.mac[mod_idP]->pre_processor_dl;
if (dl->slices) // inform slice implementation about new UE
dl->add_UE(dl->slices, UE_id);
pp_impl_param_t* ul = &RC.mac[mod_idP]->pre_processor_ul;
if (ul->slices) // inform slice implementation about new UE
ul->add_UE(ul->slices, UE_id);
if (IS_SOFTMODEM_IQPLAYER)// not specific to record/playback ?
UE_info->UE_template[cc_idP][UE_id].pre_assigned_mcs_ul = 0;
UE_info->UE_template[cc_idP][UE_id].rach_resource_type = rach_resource_type;
@@ -2259,6 +2268,12 @@ rrc_mac_remove_ue(module_id_t mod_idP,
UE_info->num_UEs--;
remove_ue_list(&UE_info->list, UE_id);
pp_impl_param_t* dl = &RC.mac[mod_idP]->pre_processor_dl;
if (dl->slices) // inform slice implementation about new UE
dl->remove_UE(dl->slices, UE_id);
pp_impl_param_t* ul = &RC.mac[mod_idP]->pre_processor_ul;
if (ul->slices) // inform slice implementation about new UE
ul->remove_UE(ul->slices, UE_id);
/* Clear all remaining pending transmissions */
memset(&UE_info->UE_template[pCC_id][UE_id], 0, sizeof(UE_TEMPLATE));

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