amarisoft_enb: add NR support
this patch adds the ability to configure NR cells with Amarisoft eNB. It adds the new DRB-NR template and updates the normal enb.cfg template to allow using it as LTE only or with NR cells (5G NSA). Change-Id: Ia27bbc6db5920ce14bacabe8043601aa2adaa5fe
This commit is contained in:
parent
9b419f32ae
commit
6e081aa1dc
|
@ -12,6 +12,7 @@ enb:
|
||||||
mnc: 70
|
mnc: 70
|
||||||
transmission_mode: 1
|
transmission_mode: 1
|
||||||
num_cells: 1
|
num_cells: 1
|
||||||
|
num_nr_cells: 0
|
||||||
enable_measurements: false
|
enable_measurements: false
|
||||||
a1_report_type: rsrp
|
a1_report_type: rsrp
|
||||||
a1_report_value: -105
|
a1_report_value: -105
|
||||||
|
|
|
@ -68,12 +68,18 @@ def on_register_schemas():
|
||||||
'cell_list[].ncell_list[].pci': schema.UINT,
|
'cell_list[].ncell_list[].pci': schema.UINT,
|
||||||
'cell_list[].ncell_list[].dl_earfcn': schema.UINT,
|
'cell_list[].ncell_list[].dl_earfcn': schema.UINT,
|
||||||
'cell_list[].scell_list[]': schema.UINT,
|
'cell_list[].scell_list[]': schema.UINT,
|
||||||
|
'cell_list[].nr_scell_list[]': schema.UINT,
|
||||||
'cell_list[].dl_earfcn': schema.UINT,
|
'cell_list[].dl_earfcn': schema.UINT,
|
||||||
'cell_list[].root_seq_idx': schema.UINT,
|
'cell_list[].root_seq_idx': schema.UINT,
|
||||||
'cell_list[].tac': schema.UINT,
|
'cell_list[].tac': schema.UINT,
|
||||||
'cell_list[].dl_rfemu.type': schema.STR,
|
'cell_list[].dl_rfemu.type': schema.STR,
|
||||||
'cell_list[].dl_rfemu.addr': schema.IPV4,
|
'cell_list[].dl_rfemu.addr': schema.IPV4,
|
||||||
'cell_list[].dl_rfemu.ports[]': schema.UINT,
|
'cell_list[].dl_rfemu.ports[]': schema.UINT,
|
||||||
|
'num_nr_cells': schema.UINT,
|
||||||
|
'nr_cell_list[].rf_port': schema.UINT,
|
||||||
|
'nr_cell_list[].cell_id': schema.UINT,
|
||||||
|
'nr_cell_list[].band': schema.UINT,
|
||||||
|
'nr_cell_list[].dl_nr_arfcn': schema.UINT,
|
||||||
}
|
}
|
||||||
for key, val in run_node.RunNode.schema().items():
|
for key, val in run_node.RunNode.schema().items():
|
||||||
resource_schema['run_node.%s' % key] = val
|
resource_schema['run_node.%s' % key] = val
|
||||||
|
@ -98,9 +104,11 @@ class eNodeB(log.Origin, metaclass=ABCMeta):
|
||||||
self.set_name('%s_%s' % (name, self._run_node.run_addr()))
|
self.set_name('%s_%s' % (name, self._run_node.run_addr()))
|
||||||
self._txmode = 0
|
self._txmode = 0
|
||||||
self._id = None
|
self._id = None
|
||||||
|
self._ran_config = "lte" # Used to determine whether we are in NSA
|
||||||
self._duplex = None
|
self._duplex = None
|
||||||
self._num_prb = 0
|
self._num_prb = 0
|
||||||
self._num_cells = None
|
self._num_cells = None
|
||||||
|
self._num_nr_cells = None
|
||||||
self._epc = None
|
self._epc = None
|
||||||
self.gen_conf = None
|
self.gen_conf = None
|
||||||
self.gr_broker = GrBroker.ref()
|
self.gr_broker = GrBroker.ref()
|
||||||
|
@ -126,10 +134,11 @@ class eNodeB(log.Origin, metaclass=ABCMeta):
|
||||||
|
|
||||||
def calc_required_zmq_ports(self, cfg_values):
|
def calc_required_zmq_ports(self, cfg_values):
|
||||||
cell_list = cfg_values['enb']['cell_list']
|
cell_list = cfg_values['enb']['cell_list']
|
||||||
return len(cell_list) * self.num_ports() # *2 if MIMO
|
nr_cell_list = cfg_values['enb']['nr_cell_list']
|
||||||
|
return len(cell_list) * self.num_ports() + len(nr_cell_list) # *2 if LTE MIMO
|
||||||
|
|
||||||
def calc_required_zmq_ports_joined_earfcn(self, cfg_values):
|
def calc_required_zmq_ports_joined_earfcn(self, cfg_values):
|
||||||
#gr_broker will join the earfcns, so we need to count uniqe earfcns:
|
#gr_broker will join the earfcns, so we need to count unique earfcns (only implemented for LTE):
|
||||||
cell_list = cfg_values['enb']['cell_list']
|
cell_list = cfg_values['enb']['cell_list']
|
||||||
earfcn_li = []
|
earfcn_li = []
|
||||||
[earfcn_li.append(int(cell['dl_earfcn'])) for cell in cell_list if int(cell['dl_earfcn']) not in earfcn_li]
|
[earfcn_li.append(int(cell['dl_earfcn'])) for cell in cell_list if int(cell['dl_earfcn']) not in earfcn_li]
|
||||||
|
@ -142,6 +151,10 @@ class eNodeB(log.Origin, metaclass=ABCMeta):
|
||||||
for cell in cell_list:
|
for cell in cell_list:
|
||||||
cell[port_name] = base_port + port_offset
|
cell[port_name] = base_port + port_offset
|
||||||
port_offset += self.num_ports()
|
port_offset += self.num_ports()
|
||||||
|
nr_cell_list = cfg_values['enb']['nr_cell_list']
|
||||||
|
for nr_cell in nr_cell_list:
|
||||||
|
nr_cell[port_name] = base_port + port_offset
|
||||||
|
port_offset += 1
|
||||||
# TODO: do we need to assign cell_list back?
|
# TODO: do we need to assign cell_list back?
|
||||||
|
|
||||||
def assign_enb_zmq_ports_joined_earfcn(self, cfg_values, port_name, base_port):
|
def assign_enb_zmq_ports_joined_earfcn(self, cfg_values, port_name, base_port):
|
||||||
|
@ -176,7 +189,9 @@ class eNodeB(log.Origin, metaclass=ABCMeta):
|
||||||
config.overlay(values, dict(enb={ 'mme_addr': self._epc.addr() }))
|
config.overlay(values, dict(enb={ 'mme_addr': self._epc.addr() }))
|
||||||
config.overlay(values, dict(enb={ 'gtp_bind_addr': self._gtp_bind_addr }))
|
config.overlay(values, dict(enb={ 'gtp_bind_addr': self._gtp_bind_addr }))
|
||||||
self._num_cells = int(values['enb'].get('num_cells', None))
|
self._num_cells = int(values['enb'].get('num_cells', None))
|
||||||
assert self._num_cells
|
self._num_nr_cells = int(values['enb'].get('num_nr_cells', None))
|
||||||
|
assert self._num_cells is not None
|
||||||
|
assert self._num_nr_cells is not None
|
||||||
|
|
||||||
# adjust cell_list to num_cells length:
|
# adjust cell_list to num_cells length:
|
||||||
len_cell_list = len(values['enb']['cell_list'])
|
len_cell_list = len(values['enb']['cell_list'])
|
||||||
|
@ -231,6 +246,9 @@ class eNodeB(log.Origin, metaclass=ABCMeta):
|
||||||
def num_cells(self):
|
def num_cells(self):
|
||||||
return self._num_cells
|
return self._num_cells
|
||||||
|
|
||||||
|
def num_nr_cells(self):
|
||||||
|
return self._num_nr_cells
|
||||||
|
|
||||||
########################
|
########################
|
||||||
# PUBLIC - INTERNAL API
|
# PUBLIC - INTERNAL API
|
||||||
########################
|
########################
|
||||||
|
@ -280,6 +298,13 @@ class eNodeB(log.Origin, metaclass=ABCMeta):
|
||||||
rf_dev_args += ',rx_port%u=tcp://%s:%u' %(idx + 1, ul_rem_addr, cell['zmq_enb_peer_port'] + 1)
|
rf_dev_args += ',rx_port%u=tcp://%s:%u' %(idx + 1, ul_rem_addr, cell['zmq_enb_peer_port'] + 1)
|
||||||
idx += self.num_ports()
|
idx += self.num_ports()
|
||||||
|
|
||||||
|
# Only single antenna supported for NR cells
|
||||||
|
nr_cell_list = cfg_values['enb']['nr_cell_list']
|
||||||
|
for nr_cell in nr_cell_list:
|
||||||
|
rf_dev_args += ',tx_port%u=tcp://%s:%u' % (idx, self.addr(), nr_cell['zmq_enb_bind_port'] + 0)
|
||||||
|
rf_dev_args += ',rx_port%u=tcp://%s:%u' % (idx, ul_rem_addr, nr_cell['zmq_enb_peer_port'] + 0)
|
||||||
|
idx += 1
|
||||||
|
|
||||||
rf_dev_args += ',id=enb,base_srate=' + str(base_srate)
|
rf_dev_args += ',id=enb,base_srate=' + str(base_srate)
|
||||||
return rf_dev_args
|
return rf_dev_args
|
||||||
|
|
||||||
|
@ -300,6 +325,14 @@ class eNodeB(log.Origin, metaclass=ABCMeta):
|
||||||
if self.num_ports() > 1:
|
if self.num_ports() > 1:
|
||||||
rf_dev_args += ',rx_port%u=tcp://%s:%u' %(idx + 1, self.addr(), cell['zmq_ue_peer_port'] + 1)
|
rf_dev_args += ',rx_port%u=tcp://%s:%u' %(idx + 1, self.addr(), cell['zmq_ue_peer_port'] + 1)
|
||||||
idx += self.num_ports()
|
idx += self.num_ports()
|
||||||
|
|
||||||
|
# NR cells again only with single antenna support
|
||||||
|
nr_cell_list = self.gen_conf['enb']['nr_cell_list']
|
||||||
|
for nr_cell in nr_cell_list:
|
||||||
|
rf_dev_args += ',tx_port%u=tcp://%s:%u' %(idx, ue.addr(), nr_cell['zmq_ue_bind_port'] + 0)
|
||||||
|
rf_dev_args += ',rx_port%u=tcp://%s:%u' %(idx, self.addr(), nr_cell['zmq_ue_peer_port'] + 0)
|
||||||
|
idx += 1
|
||||||
|
|
||||||
# remove trailing comma:
|
# remove trailing comma:
|
||||||
if rf_dev_args[0] == ',':
|
if rf_dev_args[0] == ',':
|
||||||
return rf_dev_args[1:]
|
return rf_dev_args[1:]
|
||||||
|
|
|
@ -22,6 +22,7 @@ import pprint
|
||||||
|
|
||||||
from ..core import log, util, config, template, process, remote
|
from ..core import log, util, config, template, process, remote
|
||||||
from ..core import schema
|
from ..core import schema
|
||||||
|
from ..core.event_loop import MainLoop
|
||||||
from . import enb
|
from . import enb
|
||||||
from . import rfemu
|
from . import rfemu
|
||||||
|
|
||||||
|
@ -33,12 +34,16 @@ def on_register_schemas():
|
||||||
|
|
||||||
config_schema = {
|
config_schema = {
|
||||||
'log_options': schema.STR,
|
'log_options': schema.STR,
|
||||||
|
'nr_bandwidth': schema.INT,
|
||||||
}
|
}
|
||||||
schema.register_config_schema('amarisoftenb', config_schema)
|
schema.register_config_schema('amarisoftenb', config_schema)
|
||||||
|
|
||||||
def rf_type_valid(rf_type_str):
|
def rf_type_valid(rf_type_str):
|
||||||
return rf_type_str in ('uhd', 'zmq', 'sdr')
|
return rf_type_str in ('uhd', 'zmq', 'sdr')
|
||||||
|
|
||||||
|
def ran_type_valid(ran_type_str):
|
||||||
|
return ran_type_str in ('lte', '5g_nsa')
|
||||||
|
|
||||||
class AmarisoftENB(enb.eNodeB):
|
class AmarisoftENB(enb.eNodeB):
|
||||||
|
|
||||||
REMOTE_DIR = '/osmo-gsm-tester-amarisoftenb'
|
REMOTE_DIR = '/osmo-gsm-tester-amarisoftenb'
|
||||||
|
@ -48,6 +53,7 @@ class AmarisoftENB(enb.eNodeB):
|
||||||
CFGFILE_SIB23 = 'amarisoft_sib23.asn'
|
CFGFILE_SIB23 = 'amarisoft_sib23.asn'
|
||||||
CFGFILE_RF = 'amarisoft_rf_driver.cfg'
|
CFGFILE_RF = 'amarisoft_rf_driver.cfg'
|
||||||
CFGFILE_DRB = 'amarisoft_drb.cfg'
|
CFGFILE_DRB = 'amarisoft_drb.cfg'
|
||||||
|
CFGFILE_DRB_NR = 'amarisoft_drb_nr.cfg'
|
||||||
LOGFILE = 'lteenb.log'
|
LOGFILE = 'lteenb.log'
|
||||||
PHY_SIGNAL_FILE = 'lteenb.log.bin'
|
PHY_SIGNAL_FILE = 'lteenb.log.bin'
|
||||||
|
|
||||||
|
@ -63,6 +69,7 @@ class AmarisoftENB(enb.eNodeB):
|
||||||
self.config_sib23_file = None
|
self.config_sib23_file = None
|
||||||
self.config_rf_file = None
|
self.config_rf_file = None
|
||||||
self.config_drb_file = None
|
self.config_drb_file = None
|
||||||
|
self.config_drb_nr_file = None
|
||||||
self.log_file = None
|
self.log_file = None
|
||||||
self.process = None
|
self.process = None
|
||||||
self.rem_host = None
|
self.rem_host = None
|
||||||
|
@ -72,8 +79,11 @@ class AmarisoftENB(enb.eNodeB):
|
||||||
self.remote_config_sib23_file = None
|
self.remote_config_sib23_file = None
|
||||||
self.remote_config_rf_file = None
|
self.remote_config_rf_file = None
|
||||||
self.remote_config_drb_file = None
|
self.remote_config_drb_file = None
|
||||||
|
self.remote_config_drb_nr_file = None
|
||||||
self.remote_log_file = None
|
self.remote_log_file = None
|
||||||
self.enable_measurements = False
|
self.enable_measurements = False
|
||||||
|
self.nr_bandwidth = None
|
||||||
|
self.ran_type = None
|
||||||
self.testenv = testenv
|
self.testenv = testenv
|
||||||
if not rf_type_valid(conf.get('rf_dev_type', None)):
|
if not rf_type_valid(conf.get('rf_dev_type', None)):
|
||||||
raise log.Error('Invalid rf_dev_type=%s' % conf.get('rf_dev_type', None))
|
raise log.Error('Invalid rf_dev_type=%s' % conf.get('rf_dev_type', None))
|
||||||
|
@ -131,8 +141,8 @@ class AmarisoftENB(enb.eNodeB):
|
||||||
self.process.launch()
|
self.process.launch()
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
# Not implemented
|
# Allow for some time to flush logs
|
||||||
pass
|
MainLoop.sleep(5)
|
||||||
|
|
||||||
def gen_conf_file(self, path, filename, values):
|
def gen_conf_file(self, path, filename, values):
|
||||||
self.dbg('AmarisoftENB ' + filename + ':\n' + pprint.pformat(values))
|
self.dbg('AmarisoftENB ' + filename + ':\n' + pprint.pformat(values))
|
||||||
|
@ -151,6 +161,7 @@ class AmarisoftENB(enb.eNodeB):
|
||||||
self.config_sib23_file = self.run_dir.child(AmarisoftENB.CFGFILE_SIB23)
|
self.config_sib23_file = self.run_dir.child(AmarisoftENB.CFGFILE_SIB23)
|
||||||
self.config_rf_file = self.run_dir.child(AmarisoftENB.CFGFILE_RF)
|
self.config_rf_file = self.run_dir.child(AmarisoftENB.CFGFILE_RF)
|
||||||
self.config_drb_file = self.run_dir.child(AmarisoftENB.CFGFILE_DRB)
|
self.config_drb_file = self.run_dir.child(AmarisoftENB.CFGFILE_DRB)
|
||||||
|
self.config_drb_nr_file = self.run_dir.child(AmarisoftENB.CFGFILE_DRB_NR)
|
||||||
self.log_file = self.run_dir.child(AmarisoftENB.LOGFILE)
|
self.log_file = self.run_dir.child(AmarisoftENB.LOGFILE)
|
||||||
self.phy_signal_file = self.run_dir.child(AmarisoftENB.PHY_SIGNAL_FILE)
|
self.phy_signal_file = self.run_dir.child(AmarisoftENB.PHY_SIGNAL_FILE)
|
||||||
|
|
||||||
|
@ -165,6 +176,7 @@ class AmarisoftENB(enb.eNodeB):
|
||||||
self.remote_config_sib23_file = remote_run_dir.child(AmarisoftENB.CFGFILE_SIB23)
|
self.remote_config_sib23_file = remote_run_dir.child(AmarisoftENB.CFGFILE_SIB23)
|
||||||
self.remote_config_rf_file = remote_run_dir.child(AmarisoftENB.CFGFILE_RF)
|
self.remote_config_rf_file = remote_run_dir.child(AmarisoftENB.CFGFILE_RF)
|
||||||
self.remote_config_drb_file = remote_run_dir.child(AmarisoftENB.CFGFILE_DRB)
|
self.remote_config_drb_file = remote_run_dir.child(AmarisoftENB.CFGFILE_DRB)
|
||||||
|
self.remote_config_drb_nr_file = remote_run_dir.child(AmarisoftENB.CFGFILE_DRB_NR)
|
||||||
self.remote_log_file = remote_run_dir.child(AmarisoftENB.LOGFILE)
|
self.remote_log_file = remote_run_dir.child(AmarisoftENB.LOGFILE)
|
||||||
self.remote_phy_signal_file = remote_run_dir.child(AmarisoftENB.PHY_SIGNAL_FILE)
|
self.remote_phy_signal_file = remote_run_dir.child(AmarisoftENB.PHY_SIGNAL_FILE)
|
||||||
|
|
||||||
|
@ -176,6 +188,17 @@ class AmarisoftENB(enb.eNodeB):
|
||||||
|
|
||||||
config.overlay(values, dict(enb={'enable_dl_awgn': util.str2bool(values['enb'].get('enable_dl_awgn', 'false'))}))
|
config.overlay(values, dict(enb={'enable_dl_awgn': util.str2bool(values['enb'].get('enable_dl_awgn', 'false'))}))
|
||||||
|
|
||||||
|
self.nr_bandwidth = int(values['enb'].get('nr_bandwidth', 10))
|
||||||
|
config.overlay(values, dict(enb={'nr_bandwidth': self.nr_bandwidth}))
|
||||||
|
|
||||||
|
if (self._num_cells > 0):
|
||||||
|
if (self._num_nr_cells <= 0):
|
||||||
|
self.ran_type = "lte"
|
||||||
|
else:
|
||||||
|
self.ran_type = "nsa"
|
||||||
|
else:
|
||||||
|
raise log.Error('5G SA not supported yet')
|
||||||
|
|
||||||
# Remove EEA0 from cipher list, if specified, as it's always assumed as default
|
# Remove EEA0 from cipher list, if specified, as it's always assumed as default
|
||||||
cipher_list = values['enb'].get('cipher_list', None)
|
cipher_list = values['enb'].get('cipher_list', None)
|
||||||
if "eea0" in cipher_list: cipher_list.remove("eea0")
|
if "eea0" in cipher_list: cipher_list.remove("eea0")
|
||||||
|
@ -237,6 +260,7 @@ class AmarisoftENB(enb.eNodeB):
|
||||||
self.gen_conf_file(self.config_sib23_file, AmarisoftENB.CFGFILE_SIB23, values)
|
self.gen_conf_file(self.config_sib23_file, AmarisoftENB.CFGFILE_SIB23, values)
|
||||||
self.gen_conf_file(self.config_rf_file, AmarisoftENB.CFGFILE_RF, values)
|
self.gen_conf_file(self.config_rf_file, AmarisoftENB.CFGFILE_RF, values)
|
||||||
self.gen_conf_file(self.config_drb_file, AmarisoftENB.CFGFILE_DRB, values)
|
self.gen_conf_file(self.config_drb_file, AmarisoftENB.CFGFILE_DRB, values)
|
||||||
|
self.gen_conf_file(self.config_drb_nr_file, AmarisoftENB.CFGFILE_DRB_NR, values)
|
||||||
|
|
||||||
if not self._run_node.is_local():
|
if not self._run_node.is_local():
|
||||||
self.rem_host.recreate_remote_dir(self.remote_inst)
|
self.rem_host.recreate_remote_dir(self.remote_inst)
|
||||||
|
@ -247,6 +271,7 @@ class AmarisoftENB(enb.eNodeB):
|
||||||
self.rem_host.scp('scp-cfg-sib23-to-remote', self.config_sib23_file, self.remote_config_sib23_file)
|
self.rem_host.scp('scp-cfg-sib23-to-remote', self.config_sib23_file, self.remote_config_sib23_file)
|
||||||
self.rem_host.scp('scp-cfg-rr-to-remote', self.config_rf_file, self.remote_config_rf_file)
|
self.rem_host.scp('scp-cfg-rr-to-remote', self.config_rf_file, self.remote_config_rf_file)
|
||||||
self.rem_host.scp('scp-cfg-drb-to-remote', self.config_drb_file, self.remote_config_drb_file)
|
self.rem_host.scp('scp-cfg-drb-to-remote', self.config_drb_file, self.remote_config_drb_file)
|
||||||
|
self.rem_host.scp('scp-cfg-drb-nr-to-remote', self.config_drb_nr_file, self.remote_config_drb_nr_file)
|
||||||
|
|
||||||
def ue_add(self, ue):
|
def ue_add(self, ue):
|
||||||
if self.ue is not None:
|
if self.ue is not None:
|
||||||
|
@ -279,11 +304,17 @@ class AmarisoftENB(enb.eNodeB):
|
||||||
rfemu_obj = rfemu.get_instance_by_type(rfemu_cfg['type'], rfemu_cfg)
|
rfemu_obj = rfemu.get_instance_by_type(rfemu_cfg['type'], rfemu_cfg)
|
||||||
return rfemu_obj
|
return rfemu_obj
|
||||||
|
|
||||||
|
def get_nr_bandwidth(self):
|
||||||
|
return self.nr_bandwidth
|
||||||
|
|
||||||
def ue_max_rate(self, downlink=True, num_carriers=1):
|
def ue_max_rate(self, downlink=True, num_carriers=1):
|
||||||
if self._duplex == 'fdd':
|
if self.ran_type == 'lte':
|
||||||
return self.ue_max_rate_fdd(downlink, num_carriers)
|
if self._duplex == 'fdd':
|
||||||
|
return self.ue_max_rate_fdd(downlink, num_carriers)
|
||||||
|
else:
|
||||||
|
return self.ue_max_rate_tdd(downlink, num_carriers)
|
||||||
else:
|
else:
|
||||||
return self.ue_max_rate_tdd(downlink, num_carriers)
|
return self.ue_max_rate_nsa_tdd(downlink)
|
||||||
|
|
||||||
def ue_max_rate_fdd(self, downlink, num_carriers):
|
def ue_max_rate_fdd(self, downlink, num_carriers):
|
||||||
# The max rate for a single UE per PRB configuration in TM1 with MCS 28 QAM64
|
# The max rate for a single UE per PRB configuration in TM1 with MCS 28 QAM64
|
||||||
|
@ -323,7 +354,7 @@ class AmarisoftENB(enb.eNodeB):
|
||||||
return max_rate
|
return max_rate
|
||||||
|
|
||||||
def ue_max_rate_tdd(self, downlink, num_carriers):
|
def ue_max_rate_tdd(self, downlink, num_carriers):
|
||||||
# Max rate calculation for TDD depends on the acutal TDD configuration
|
# Max rate calculation for TDD depends on the actual TDD configuration
|
||||||
# See: https://www.sharetechnote.com/html/Handbook_LTE_ThroughputCalculationExample_TDD.html
|
# See: https://www.sharetechnote.com/html/Handbook_LTE_ThroughputCalculationExample_TDD.html
|
||||||
# and https://i0.wp.com/www.techtrained.com/wp-content/uploads/2017/09/Blog_Post_1_TDD_Max_Throughput_Theoretical.jpg
|
# and https://i0.wp.com/www.techtrained.com/wp-content/uploads/2017/09/Blog_Post_1_TDD_Max_Throughput_Theoretical.jpg
|
||||||
max_phy_rate_tdd_uldl_config0_sp0 = { 6 : 1.5e6,
|
max_phy_rate_tdd_uldl_config0_sp0 = { 6 : 1.5e6,
|
||||||
|
@ -333,8 +364,21 @@ class AmarisoftENB(enb.eNodeB):
|
||||||
75 : 18.4e6,
|
75 : 18.4e6,
|
||||||
100 : 54.5e6 }
|
100 : 54.5e6 }
|
||||||
if downlink:
|
if downlink:
|
||||||
max_rate = max_phy_rate_tdd_uldl_config0_sp0[self.num_prb()]
|
return max_phy_rate_tdd_uldl_config0_sp0[self.num_prb()]
|
||||||
else:
|
else:
|
||||||
return 1e6 # dummy value, we need to replace that later
|
return 1e6 # dummy value, we need to replace that later
|
||||||
|
|
||||||
|
def ue_max_rate_nsa_tdd(self, downlink):
|
||||||
|
# Max rate calculation based on https://5g-tools.com/5g-nr-throughput-calculator/
|
||||||
|
# Only FR1 15kHz SCS, QAM64, 6 DL slots, 3 UL slots
|
||||||
|
max_phy_rate_nsa_dl_fr1_15khz = { 10: 18.4e6,
|
||||||
|
20: 38.0e6 }
|
||||||
|
max_phy_rate_nsa_ul_fr1_15khz = { 10: 10.7e6,
|
||||||
|
20: 23.0e6 }
|
||||||
|
|
||||||
|
if downlink:
|
||||||
|
return max_phy_rate_nsa_dl_fr1_15khz[self.get_nr_bandwidth()]
|
||||||
|
else:
|
||||||
|
return max_phy_rate_nsa_ul_fr1_15khz[self.get_nr_bandwidth()]
|
||||||
|
|
||||||
# vim: expandtab tabstop=4 shiftwidth=4
|
# vim: expandtab tabstop=4 shiftwidth=4
|
||||||
|
|
|
@ -0,0 +1,423 @@
|
||||||
|
/* DRB configuration for each QCI value.
|
||||||
|
QCI characteristics in TS 23.203 table 6.1.7 */
|
||||||
|
[
|
||||||
|
/**************************************** GBR */
|
||||||
|
{
|
||||||
|
qci: 1, /* UM - real time (RTP for VOIP) */
|
||||||
|
use_for_en_dc: false,
|
||||||
|
pdcp_config: {
|
||||||
|
discardTimer: 100, /* in ms, 0 means infinity */
|
||||||
|
pdcp_SN_SizeUL: 12,
|
||||||
|
pdcp_SN_SizeDL: 12,
|
||||||
|
statusReportRequired: false,
|
||||||
|
outOfOrderDelivery: false,
|
||||||
|
t_Reordering: 0,
|
||||||
|
/* ROHC header compression */
|
||||||
|
/*
|
||||||
|
headerCompression: {
|
||||||
|
maxCID: 15,
|
||||||
|
profile0x0001: true, // RTP profile
|
||||||
|
profile0x0002: true, // UDP profile
|
||||||
|
profile0x0004: false, // IP profile
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
},
|
||||||
|
rlc_config: {
|
||||||
|
ul_um: {
|
||||||
|
sn_FieldLength: 6,
|
||||||
|
},
|
||||||
|
dl_um: {
|
||||||
|
sn_FieldLength: 6,
|
||||||
|
t_Reassembly: 50,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
logical_channel_config: {
|
||||||
|
priority: 7,
|
||||||
|
prioritisedBitRate: 0, /* in kb/s, -1 means infinity */
|
||||||
|
bucketSizeDuration: 100, /* in ms */
|
||||||
|
logicalChannelGroup: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
qci: 2, /* UM - real time (video) */
|
||||||
|
pdcp_config: {
|
||||||
|
discardTimer: 150, /* in ms, 0 means infinity */
|
||||||
|
pdcp_SN_SizeUL: 18,
|
||||||
|
pdcp_SN_SizeDL: 18,
|
||||||
|
statusReportRequired: false,
|
||||||
|
outOfOrderDelivery: false,
|
||||||
|
t_Reordering: 0,
|
||||||
|
},
|
||||||
|
rlc_config: {
|
||||||
|
ul_um: {
|
||||||
|
sn_FieldLength: 12,
|
||||||
|
},
|
||||||
|
dl_um: {
|
||||||
|
sn_FieldLength: 12,
|
||||||
|
t_Reassembly: 50,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
logical_channel_config: {
|
||||||
|
priority: 8,
|
||||||
|
prioritisedBitRate: 0, /* in kb/s, -1 means infinity */
|
||||||
|
bucketSizeDuration: 100, /* in ms */
|
||||||
|
logicalChannelGroup: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
qci: 3, /* UM - real time (gaming) */
|
||||||
|
pdcp_config: {
|
||||||
|
discardTimer: 100, /* in ms, 0 means infinity */
|
||||||
|
pdcp_SN_SizeUL: 18,
|
||||||
|
pdcp_SN_SizeDL: 18,
|
||||||
|
statusReportRequired: false,
|
||||||
|
outOfOrderDelivery: false,
|
||||||
|
t_Reordering: 0,
|
||||||
|
},
|
||||||
|
rlc_config: {
|
||||||
|
ul_um: {
|
||||||
|
sn_FieldLength: 12,
|
||||||
|
},
|
||||||
|
dl_um: {
|
||||||
|
sn_FieldLength: 12,
|
||||||
|
t_Reassembly: 50,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
logical_channel_config: {
|
||||||
|
priority: 7,
|
||||||
|
prioritisedBitRate: 0, /* in kb/s, -1 means infinity */
|
||||||
|
bucketSizeDuration: 100, /* in ms */
|
||||||
|
logicalChannelGroup: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
qci: 4, /* AM - Non-Conversational Video (Buffered Streaming) */
|
||||||
|
pdcp_config: {
|
||||||
|
discardTimer: 0, /* in ms, 0 means infinity */
|
||||||
|
pdcp_SN_SizeUL: 18,
|
||||||
|
pdcp_SN_SizeDL: 18,
|
||||||
|
statusReportRequired: true,
|
||||||
|
outOfOrderDelivery: false,
|
||||||
|
},
|
||||||
|
rlc_config: {
|
||||||
|
ul_am: {
|
||||||
|
sn_FieldLength: 18,
|
||||||
|
t_PollRetransmit: 80, /* in ms */
|
||||||
|
pollPDU: 64,
|
||||||
|
pollByte: 125, /* in kBytes, 0 means infinity */
|
||||||
|
maxRetxThreshold: 4,
|
||||||
|
},
|
||||||
|
dl_am: {
|
||||||
|
sn_FieldLength: 18,
|
||||||
|
t_Reassembly: 80, /* in ms */
|
||||||
|
t_StatusProhibit: 10, /* in ms */
|
||||||
|
},
|
||||||
|
},
|
||||||
|
logical_channel_config: {
|
||||||
|
priority: 9,
|
||||||
|
prioritisedBitRate: 8, /* in kb/s, -1 means infinity */
|
||||||
|
bucketSizeDuration: 100, /* in ms */
|
||||||
|
logicalChannelGroup: 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
qci: 65, /* UM - real time (MC-PTT voice) */
|
||||||
|
use_for_en_dc: false,
|
||||||
|
pdcp_config: {
|
||||||
|
discardTimer: 100, /* in ms, 0 means infinity */
|
||||||
|
pdcp_SN_SizeUL: 12,
|
||||||
|
pdcp_SN_SizeDL: 12,
|
||||||
|
statusReportRequired: false,
|
||||||
|
outOfOrderDelivery: false,
|
||||||
|
t_Reordering: 0,
|
||||||
|
/* ROHC header compression */
|
||||||
|
/*
|
||||||
|
headerCompression: {
|
||||||
|
maxCID: 15,
|
||||||
|
profile0x0001: true, // RTP profile
|
||||||
|
profile0x0002: true, // UDP profile
|
||||||
|
profile0x0004: false, // IP profile
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
},
|
||||||
|
rlc_config: {
|
||||||
|
ul_um: {
|
||||||
|
sn_FieldLength: 6,
|
||||||
|
},
|
||||||
|
dl_um: {
|
||||||
|
sn_FieldLength: 6,
|
||||||
|
t_Reassembly: 50,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
logical_channel_config: {
|
||||||
|
priority: 5,
|
||||||
|
prioritisedBitRate: 0, /* in kb/s, -1 means infinity */
|
||||||
|
bucketSizeDuration: 100, /* in ms */
|
||||||
|
logicalChannelGroup: 4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
qci: 66, /* UM - real time (non MC-PTT voice) */
|
||||||
|
use_for_en_dc: false,
|
||||||
|
pdcp_config: {
|
||||||
|
discardTimer: 150, /* in ms, 0 means infinity */
|
||||||
|
pdcp_SN_SizeUL: 18,
|
||||||
|
pdcp_SN_SizeDL: 18,
|
||||||
|
statusReportRequired: false,
|
||||||
|
outOfOrderDelivery: false,
|
||||||
|
t_Reordering: 0,
|
||||||
|
},
|
||||||
|
rlc_config: {
|
||||||
|
ul_um: {
|
||||||
|
sn_FieldLength: 12,
|
||||||
|
},
|
||||||
|
dl_um: {
|
||||||
|
sn_FieldLength: 12,
|
||||||
|
t_Reassembly: 50,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
logical_channel_config: {
|
||||||
|
priority: 7,
|
||||||
|
prioritisedBitRate: 0, /* in kb/s, -1 means infinity */
|
||||||
|
bucketSizeDuration: 100, /* in ms */
|
||||||
|
logicalChannelGroup: 4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
qci: 67, /* UM - Mission Critical Video user plane */
|
||||||
|
use_for_en_dc: false,
|
||||||
|
pdcp_config: {
|
||||||
|
discardTimer: 100, /* in ms, 0 means infinity */
|
||||||
|
pdcp_SN_SizeUL: 18,
|
||||||
|
pdcp_SN_SizeDL: 18,
|
||||||
|
statusReportRequired: false,
|
||||||
|
outOfOrderDelivery: false,
|
||||||
|
t_Reordering: 0,
|
||||||
|
},
|
||||||
|
rlc_config: {
|
||||||
|
ul_um: {
|
||||||
|
sn_FieldLength: 12,
|
||||||
|
},
|
||||||
|
dl_um: {
|
||||||
|
sn_FieldLength: 12,
|
||||||
|
t_Reassembly: 50,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
logical_channel_config: {
|
||||||
|
priority: 6,
|
||||||
|
prioritisedBitRate: 0, /* in kb/s, -1 means infinity */
|
||||||
|
bucketSizeDuration: 100, /* in ms */
|
||||||
|
logicalChannelGroup: 5,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
/**************************************** non GBR */
|
||||||
|
{
|
||||||
|
qci: 5, /* AM - high priority (SIP) */
|
||||||
|
use_for_en_dc: false,
|
||||||
|
pdcp_config: {
|
||||||
|
discardTimer: 0, /* in ms, 0 means infinity */
|
||||||
|
pdcp_SN_SizeUL: 18,
|
||||||
|
pdcp_SN_SizeDL: 18,
|
||||||
|
statusReportRequired: true,
|
||||||
|
outOfOrderDelivery: false,
|
||||||
|
},
|
||||||
|
rlc_config: {
|
||||||
|
ul_am: {
|
||||||
|
sn_FieldLength: 18,
|
||||||
|
t_PollRetransmit: 80, /* in ms */
|
||||||
|
pollPDU: 64,
|
||||||
|
pollByte: 125, /* in kBytes, 0 means infinity */
|
||||||
|
maxRetxThreshold: 4,
|
||||||
|
},
|
||||||
|
dl_am: {
|
||||||
|
sn_FieldLength: 18,
|
||||||
|
t_Reassembly: 80, /* in ms */
|
||||||
|
t_StatusProhibit: 10, /* in ms */
|
||||||
|
},
|
||||||
|
},
|
||||||
|
logical_channel_config: {
|
||||||
|
priority: 6,
|
||||||
|
prioritisedBitRate: 8, /* in kb/s, -1 means infinity */
|
||||||
|
bucketSizeDuration: 100, /* in ms */
|
||||||
|
logicalChannelGroup: 4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
qci: 6, /* AM - Video (buffered streaming) */
|
||||||
|
pdcp_config: {
|
||||||
|
discardTimer: 0, /* in ms, 0 means infinity */
|
||||||
|
pdcp_SN_SizeUL: 18,
|
||||||
|
pdcp_SN_SizeDL: 18,
|
||||||
|
statusReportRequired: true,
|
||||||
|
outOfOrderDelivery: false,
|
||||||
|
},
|
||||||
|
rlc_config: {
|
||||||
|
ul_am: {
|
||||||
|
sn_FieldLength: 18,
|
||||||
|
t_PollRetransmit: 80, /* in ms */
|
||||||
|
pollPDU: 64,
|
||||||
|
pollByte: 125, /* in kBytes, 0 means infinity */
|
||||||
|
maxRetxThreshold: 4,
|
||||||
|
},
|
||||||
|
dl_am: {
|
||||||
|
sn_FieldLength: 18,
|
||||||
|
t_Reassembly: 80, /* in ms */
|
||||||
|
t_StatusProhibit: 10, /* in ms */
|
||||||
|
},
|
||||||
|
},
|
||||||
|
logical_channel_config: {
|
||||||
|
priority: 10,
|
||||||
|
prioritisedBitRate: 8, /* in kb/s, -1 means infinity */
|
||||||
|
bucketSizeDuration: 100, /* in ms */
|
||||||
|
logicalChannelGroup: 5,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
qci: 7, /* UM - voice, video (live streaming), interactive gaming */
|
||||||
|
pdcp_config: {
|
||||||
|
discardTimer: 100, /* in ms, 0 means infinity */
|
||||||
|
pdcp_SN_SizeUL: 18,
|
||||||
|
pdcp_SN_SizeDL: 18,
|
||||||
|
statusReportRequired: false,
|
||||||
|
outOfOrderDelivery: false,
|
||||||
|
t_Reordering: 0,
|
||||||
|
},
|
||||||
|
rlc_config: {
|
||||||
|
ul_um: {
|
||||||
|
sn_FieldLength: 12,
|
||||||
|
},
|
||||||
|
dl_um: {
|
||||||
|
sn_FieldLength: 12,
|
||||||
|
t_Reassembly: 50,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
logical_channel_config: {
|
||||||
|
priority: 11,
|
||||||
|
prioritisedBitRate: 0, /* in kb/s, -1 means infinity */
|
||||||
|
bucketSizeDuration: 100, /* in ms */
|
||||||
|
logicalChannelGroup: 6,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
qci: 8, /* AM - best effort (Internet traffic) */
|
||||||
|
pdcp_config: {
|
||||||
|
discardTimer: 0, /* in ms, 0 means infinity */
|
||||||
|
pdcp_SN_SizeUL: 18,
|
||||||
|
pdcp_SN_SizeDL: 18,
|
||||||
|
statusReportRequired: true,
|
||||||
|
outOfOrderDelivery: false,
|
||||||
|
},
|
||||||
|
rlc_config: {
|
||||||
|
ul_am: {
|
||||||
|
sn_FieldLength: 18,
|
||||||
|
t_PollRetransmit: 80, /* in ms */
|
||||||
|
pollPDU: 64,
|
||||||
|
pollByte: 125, /* in kBytes, 0 means infinity */
|
||||||
|
maxRetxThreshold: 4,
|
||||||
|
},
|
||||||
|
dl_am: {
|
||||||
|
sn_FieldLength: 18,
|
||||||
|
t_Reassembly: 80, /* in ms */
|
||||||
|
t_StatusProhibit: 10, /* in ms */
|
||||||
|
},
|
||||||
|
},
|
||||||
|
logical_channel_config: {
|
||||||
|
priority: 12,
|
||||||
|
prioritisedBitRate: 8, /* in kb/s, -1 means infinity */
|
||||||
|
bucketSizeDuration: 100, /* in ms */
|
||||||
|
logicalChannelGroup: 7,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
qci: 9, /* AM - best effort (Internet traffic) */
|
||||||
|
pdcp_config: {
|
||||||
|
discardTimer: 0, /* in ms, 0 means infinity */
|
||||||
|
pdcp_SN_SizeUL: 18,
|
||||||
|
pdcp_SN_SizeDL: 18,
|
||||||
|
statusReportRequired: true,
|
||||||
|
outOfOrderDelivery: false,
|
||||||
|
},
|
||||||
|
rlc_config: {
|
||||||
|
ul_am: {
|
||||||
|
sn_FieldLength: 18,
|
||||||
|
t_PollRetransmit: 80, /* in ms */
|
||||||
|
pollPDU: 64,
|
||||||
|
pollByte: 125, /* in kBytes, 0 means infinity */
|
||||||
|
maxRetxThreshold: 4,
|
||||||
|
},
|
||||||
|
dl_am: {
|
||||||
|
sn_FieldLength: 18,
|
||||||
|
t_Reassembly: 80, /* in ms */
|
||||||
|
t_StatusProhibit: 10, /* in ms */
|
||||||
|
},
|
||||||
|
},
|
||||||
|
logical_channel_config: {
|
||||||
|
priority: 13,
|
||||||
|
prioritisedBitRate: 8, /* in kb/s, -1 means infinity */
|
||||||
|
bucketSizeDuration: 100, /* in ms */
|
||||||
|
logicalChannelGroup: 7,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
qci: 69, /* AM - high priority (MC-PTT signalling) */
|
||||||
|
use_for_en_dc: false,
|
||||||
|
pdcp_config: {
|
||||||
|
discardTimer: 0, /* in ms, 0 means infinity */
|
||||||
|
pdcp_SN_SizeUL: 18,
|
||||||
|
pdcp_SN_SizeDL: 18,
|
||||||
|
statusReportRequired: true,
|
||||||
|
outOfOrderDelivery: false,
|
||||||
|
},
|
||||||
|
rlc_config: {
|
||||||
|
ul_am: {
|
||||||
|
sn_FieldLength: 18,
|
||||||
|
t_PollRetransmit: 80, /* in ms */
|
||||||
|
pollPDU: 64,
|
||||||
|
pollByte: 125, /* in kBytes, 0 means infinity */
|
||||||
|
maxRetxThreshold: 4,
|
||||||
|
},
|
||||||
|
dl_am: {
|
||||||
|
sn_FieldLength: 18,
|
||||||
|
t_Reassembly: 80, /* in ms */
|
||||||
|
t_StatusProhibit: 10, /* in ms */
|
||||||
|
},
|
||||||
|
},
|
||||||
|
logical_channel_config: {
|
||||||
|
priority: 4,
|
||||||
|
prioritisedBitRate: 8, /* in kb/s, -1 means infinity */
|
||||||
|
bucketSizeDuration: 100, /* in ms */
|
||||||
|
logicalChannelGroup: 4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
qci: 70, /* AM - MC data */
|
||||||
|
use_for_en_dc: false,
|
||||||
|
pdcp_config: {
|
||||||
|
discardTimer: 0, /* in ms, 0 means infinity */
|
||||||
|
pdcp_SN_SizeUL: 18,
|
||||||
|
pdcp_SN_SizeDL: 18,
|
||||||
|
statusReportRequired: true,
|
||||||
|
outOfOrderDelivery: false,
|
||||||
|
},
|
||||||
|
rlc_config: {
|
||||||
|
ul_am: {
|
||||||
|
sn_FieldLength: 18,
|
||||||
|
t_PollRetransmit: 80, /* in ms */
|
||||||
|
pollPDU: 64,
|
||||||
|
pollByte: 125, /* in kBytes, 0 means infinity */
|
||||||
|
maxRetxThreshold: 4,
|
||||||
|
},
|
||||||
|
dl_am: {
|
||||||
|
sn_FieldLength: 18,
|
||||||
|
t_Reassembly: 80, /* in ms */
|
||||||
|
t_StatusProhibit: 10, /* in ms */
|
||||||
|
},
|
||||||
|
},
|
||||||
|
logical_channel_config: {
|
||||||
|
priority: 11,
|
||||||
|
prioritisedBitRate: 8, /* in kb/s, -1 means infinity */
|
||||||
|
bucketSizeDuration: 100, /* in ms */
|
||||||
|
logicalChannelGroup: 5,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
|
@ -1,6 +1,5 @@
|
||||||
/* lteenb configuration file version 2018-10-18
|
/* OGT templated version of the lteenb configuration file for 4G and 5G NSA */
|
||||||
* Copyright (C) 2015-2018 Amarisoft
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
|
|
||||||
%if enb.license_server_addr != '0.0.0.0':
|
%if enb.license_server_addr != '0.0.0.0':
|
||||||
|
@ -64,10 +63,15 @@
|
||||||
/* high 20 bits of SIB1.cellIdentifier */
|
/* high 20 bits of SIB1.cellIdentifier */
|
||||||
enb_id: ${enb.id},
|
enb_id: ${enb.id},
|
||||||
|
|
||||||
|
% if int(enb.num_nr_cells) > 0:
|
||||||
|
nr_support: true,
|
||||||
|
% endif
|
||||||
|
|
||||||
/* list of cells */
|
/* list of cells */
|
||||||
cell_list: [
|
cell_list: [
|
||||||
|
|
||||||
%for cell in enb.cell_list:
|
%for cell in enb.cell_list:
|
||||||
|
%if loop.index == 0:
|
||||||
{
|
{
|
||||||
dl_earfcn: ${cell.dl_earfcn},
|
dl_earfcn: ${cell.dl_earfcn},
|
||||||
rf_port: ${cell.rf_port},
|
rf_port: ${cell.rf_port},
|
||||||
|
@ -85,12 +89,38 @@
|
||||||
scell_list: [
|
scell_list: [
|
||||||
%for scell_id in cell.scell_list:
|
%for scell_id in cell.scell_list:
|
||||||
{ cell_id: ${scell_id}, cross_carrier_scheduling: false, scheduling_cell_id: ${cell.cell_id}, ul_allowed: true},
|
{ cell_id: ${scell_id}, cross_carrier_scheduling: false, scheduling_cell_id: ${cell.cell_id}, ul_allowed: true},
|
||||||
|
%endfor
|
||||||
|
],
|
||||||
|
|
||||||
|
nr_scell_list: [
|
||||||
|
%for nr_scell_id in cell.nr_scell_list:
|
||||||
|
{ cell_id: ${nr_scell_id} },
|
||||||
%endfor
|
%endfor
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
%endif
|
||||||
%endfor
|
%endfor
|
||||||
], /* cell_list */
|
], /* cell_list */
|
||||||
|
|
||||||
|
% if int(enb.num_nr_cells) > 0:
|
||||||
|
|
||||||
|
nr_cell_list: [
|
||||||
|
|
||||||
|
%for nr_cell in enb.nr_cell_list:
|
||||||
|
%if loop.index == 0:
|
||||||
|
{
|
||||||
|
rf_port: ${nr_cell.rf_port},
|
||||||
|
cell_id: ${nr_cell.cell_id},
|
||||||
|
band: ${nr_cell.band},
|
||||||
|
dl_nr_arfcn: ${nr_cell.dl_nr_arfcn},
|
||||||
|
},
|
||||||
|
%endif
|
||||||
|
%endfor
|
||||||
|
|
||||||
|
], /* nr_cell_list */
|
||||||
|
|
||||||
|
% endif
|
||||||
|
|
||||||
/* default cell parameters */
|
/* default cell parameters */
|
||||||
cell_default: {
|
cell_default: {
|
||||||
/* Broadcasted PLMN identities */
|
/* Broadcasted PLMN identities */
|
||||||
|
@ -123,7 +153,11 @@
|
||||||
/* other SIBs, in same order as the scheduling list in SIB 1 */
|
/* other SIBs, in same order as the scheduling list in SIB 1 */
|
||||||
sib_sched_list: [ "amarisoft_sib23.asn" ],
|
sib_sched_list: [ "amarisoft_sib23.asn" ],
|
||||||
|
|
||||||
|
% if int(enb.num_prb) == 6:
|
||||||
si_coderate: 0.30, /* maximum code rate for SI/RA/P-RNTI messages */
|
si_coderate: 0.30, /* maximum code rate for SI/RA/P-RNTI messages */
|
||||||
|
% else:
|
||||||
|
si_coderate: 0.20, /* maximum code rate for SI/RA/P-RNTI messages */
|
||||||
|
% endif
|
||||||
si_pdcch_format: 2, /* 2 or 3. Log2 of the number of CCEs for PDCCH
|
si_pdcch_format: 2, /* 2 or 3. Log2 of the number of CCEs for PDCCH
|
||||||
for SI/RA/P-RNTI */
|
for SI/RA/P-RNTI */
|
||||||
|
|
||||||
|
@ -154,7 +188,11 @@
|
||||||
pusch_msg3_mcs: 0,
|
pusch_msg3_mcs: 0,
|
||||||
|
|
||||||
/* this CQI value is assumed when none is received from the UE */
|
/* this CQI value is assumed when none is received from the UE */
|
||||||
|
% if int(enb.num_prb) == 6:
|
||||||
initial_cqi: 5,
|
initial_cqi: 5,
|
||||||
|
% else:
|
||||||
|
initial_cqi: 3,
|
||||||
|
% endif
|
||||||
|
|
||||||
/* if defined, force the PUSCH MCS for all UEs. Otherwise it is
|
/* if defined, force the PUSCH MCS for all UEs. Otherwise it is
|
||||||
computed from the last received SRS/PUSCH. */
|
computed from the last received SRS/PUSCH. */
|
||||||
|
@ -162,6 +200,9 @@
|
||||||
|
|
||||||
transmission_mode: ${enb.transmission_mode},
|
transmission_mode: ${enb.transmission_mode},
|
||||||
|
|
||||||
|
dl_256qam: true,
|
||||||
|
ul_64qam: true,
|
||||||
|
|
||||||
/* Scheduling request period (ms). Must be >= 40 for HD-FDD */
|
/* Scheduling request period (ms). Must be >= 40 for HD-FDD */
|
||||||
sr_period: 20,
|
sr_period: 20,
|
||||||
|
|
||||||
|
@ -188,6 +229,9 @@
|
||||||
// tdd_ack_nack_feedback_mode_r10: "cs",
|
// tdd_ack_nack_feedback_mode_r10: "cs",
|
||||||
% endif
|
% endif
|
||||||
|
|
||||||
|
n1_pucch_sr_count: 11, /* increase if more UEs are needed */
|
||||||
|
cqi_pucch_n_rb: 1, /* increase if more UEs are needed */
|
||||||
|
|
||||||
/* number of PUCCH 1b CS resources. It determines
|
/* number of PUCCH 1b CS resources. It determines
|
||||||
the maximum number of UEs that can be scheduled in one TTI
|
the maximum number of UEs that can be scheduled in one TTI
|
||||||
using carrier aggregation with PUCCH 1b CS ack/nack feedback. */
|
using carrier aggregation with PUCCH 1b CS ack/nack feedback. */
|
||||||
|
@ -266,6 +310,14 @@
|
||||||
a3_offset: ${enb.a3_report_value},
|
a3_offset: ${enb.a3_report_value},
|
||||||
a3_hysteresis: ${enb.a3_hysteresis},
|
a3_hysteresis: ${enb.a3_hysteresis},
|
||||||
a3_time_to_trigger: ${enb.a3_time_to_trigger},
|
a3_time_to_trigger: ${enb.a3_time_to_trigger},
|
||||||
|
% if int(enb.num_nr_cells) > 0:
|
||||||
|
// NR events hard-coded
|
||||||
|
nr_b1_report_type: "rsrp",
|
||||||
|
nr_b1_rsrp: -100,
|
||||||
|
nr_b1_hysteresis: 0,
|
||||||
|
nr_b1_time_to_trigger: 100,
|
||||||
|
nr_rsrp_filter_coeff: 3
|
||||||
|
% endif
|
||||||
},
|
},
|
||||||
|
|
||||||
/* measurement gap configuration */
|
/* measurement gap configuration */
|
||||||
|
@ -276,4 +328,357 @@
|
||||||
ho_from_meas: true,
|
ho_from_meas: true,
|
||||||
% endif
|
% endif
|
||||||
},
|
},
|
||||||
|
|
||||||
|
% if int(enb.num_nr_cells) > 0:
|
||||||
|
nr_cell_default: {
|
||||||
|
subcarrier_spacing: 15, /* kHz */
|
||||||
|
ssb_subcarrier_spacing: 30,
|
||||||
|
bandwidth: ${enb.nr_bandwidth}, /* MHz */
|
||||||
|
n_antenna_dl: 1,
|
||||||
|
n_antenna_ul: 1,
|
||||||
|
|
||||||
|
/* force the timing TA offset (optional) */
|
||||||
|
n_timing_advance_offset: 0,
|
||||||
|
|
||||||
|
tdd_ul_dl_config: {
|
||||||
|
pattern1: {
|
||||||
|
period: 10,
|
||||||
|
dl_slots: 6,
|
||||||
|
dl_symbols: 0,
|
||||||
|
ul_slots: 3,
|
||||||
|
ul_symbols: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ssb_pos_bitmap: "10000000",
|
||||||
|
ssb_period: 20, /* in ms */
|
||||||
|
n_id_cell: 500,
|
||||||
|
|
||||||
|
root_sequence_index: 1, /* PRACH root sequence index */
|
||||||
|
|
||||||
|
/* Scheduling request period (slots). */
|
||||||
|
sr_period: 40,
|
||||||
|
|
||||||
|
dmrs_type_a_pos: 2,
|
||||||
|
|
||||||
|
/* to limit the number of HARQ feedback in UL, use pdsch_harq_ack_max;
|
||||||
|
allows to workaround issues with SM-G977N for example */
|
||||||
|
//pdsch_harq_ack_max: 2,
|
||||||
|
|
||||||
|
prach: {
|
||||||
|
prach_config_index: 0,
|
||||||
|
msg1_subcarrier_spacing: 15, /* kHz */
|
||||||
|
msg1_fdm: 1,
|
||||||
|
% if int(enb.nr_bandwidth) == 10:
|
||||||
|
msg1_frequency_start: 1,
|
||||||
|
% else:
|
||||||
|
msg1_frequency_start: 3,
|
||||||
|
% endif
|
||||||
|
zero_correlation_zone_config: 0,
|
||||||
|
preamble_received_target_power: -110, /* in dBm */
|
||||||
|
preamble_trans_max: 7,
|
||||||
|
power_ramping_step: 4, /* in dB */
|
||||||
|
ra_response_window: 10, /* in slots */
|
||||||
|
restricted_set_config: "unrestricted_set",
|
||||||
|
ra_contention_resolution_timer: 64, /* in ms */
|
||||||
|
ssb_per_prach_occasion: 1,
|
||||||
|
cb_preambles_per_ssb: 8,
|
||||||
|
},
|
||||||
|
|
||||||
|
pdcch: {
|
||||||
|
common_coreset: {
|
||||||
|
rb_start: -1, /* -1 to have the maximum bandwidth */
|
||||||
|
l_crb: -1, /* -1 means all the bandwidth */
|
||||||
|
duration: 1,
|
||||||
|
precoder_granularity: "sameAsREG_bundle",
|
||||||
|
//dmrs_scid: 0,
|
||||||
|
},
|
||||||
|
|
||||||
|
dedicated_coreset: {
|
||||||
|
rb_start: -1, /* -1 to have the maximum bandwidth */
|
||||||
|
l_crb: -1, /* -1 means all the bandwidth */
|
||||||
|
duration: 1,
|
||||||
|
precoder_granularity: "sameAsREG_bundle",
|
||||||
|
//dmrs_scid: 0,
|
||||||
|
},
|
||||||
|
|
||||||
|
css: {
|
||||||
|
n_candidates: [ 1, 1, 1, 0, 0 ],
|
||||||
|
},
|
||||||
|
rar_al_index: 2,
|
||||||
|
|
||||||
|
uss: {
|
||||||
|
n_candidates: [ 0, 2, 1, 0, 0 ],
|
||||||
|
dci_0_1_and_1_1: false,
|
||||||
|
force_dci_0_0: true, // Forces DCI format 0_0 for Uplink
|
||||||
|
force_dci_1_0: true, // Forces DCI format 1_0 for Downlink
|
||||||
|
},
|
||||||
|
al_index: 1,
|
||||||
|
},
|
||||||
|
|
||||||
|
pdsch: {
|
||||||
|
mapping_type: "typeA",
|
||||||
|
start_symb: 1,
|
||||||
|
n_symb: 13,
|
||||||
|
dmrs_add_pos: 1,
|
||||||
|
dmrs_type: 1,
|
||||||
|
dmrs_max_len: 1,
|
||||||
|
k0: 0, /* delay in slots from DCI to PDSCH */
|
||||||
|
/* delay in slots from PDSCH to PUCCH/PUSCH ACK/NACK */
|
||||||
|
k1: [ 8, 7, 6, 6, 5, 4],
|
||||||
|
mcs_table: "qam64",
|
||||||
|
|
||||||
|
rar_mcs: 2,
|
||||||
|
/* If defined, force the PDSCH MCS for all UEs. Otherwise it is computed
|
||||||
|
* based on DL channel quality estimation */
|
||||||
|
/* mcs: 24, */
|
||||||
|
},
|
||||||
|
|
||||||
|
csi_rs: {
|
||||||
|
nzp_csi_rs_resource: [
|
||||||
|
{
|
||||||
|
csi_rs_id: 0,
|
||||||
|
n_ports: 1,
|
||||||
|
frequency_domain_allocation: "row2",
|
||||||
|
bitmap: "100000000000",
|
||||||
|
cdm_type: "no_cdm",
|
||||||
|
density: 1,
|
||||||
|
first_symb: 4,
|
||||||
|
rb_start: 0,
|
||||||
|
l_crb: -1, /* -1 means from rb_start to the end of the bandwidth */
|
||||||
|
power_control_offset: 0, /* dB */
|
||||||
|
power_control_offset_ss: 0, /* dB */
|
||||||
|
scrambling_id: 0,
|
||||||
|
period: 80,
|
||||||
|
offset: 1, /* != 0 to avoid collision with SSB */
|
||||||
|
qcl_info_periodic_csi_rs: 0,
|
||||||
|
},
|
||||||
|
#define USE_TRS
|
||||||
|
#ifdef USE_TRS
|
||||||
|
/* TRS : period of 40 ms, slots 1 & 2, symbols 4 and 8 */
|
||||||
|
{
|
||||||
|
csi_rs_id: 1,
|
||||||
|
n_ports: 1,
|
||||||
|
frequency_domain_allocation: "row1",
|
||||||
|
bitmap: "0001",
|
||||||
|
cdm_type: "no_cdm",
|
||||||
|
density: 3,
|
||||||
|
first_symb: 4,
|
||||||
|
rb_start: 0,
|
||||||
|
l_crb: -1, /* -1 means from rb_start to the end of the bandwidth */
|
||||||
|
power_control_offset: 0, /* dB */
|
||||||
|
power_control_offset_ss: 0, /* dB */
|
||||||
|
scrambling_id: 0,
|
||||||
|
period: 40,
|
||||||
|
offset: 11,
|
||||||
|
qcl_info_periodic_csi_rs: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
csi_rs_id: 2,
|
||||||
|
n_ports: 1,
|
||||||
|
frequency_domain_allocation: "row1",
|
||||||
|
bitmap: "0001",
|
||||||
|
cdm_type: "no_cdm",
|
||||||
|
density: 3,
|
||||||
|
first_symb: 8,
|
||||||
|
rb_start: 0,
|
||||||
|
l_crb: -1, /* -1 means from rb_start to the end of the bandwidth */
|
||||||
|
power_control_offset: 0, /* dB */
|
||||||
|
power_control_offset_ss: 0, /* dB */
|
||||||
|
scrambling_id: 0,
|
||||||
|
period: 40,
|
||||||
|
offset: 11,
|
||||||
|
qcl_info_periodic_csi_rs: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
csi_rs_id: 3,
|
||||||
|
n_ports: 1,
|
||||||
|
frequency_domain_allocation: "row1",
|
||||||
|
bitmap: "0001",
|
||||||
|
cdm_type: "no_cdm",
|
||||||
|
density: 3,
|
||||||
|
first_symb: 4,
|
||||||
|
rb_start: 0,
|
||||||
|
l_crb: -1, /* -1 means from rb_start to the end of the bandwidth */
|
||||||
|
power_control_offset: 0, /* dB */
|
||||||
|
power_control_offset_ss: 0, /* dB */
|
||||||
|
scrambling_id: 0,
|
||||||
|
period: 40,
|
||||||
|
offset: 12,
|
||||||
|
qcl_info_periodic_csi_rs: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
csi_rs_id: 4,
|
||||||
|
n_ports: 1,
|
||||||
|
frequency_domain_allocation: "row1",
|
||||||
|
bitmap: "0001",
|
||||||
|
cdm_type: "no_cdm",
|
||||||
|
density: 3,
|
||||||
|
first_symb: 8,
|
||||||
|
rb_start: 0,
|
||||||
|
l_crb: -1, /* -1 means from rb_start to the end of the bandwidth */
|
||||||
|
power_control_offset: 0, /* dB */
|
||||||
|
power_control_offset_ss: 0, /* dB */
|
||||||
|
scrambling_id: 0,
|
||||||
|
period: 40,
|
||||||
|
offset: 12,
|
||||||
|
qcl_info_periodic_csi_rs: 0,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
],
|
||||||
|
nzp_csi_rs_resource_set: [
|
||||||
|
{
|
||||||
|
csi_rs_set_id: 0,
|
||||||
|
nzp_csi_rs_resources: [ 0 ],
|
||||||
|
repetition: false,
|
||||||
|
},
|
||||||
|
#ifdef USE_TRS
|
||||||
|
{
|
||||||
|
csi_rs_set_id: 1,
|
||||||
|
nzp_csi_rs_resources: [ 1, 2, 3, 4 ],
|
||||||
|
repetition: false,
|
||||||
|
trs_info: true,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
],
|
||||||
|
|
||||||
|
csi_im_resource: [
|
||||||
|
{
|
||||||
|
csi_im_id: 0,
|
||||||
|
pattern: 1,
|
||||||
|
subcarrier_location: 8,
|
||||||
|
symbol_location: 8,
|
||||||
|
rb_start: 0,
|
||||||
|
l_crb: -1, /* -1 means from rb_start to the end of the bandwidth */
|
||||||
|
period: 80,
|
||||||
|
offset: 1, /* != 0 to avoid collision with SSB */
|
||||||
|
},
|
||||||
|
],
|
||||||
|
csi_im_resource_set: [
|
||||||
|
{
|
||||||
|
csi_im_set_id: 0,
|
||||||
|
csi_im_resources: [ 0 ],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
/* ZP CSI-RS to set the CSI-IM REs to zero */
|
||||||
|
zp_csi_rs_resource: [
|
||||||
|
{
|
||||||
|
csi_rs_id: 0,
|
||||||
|
frequency_domain_allocation: "row4",
|
||||||
|
bitmap: "100",
|
||||||
|
n_ports: 4,
|
||||||
|
cdm_type: "fd_cdm2",
|
||||||
|
first_symb: 8,
|
||||||
|
density: 1,
|
||||||
|
rb_start: 0,
|
||||||
|
l_crb: -1, /* -1 means from rb_start to the end of the bandwidth */
|
||||||
|
period: 80,
|
||||||
|
offset: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
p_zp_csi_rs_resource_set: [
|
||||||
|
{
|
||||||
|
zp_csi_rs_resources: [ 0 ],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
csi_resource_config: [
|
||||||
|
{
|
||||||
|
csi_rsc_config_id: 0,
|
||||||
|
nzp_csi_rs_resource_set_list: [ 0 ],
|
||||||
|
resource_type: "periodic",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
csi_rsc_config_id: 1,
|
||||||
|
csi_im_resource_set_list: [ 0 ],
|
||||||
|
resource_type: "periodic",
|
||||||
|
},
|
||||||
|
#ifdef USE_TRS
|
||||||
|
{
|
||||||
|
csi_rsc_config_id: 2,
|
||||||
|
nzp_csi_rs_resource_set_list: [ 1 ],
|
||||||
|
resource_type: "periodic",
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
],
|
||||||
|
csi_report_config: [
|
||||||
|
{
|
||||||
|
resources_for_channel_measurement: 0,
|
||||||
|
csi_im_resources_for_interference: 1,
|
||||||
|
report_config_type: "periodic",
|
||||||
|
period: 80,
|
||||||
|
report_quantity: "CRI_RI_PMI_CQI",
|
||||||
|
cqi_table: 2,
|
||||||
|
subband_size: "value1",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
pucch: {
|
||||||
|
pucch_group_hopping: "neither",
|
||||||
|
hopping_id: -1, /* -1 = n_cell_id */
|
||||||
|
p0_nominal: -90,
|
||||||
|
pucch1: {
|
||||||
|
n_cs: 3,
|
||||||
|
n_occ: 3,
|
||||||
|
freq_hopping: false,
|
||||||
|
},
|
||||||
|
pucch2: {
|
||||||
|
n_symb: 2,
|
||||||
|
n_prb: 1,
|
||||||
|
freq_hopping: false,
|
||||||
|
simultaneous_harq_ack_csi: false,
|
||||||
|
max_code_rate: 0.25,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
pusch: {
|
||||||
|
mapping_type: "typeA",
|
||||||
|
n_symb: 14,
|
||||||
|
dmrs_add_pos: 1,
|
||||||
|
dmrs_type: 1,
|
||||||
|
dmrs_max_len: 1,
|
||||||
|
tf_precoding: false,
|
||||||
|
mcs_table: "qam64", /* without transform precoding */
|
||||||
|
mcs_table_tp: "qam64", /* with transform precoding */
|
||||||
|
ldpc_max_its: 5,
|
||||||
|
k2: 4, /* delay in slots from DCI to PUSCH */
|
||||||
|
p0_nominal_with_grant: -90,
|
||||||
|
msg3_k2: 5,
|
||||||
|
msg3_mcs: 4,
|
||||||
|
msg3_delta_power: 0, /* in dB */
|
||||||
|
beta_offset_ack_index: 9,
|
||||||
|
|
||||||
|
/* hardcoded scheduling parameters */
|
||||||
|
n_dmrs_cdm_groups: 1,
|
||||||
|
n_layer: 1,
|
||||||
|
/* if defined, force the PUSCH MCS for all UEs. Otherwise it is
|
||||||
|
computed from the last received PUSCH. */
|
||||||
|
//mcs: 16,
|
||||||
|
//max_mcs: 16,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* MAC configuration */
|
||||||
|
mac_config: {
|
||||||
|
msg3_max_harq_tx: 5,
|
||||||
|
ul_max_harq_tx: 5, /* max number of HARQ transmissions for uplink */
|
||||||
|
dl_max_harq_tx: 5, /* max number of HARQ transmissions for downlink */
|
||||||
|
ul_max_consecutive_retx: 30, /* disconnect UE if reached */
|
||||||
|
dl_max_consecutive_retx: 30, /* disconnect UE if reached */
|
||||||
|
periodic_bsr_timer: 20,
|
||||||
|
retx_bsr_timer: 320,
|
||||||
|
periodic_phr_timer: 500,
|
||||||
|
prohibit_phr_timer: 200,
|
||||||
|
phr_tx_power_factor_change: "dB3",
|
||||||
|
sr_prohibit_timer: 0, /* in ms, 0 to disable the timer */
|
||||||
|
sr_trans_max: 64,
|
||||||
|
},
|
||||||
|
|
||||||
|
cipher_algo_pref: [${', '.join(list(dict.fromkeys(enb.cipher_list))).split("eea")[1] if len(list(dict.fromkeys(enb.cipher_list))) > 0 else ''}],
|
||||||
|
integ_algo_pref: [${', '.join(list(dict.fromkeys(enb.integrity_list))).split("eia")[1]}],
|
||||||
|
|
||||||
|
inactivity_timer: ${enb.inactivity_timer},
|
||||||
|
|
||||||
|
drb_config: "amarisoft_drb_nr.cfg",
|
||||||
|
},
|
||||||
|
% endif
|
||||||
}
|
}
|
|
@ -15,6 +15,26 @@ rf_driver: {
|
||||||
tx_gain: ${trx.tx_gain}, /* TX gain (in dB) B2x0: 0 to 89.8 dB */
|
tx_gain: ${trx.tx_gain}, /* TX gain (in dB) B2x0: 0 to 89.8 dB */
|
||||||
rx_gain: ${trx.rx_gain}, /* RX gain (in dB) B2x0: 0 to 73 dB */
|
rx_gain: ${trx.rx_gain}, /* RX gain (in dB) B2x0: 0 to 73 dB */
|
||||||
|
|
||||||
|
rf_ports: [
|
||||||
|
% if trx.rf_dev_type == 'sdr':
|
||||||
|
{
|
||||||
|
sample_rate: 23.04,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sample_rate: 61.44,
|
||||||
|
dl_freq: 3502.8, // Moves NR DL LO frequency -5.76 MHz
|
||||||
|
ul_freq: 3502.8, // Moves NR UL LO frequency -5.76 MHz
|
||||||
|
}
|
||||||
|
% else:
|
||||||
|
{
|
||||||
|
sample_rate: ${enb.sample_rate},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sample_rate: ${enb.sample_rate},
|
||||||
|
}
|
||||||
|
% endif
|
||||||
|
],
|
||||||
|
|
||||||
// only the B210 requires a sample offset
|
// only the B210 requires a sample offset
|
||||||
% if "b200" in trx.rf_dev_args:
|
% if "b200" in trx.rf_dev_args:
|
||||||
tx_time_offset: -150,
|
tx_time_offset: -150,
|
||||||
|
|
|
@ -114,6 +114,7 @@ enb:
|
||||||
duplex: fdd
|
duplex: fdd
|
||||||
transmission_mode: 1
|
transmission_mode: 1
|
||||||
num_cells: 1
|
num_cells: 1
|
||||||
|
num_nr_cells: 0
|
||||||
inactivity_timer: 20000
|
inactivity_timer: 20000
|
||||||
enable_measurements: false
|
enable_measurements: false
|
||||||
enable_dl_awgn: false
|
enable_dl_awgn: false
|
||||||
|
@ -147,6 +148,8 @@ enb:
|
||||||
root_seq_idx: 205
|
root_seq_idx: 205
|
||||||
scell_list: []
|
scell_list: []
|
||||||
ncell_list: []
|
ncell_list: []
|
||||||
|
nr_scell_list: []
|
||||||
|
nr_cell_list: []
|
||||||
cipher_list:
|
cipher_list:
|
||||||
- eea0
|
- eea0
|
||||||
- eea2
|
- eea2
|
||||||
|
|
Loading…
Reference in New Issue