2020-03-30 11:51:21 +00:00
|
|
|
# osmo_gsm_tester: base classes to share code among eNodeB subclasses.
|
|
|
|
#
|
|
|
|
# Copyright (C) 2020 by sysmocom - s.f.m.c. GmbH
|
|
|
|
#
|
|
|
|
# Author: Pau Espin Pedrol <pespin@sysmocom.de>
|
|
|
|
#
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as
|
|
|
|
# published by the Free Software Foundation, either version 3 of the
|
|
|
|
# License, or (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
from abc import ABCMeta, abstractmethod
|
2020-04-10 18:46:07 +00:00
|
|
|
from ..core import log, config
|
2020-05-04 10:05:05 +00:00
|
|
|
from ..core import schema
|
2020-05-26 10:32:19 +00:00
|
|
|
from . import run_node
|
4g: Introduce ZMQ GnuRadio stream broker
srsENB currently creates 1 zmq stream (1 tx, 1 rx) for each cell (2 if
MIMO is enabled). Each cell transceives on a given EARFCN (and several
cells can transmit on same EARFCN).
However, for handover test purposes, we want to join all cells operating
on the same EARFCN to transceive on the same ZMQ conn, so that an srsUE
can interact with them at the same time (same as if the medium was shared).
Furthermore, we want to set different gains on each of those paths
before merging them in order to emulate RF conditions like handover.
In order to do so, a new element called the Broker is introduced, which
is placed in between ENBs and UEs ZMQ conenctions, multiplexing the
connections on the ENB side towards the UE side.
A separate process for the broker is run remotely (ENB run host) which
listens on a ctrl socket for commands. An internal Broker class is used
in osmo-gsm-tester to interact with the remote script, for instance to
configure the ports, start and stop the remote process, send commands to
it, etc.
On each ENB, when the rfemu "gnuradio_zmq" rfemu implementation is selected
in configuration, it will configure its zmq connections and the UE ones to
go over the Broker.
As a result, that means the UE zmq port configuration is expected to be
different than when no broker is in used, since there's the multiplexing
per EARFCN in between.
In this commit, only 1 ENB is supported, but multi-enb support is
planned in the future.
The handover test passes in the docker setup with this config:
"""
OSMO_GSM_TESTER_OPTS="-T -l dbg -s 4g:srsue-rftype@zmq+srsenb-rftype@zmq+" \
"mod-enb-nprb@6+mod-enb-ncells@2+mod-enb-cells-2ca+suite-4g@10,2+" \
"mod-enb-meas-enable -t =handover.py"
"""
and in resources.conf (or scenario), added:
"""
enb:
...
cell_list:
- dl_rfemu:
type: gnuradio_zmq
- dl_rfemu:
type: gnuradio_zmq
"""
Note that since the broker is used, there's not need for mod-srsue-ncarriers@2
since the broker is joining the 2 enb cells into 1 stream on the UE side.
Change-Id: I6282cda400558dcb356276786d91e6388524c5b1
2020-10-05 17:23:38 +00:00
|
|
|
from .rfemu_gnuradio_zmq import GrBroker
|
2020-03-30 11:51:21 +00:00
|
|
|
|
2020-05-04 10:05:05 +00:00
|
|
|
def on_register_schemas():
|
|
|
|
resource_schema = {
|
|
|
|
'label': schema.STR,
|
|
|
|
'type': schema.STR,
|
|
|
|
'gtp_bind_addr': schema.IPV4,
|
|
|
|
'id': schema.UINT,
|
|
|
|
'num_prb': schema.UINT,
|
|
|
|
'transmission_mode': schema.LTE_TRANSMISSION_MODE,
|
|
|
|
'tx_gain': schema.UINT,
|
|
|
|
'rx_gain': schema.UINT,
|
|
|
|
'rf_dev_type': schema.STR,
|
|
|
|
'rf_dev_args': schema.STR,
|
2020-10-09 12:46:38 +00:00
|
|
|
'rf_dev_sync': schema.STR,
|
2020-06-15 15:01:16 +00:00
|
|
|
'additional_args[]': schema.STR,
|
2020-08-26 16:19:15 +00:00
|
|
|
'inactivity_timer': schema.INT,
|
2020-05-04 10:05:05 +00:00
|
|
|
'enable_measurements': schema.BOOL_STR,
|
2020-07-01 13:44:09 +00:00
|
|
|
'enable_dl_awgn': schema.BOOL_STR,
|
|
|
|
'dl_awgn_snr': schema.INT,
|
2020-05-04 10:05:05 +00:00
|
|
|
'a1_report_type': schema.STR,
|
|
|
|
'a1_report_value': schema.INT,
|
|
|
|
'a1_hysteresis': schema.INT,
|
|
|
|
'a1_time_to_trigger': schema.INT,
|
|
|
|
'a2_report_type': schema.STR,
|
|
|
|
'a2_report_value': schema.INT,
|
|
|
|
'a2_hysteresis': schema.INT,
|
|
|
|
'a2_time_to_trigger': schema.INT,
|
|
|
|
'a3_report_type': schema.STR,
|
|
|
|
'a3_report_value': schema.INT,
|
|
|
|
'a3_hysteresis': schema.INT,
|
|
|
|
'a3_time_to_trigger': schema.INT,
|
|
|
|
'num_cells': schema.UINT,
|
|
|
|
'cell_list[].cell_id': schema.UINT,
|
2020-04-21 19:14:30 +00:00
|
|
|
'cell_list[].rf_port': schema.UINT,
|
2020-05-04 10:05:05 +00:00
|
|
|
'cell_list[].pci': schema.UINT,
|
|
|
|
'cell_list[].ncell_list[]': schema.UINT,
|
|
|
|
'cell_list[].scell_list[]': schema.UINT,
|
|
|
|
'cell_list[].dl_earfcn': schema.UINT,
|
|
|
|
'cell_list[].dl_rfemu.type': schema.STR,
|
|
|
|
'cell_list[].dl_rfemu.addr': schema.IPV4,
|
|
|
|
'cell_list[].dl_rfemu.ports[]': schema.UINT,
|
|
|
|
}
|
2020-05-26 10:32:19 +00:00
|
|
|
for key, val in run_node.RunNode.schema().items():
|
|
|
|
resource_schema['run_node.%s' % key] = val
|
2020-05-04 10:05:05 +00:00
|
|
|
schema.register_resource_schema('enb', resource_schema)
|
2020-03-30 11:51:21 +00:00
|
|
|
|
|
|
|
class eNodeB(log.Origin, metaclass=ABCMeta):
|
|
|
|
|
|
|
|
##############
|
|
|
|
# PROTECTED
|
|
|
|
##############
|
2020-05-05 10:54:37 +00:00
|
|
|
def __init__(self, testenv, conf, name):
|
2020-03-30 11:51:21 +00:00
|
|
|
super().__init__(log.C_RUN, '%s' % name)
|
|
|
|
self._conf = conf
|
2020-05-26 10:32:19 +00:00
|
|
|
self._run_node = run_node.RunNode.from_conf(conf.get('run_node', {}))
|
2020-04-14 20:24:00 +00:00
|
|
|
self._gtp_bind_addr = conf.get('gtp_bind_addr', None)
|
|
|
|
if self._gtp_bind_addr is None:
|
2020-05-26 10:32:19 +00:00
|
|
|
self._gtp_bind_addr = self._run_node.run_addr()
|
|
|
|
self.set_name('%s_%s' % (name, self._run_node.run_addr()))
|
2020-03-31 10:35:19 +00:00
|
|
|
self._txmode = 0
|
2020-04-20 12:20:43 +00:00
|
|
|
self._id = None
|
2020-03-31 10:35:19 +00:00
|
|
|
self._num_prb = 0
|
2020-04-17 14:23:54 +00:00
|
|
|
self._num_cells = None
|
2020-03-31 10:35:19 +00:00
|
|
|
self._epc = None
|
4g: Introduce ZMQ GnuRadio stream broker
srsENB currently creates 1 zmq stream (1 tx, 1 rx) for each cell (2 if
MIMO is enabled). Each cell transceives on a given EARFCN (and several
cells can transmit on same EARFCN).
However, for handover test purposes, we want to join all cells operating
on the same EARFCN to transceive on the same ZMQ conn, so that an srsUE
can interact with them at the same time (same as if the medium was shared).
Furthermore, we want to set different gains on each of those paths
before merging them in order to emulate RF conditions like handover.
In order to do so, a new element called the Broker is introduced, which
is placed in between ENBs and UEs ZMQ conenctions, multiplexing the
connections on the ENB side towards the UE side.
A separate process for the broker is run remotely (ENB run host) which
listens on a ctrl socket for commands. An internal Broker class is used
in osmo-gsm-tester to interact with the remote script, for instance to
configure the ports, start and stop the remote process, send commands to
it, etc.
On each ENB, when the rfemu "gnuradio_zmq" rfemu implementation is selected
in configuration, it will configure its zmq connections and the UE ones to
go over the Broker.
As a result, that means the UE zmq port configuration is expected to be
different than when no broker is in used, since there's the multiplexing
per EARFCN in between.
In this commit, only 1 ENB is supported, but multi-enb support is
planned in the future.
The handover test passes in the docker setup with this config:
"""
OSMO_GSM_TESTER_OPTS="-T -l dbg -s 4g:srsue-rftype@zmq+srsenb-rftype@zmq+" \
"mod-enb-nprb@6+mod-enb-ncells@2+mod-enb-cells-2ca+suite-4g@10,2+" \
"mod-enb-meas-enable -t =handover.py"
"""
and in resources.conf (or scenario), added:
"""
enb:
...
cell_list:
- dl_rfemu:
type: gnuradio_zmq
- dl_rfemu:
type: gnuradio_zmq
"""
Note that since the broker is used, there's not need for mod-srsue-ncarriers@2
since the broker is joining the 2 enb cells into 1 stream on the UE side.
Change-Id: I6282cda400558dcb356276786d91e6388524c5b1
2020-10-05 17:23:38 +00:00
|
|
|
self.gen_conf = None
|
|
|
|
self.gr_broker = None
|
|
|
|
|
|
|
|
def using_grbroker(self, cfg_values):
|
|
|
|
# whether we are to use Grbroker in between ENB and UE.
|
|
|
|
# Initial checks:
|
|
|
|
if cfg_values['enb'].get('rf_dev_type') != 'zmq':
|
|
|
|
return False
|
|
|
|
cell_list = cfg_values['enb']['cell_list']
|
|
|
|
use_match = False
|
|
|
|
notuse_match = False
|
|
|
|
for cell in cell_list:
|
|
|
|
if cell.get('dl_rfemu', False) and cell['dl_rfemu'].get('type', None) == 'gnuradio_zmq':
|
|
|
|
use_match = True
|
|
|
|
else:
|
|
|
|
notuse_match = True
|
|
|
|
if use_match and notuse_match:
|
|
|
|
raise log.Error('Some Cells are configured to use gnuradio_zmq and some are not, unsupported')
|
|
|
|
return use_match
|
|
|
|
|
|
|
|
def calc_required_zmq_ports(self, cfg_values):
|
|
|
|
cell_list = cfg_values['enb']['cell_list']
|
|
|
|
return len(cell_list) * self.num_ports() # *2 if MIMO
|
|
|
|
|
|
|
|
def calc_required_zmq_ports_joined_earfcn(self, cfg_values):
|
|
|
|
#gr_broker will join the earfcns, so we need to count uniqe earfcns:
|
|
|
|
cell_list = cfg_values['enb']['cell_list']
|
|
|
|
earfcn_li = []
|
|
|
|
[earfcn_li.append(int(cell['dl_earfcn'])) for cell in cell_list if int(cell['dl_earfcn']) not in earfcn_li]
|
|
|
|
return len(earfcn_li) * self.num_ports() # *2 if MIMO
|
|
|
|
|
|
|
|
|
|
|
|
def assign_enb_zmq_ports(self, cfg_values, port_name, base_port):
|
|
|
|
port_offset = 0
|
|
|
|
cell_list = cfg_values['enb']['cell_list']
|
|
|
|
for cell in cell_list:
|
|
|
|
cell[port_name] = base_port + port_offset
|
|
|
|
port_offset += self.num_ports()
|
|
|
|
# TODO: do we need to assign cell_list back?
|
|
|
|
|
|
|
|
def assign_enb_zmq_ports_joined_earfcn(self, cfg_values, port_name, base_port):
|
|
|
|
# TODO: Set in cell one bind port per unique earfcn, this is where UE will connect to when we use grbroker.
|
|
|
|
cell_list = cfg_values['enb']['cell_list']
|
|
|
|
earfcn_li = []
|
|
|
|
[earfcn_li.append(int(cell['dl_earfcn'])) for cell in cell_list if int(cell['dl_earfcn']) not in earfcn_li]
|
|
|
|
for cell in cell_list:
|
|
|
|
cell[port_name] = base_port + earfcn_li.index(int(cell['dl_earfcn'])) * self.num_ports()
|
2020-03-31 10:35:19 +00:00
|
|
|
|
2020-04-01 11:55:51 +00:00
|
|
|
def configure(self, config_specifics_li):
|
2020-03-31 10:35:19 +00:00
|
|
|
values = dict(enb=config.get_defaults('enb'))
|
2020-04-01 11:55:51 +00:00
|
|
|
for config_specifics in config_specifics_li:
|
|
|
|
config.overlay(values, dict(enb=config.get_defaults(config_specifics)))
|
2020-05-05 10:54:37 +00:00
|
|
|
config.overlay(values, dict(enb=self.testenv.suite().config().get('enb', {})))
|
2020-04-01 11:55:51 +00:00
|
|
|
for config_specifics in config_specifics_li:
|
2020-05-05 10:54:37 +00:00
|
|
|
config.overlay(values, dict(enb=self.testenv.suite().config().get(config_specifics, {})))
|
2020-03-31 10:35:19 +00:00
|
|
|
config.overlay(values, dict(enb=self._conf))
|
2020-04-20 12:20:43 +00:00
|
|
|
self._id = int(values['enb'].get('id', None))
|
|
|
|
assert self._id is not None
|
2020-03-31 10:35:19 +00:00
|
|
|
self._num_prb = int(values['enb'].get('num_prb', None))
|
|
|
|
assert self._num_prb
|
|
|
|
self._txmode = int(values['enb'].get('transmission_mode', None))
|
|
|
|
assert self._txmode
|
|
|
|
config.overlay(values, dict(enb={ 'num_ports': self.num_ports() }))
|
2020-08-26 16:19:15 +00:00
|
|
|
self._inactivity_timer = int(values['enb'].get('inactivity_timer', None))
|
|
|
|
assert self._inactivity_timer
|
2020-03-31 10:35:19 +00:00
|
|
|
assert self._epc is not None
|
2020-05-26 10:32:19 +00:00
|
|
|
config.overlay(values, dict(enb={ 'addr': self.addr() }))
|
2020-03-31 10:35:19 +00:00
|
|
|
config.overlay(values, dict(enb={ 'mme_addr': self._epc.addr() }))
|
2020-04-14 20:24:00 +00:00
|
|
|
config.overlay(values, dict(enb={ 'gtp_bind_addr': self._gtp_bind_addr }))
|
2020-04-17 14:23:54 +00:00
|
|
|
self._num_cells = int(values['enb'].get('num_cells', None))
|
|
|
|
assert self._num_cells
|
|
|
|
|
|
|
|
# adjust cell_list to num_cells length:
|
|
|
|
len_cell_list = len(values['enb']['cell_list'])
|
|
|
|
if len_cell_list >= self._num_cells:
|
|
|
|
values['enb']['cell_list'] = values['enb']['cell_list'][:self._num_cells]
|
|
|
|
else:
|
|
|
|
raise log.Error('enb.cell_list items (%d) < enb.num_cells (%d) attribute!' % (len_cell_list, self._num_cells))
|
|
|
|
# adjust scell list (to only contain values available in cell_list):
|
|
|
|
cell_id_list = [c['cell_id'] for c in values['enb']['cell_list']]
|
|
|
|
for i in range(len(values['enb']['cell_list'])):
|
|
|
|
scell_list_old = values['enb']['cell_list'][i]['scell_list']
|
|
|
|
scell_list_new = []
|
|
|
|
for scell_id in scell_list_old:
|
|
|
|
if scell_id in cell_id_list:
|
|
|
|
scell_list_new.append(scell_id)
|
|
|
|
values['enb']['cell_list'][i]['scell_list'] = scell_list_new
|
|
|
|
|
4g: Introduce ZMQ GnuRadio stream broker
srsENB currently creates 1 zmq stream (1 tx, 1 rx) for each cell (2 if
MIMO is enabled). Each cell transceives on a given EARFCN (and several
cells can transmit on same EARFCN).
However, for handover test purposes, we want to join all cells operating
on the same EARFCN to transceive on the same ZMQ conn, so that an srsUE
can interact with them at the same time (same as if the medium was shared).
Furthermore, we want to set different gains on each of those paths
before merging them in order to emulate RF conditions like handover.
In order to do so, a new element called the Broker is introduced, which
is placed in between ENBs and UEs ZMQ conenctions, multiplexing the
connections on the ENB side towards the UE side.
A separate process for the broker is run remotely (ENB run host) which
listens on a ctrl socket for commands. An internal Broker class is used
in osmo-gsm-tester to interact with the remote script, for instance to
configure the ports, start and stop the remote process, send commands to
it, etc.
On each ENB, when the rfemu "gnuradio_zmq" rfemu implementation is selected
in configuration, it will configure its zmq connections and the UE ones to
go over the Broker.
As a result, that means the UE zmq port configuration is expected to be
different than when no broker is in used, since there's the multiplexing
per EARFCN in between.
In this commit, only 1 ENB is supported, but multi-enb support is
planned in the future.
The handover test passes in the docker setup with this config:
"""
OSMO_GSM_TESTER_OPTS="-T -l dbg -s 4g:srsue-rftype@zmq+srsenb-rftype@zmq+" \
"mod-enb-nprb@6+mod-enb-ncells@2+mod-enb-cells-2ca+suite-4g@10,2+" \
"mod-enb-meas-enable -t =handover.py"
"""
and in resources.conf (or scenario), added:
"""
enb:
...
cell_list:
- dl_rfemu:
type: gnuradio_zmq
- dl_rfemu:
type: gnuradio_zmq
"""
Note that since the broker is used, there's not need for mod-srsue-ncarriers@2
since the broker is joining the 2 enb cells into 1 stream on the UE side.
Change-Id: I6282cda400558dcb356276786d91e6388524c5b1
2020-10-05 17:23:38 +00:00
|
|
|
# Assign ZMQ ports to each Cell/EARFCN.
|
|
|
|
if values['enb'].get('rf_dev_type') == 'zmq':
|
|
|
|
resourcep = self.testenv.suite().resource_pool()
|
|
|
|
num_ports = self.calc_required_zmq_ports(values)
|
|
|
|
num_ports_joined_earfcn = self.calc_required_zmq_ports_joined_earfcn(values)
|
|
|
|
ue_bind_port = self.ue.zmq_base_bind_port()
|
|
|
|
enb_bind_port = resourcep.next_zmq_port_range(self, num_ports)
|
|
|
|
self.assign_enb_zmq_ports(values, 'zmq_enb_bind_port', enb_bind_port)
|
|
|
|
# If we are to use a GrBroker, then initialize here to have remote zmq ports available:
|
|
|
|
if self.using_grbroker(values):
|
|
|
|
zmq_enb_peer_port = resourcep.next_zmq_port_range(self, num_ports)
|
|
|
|
self.assign_enb_zmq_ports(values, 'zmq_enb_peer_port', zmq_enb_peer_port) # These are actually bound to GrBroker
|
|
|
|
self.assign_enb_zmq_ports_joined_earfcn(values, 'zmq_ue_bind_port', ue_bind_port) # This is were GrBroker binds on the UE side
|
|
|
|
zmq_ue_peer_port = resourcep.next_zmq_port_range(self, num_ports_joined_earfcn)
|
|
|
|
self.assign_enb_zmq_ports_joined_earfcn(values, 'zmq_ue_peer_port', zmq_ue_peer_port) # This is were GrBroker binds on the UE side
|
|
|
|
# Already set gen_conf here in advance since gr_broker needs the cell list
|
|
|
|
self.gen_conf = values
|
|
|
|
self.gr_broker = GrBroker.ref()
|
|
|
|
self.gr_broker.handle_enb(self)
|
|
|
|
else:
|
|
|
|
self.assign_enb_zmq_ports(values, 'zmq_enb_peer_port', ue_bind_port)
|
|
|
|
self.assign_enb_zmq_ports(values, 'zmq_ue_bind_port', ue_bind_port) #If no broker we need to match amount of ports
|
|
|
|
self.assign_enb_zmq_ports(values, 'zmq_ue_peer_port', enb_bind_port)
|
|
|
|
|
2020-03-31 10:35:19 +00:00
|
|
|
return values
|
|
|
|
|
2020-04-20 12:20:43 +00:00
|
|
|
def id(self):
|
|
|
|
return self._id
|
|
|
|
|
2020-03-31 10:35:19 +00:00
|
|
|
def num_ports(self):
|
|
|
|
if self._txmode == 1:
|
|
|
|
return 1
|
|
|
|
return 2
|
2020-03-30 11:51:21 +00:00
|
|
|
|
2020-06-16 14:29:27 +00:00
|
|
|
def num_cells(self):
|
|
|
|
return self._num_cells
|
|
|
|
|
2020-03-30 11:51:21 +00:00
|
|
|
########################
|
|
|
|
# PUBLIC - INTERNAL API
|
|
|
|
########################
|
|
|
|
def cleanup(self):
|
|
|
|
'Nothing to do by default. Subclass can override if required.'
|
4g: Introduce ZMQ GnuRadio stream broker
srsENB currently creates 1 zmq stream (1 tx, 1 rx) for each cell (2 if
MIMO is enabled). Each cell transceives on a given EARFCN (and several
cells can transmit on same EARFCN).
However, for handover test purposes, we want to join all cells operating
on the same EARFCN to transceive on the same ZMQ conn, so that an srsUE
can interact with them at the same time (same as if the medium was shared).
Furthermore, we want to set different gains on each of those paths
before merging them in order to emulate RF conditions like handover.
In order to do so, a new element called the Broker is introduced, which
is placed in between ENBs and UEs ZMQ conenctions, multiplexing the
connections on the ENB side towards the UE side.
A separate process for the broker is run remotely (ENB run host) which
listens on a ctrl socket for commands. An internal Broker class is used
in osmo-gsm-tester to interact with the remote script, for instance to
configure the ports, start and stop the remote process, send commands to
it, etc.
On each ENB, when the rfemu "gnuradio_zmq" rfemu implementation is selected
in configuration, it will configure its zmq connections and the UE ones to
go over the Broker.
As a result, that means the UE zmq port configuration is expected to be
different than when no broker is in used, since there's the multiplexing
per EARFCN in between.
In this commit, only 1 ENB is supported, but multi-enb support is
planned in the future.
The handover test passes in the docker setup with this config:
"""
OSMO_GSM_TESTER_OPTS="-T -l dbg -s 4g:srsue-rftype@zmq+srsenb-rftype@zmq+" \
"mod-enb-nprb@6+mod-enb-ncells@2+mod-enb-cells-2ca+suite-4g@10,2+" \
"mod-enb-meas-enable -t =handover.py"
"""
and in resources.conf (or scenario), added:
"""
enb:
...
cell_list:
- dl_rfemu:
type: gnuradio_zmq
- dl_rfemu:
type: gnuradio_zmq
"""
Note that since the broker is used, there's not need for mod-srsue-ncarriers@2
since the broker is joining the 2 enb cells into 1 stream on the UE side.
Change-Id: I6282cda400558dcb356276786d91e6388524c5b1
2020-10-05 17:23:38 +00:00
|
|
|
if self.gr_broker:
|
|
|
|
GrBroker.unref()
|
|
|
|
self.gr_broker = None
|
2020-03-30 11:51:21 +00:00
|
|
|
|
2020-03-31 10:35:19 +00:00
|
|
|
def num_prb(self):
|
|
|
|
return self._num_prb
|
|
|
|
|
2020-04-20 18:39:34 +00:00
|
|
|
#reference: srsLTE.git srslte_symbol_sz()
|
|
|
|
def num_prb2symbol_sz(self, num_prb):
|
2020-06-02 20:35:27 +00:00
|
|
|
if num_prb == 6:
|
2020-04-20 18:39:34 +00:00
|
|
|
return 128
|
2020-06-02 20:35:27 +00:00
|
|
|
if num_prb == 50:
|
2020-04-20 18:39:34 +00:00
|
|
|
return 768
|
2020-06-02 20:35:27 +00:00
|
|
|
if num_prb == 75:
|
2020-04-20 18:39:34 +00:00
|
|
|
return 1024
|
2020-06-02 20:35:27 +00:00
|
|
|
return 1536
|
|
|
|
|
2020-04-20 18:39:34 +00:00
|
|
|
raise log.Error('invalid num_prb %r', num_prb)
|
|
|
|
|
|
|
|
def num_prb2base_srate(self, num_prb):
|
|
|
|
return self.num_prb2symbol_sz(num_prb) * 15 * 1000
|
|
|
|
|
4g: Introduce ZMQ GnuRadio stream broker
srsENB currently creates 1 zmq stream (1 tx, 1 rx) for each cell (2 if
MIMO is enabled). Each cell transceives on a given EARFCN (and several
cells can transmit on same EARFCN).
However, for handover test purposes, we want to join all cells operating
on the same EARFCN to transceive on the same ZMQ conn, so that an srsUE
can interact with them at the same time (same as if the medium was shared).
Furthermore, we want to set different gains on each of those paths
before merging them in order to emulate RF conditions like handover.
In order to do so, a new element called the Broker is introduced, which
is placed in between ENBs and UEs ZMQ conenctions, multiplexing the
connections on the ENB side towards the UE side.
A separate process for the broker is run remotely (ENB run host) which
listens on a ctrl socket for commands. An internal Broker class is used
in osmo-gsm-tester to interact with the remote script, for instance to
configure the ports, start and stop the remote process, send commands to
it, etc.
On each ENB, when the rfemu "gnuradio_zmq" rfemu implementation is selected
in configuration, it will configure its zmq connections and the UE ones to
go over the Broker.
As a result, that means the UE zmq port configuration is expected to be
different than when no broker is in used, since there's the multiplexing
per EARFCN in between.
In this commit, only 1 ENB is supported, but multi-enb support is
planned in the future.
The handover test passes in the docker setup with this config:
"""
OSMO_GSM_TESTER_OPTS="-T -l dbg -s 4g:srsue-rftype@zmq+srsenb-rftype@zmq+" \
"mod-enb-nprb@6+mod-enb-ncells@2+mod-enb-cells-2ca+suite-4g@10,2+" \
"mod-enb-meas-enable -t =handover.py"
"""
and in resources.conf (or scenario), added:
"""
enb:
...
cell_list:
- dl_rfemu:
type: gnuradio_zmq
- dl_rfemu:
type: gnuradio_zmq
"""
Note that since the broker is used, there's not need for mod-srsue-ncarriers@2
since the broker is joining the 2 enb cells into 1 stream on the UE side.
Change-Id: I6282cda400558dcb356276786d91e6388524c5b1
2020-10-05 17:23:38 +00:00
|
|
|
def get_zmq_rf_dev_args(self, cfg_values):
|
2020-04-20 18:39:34 +00:00
|
|
|
base_srate = self.num_prb2base_srate(self.num_prb())
|
4g: Introduce ZMQ GnuRadio stream broker
srsENB currently creates 1 zmq stream (1 tx, 1 rx) for each cell (2 if
MIMO is enabled). Each cell transceives on a given EARFCN (and several
cells can transmit on same EARFCN).
However, for handover test purposes, we want to join all cells operating
on the same EARFCN to transceive on the same ZMQ conn, so that an srsUE
can interact with them at the same time (same as if the medium was shared).
Furthermore, we want to set different gains on each of those paths
before merging them in order to emulate RF conditions like handover.
In order to do so, a new element called the Broker is introduced, which
is placed in between ENBs and UEs ZMQ conenctions, multiplexing the
connections on the ENB side towards the UE side.
A separate process for the broker is run remotely (ENB run host) which
listens on a ctrl socket for commands. An internal Broker class is used
in osmo-gsm-tester to interact with the remote script, for instance to
configure the ports, start and stop the remote process, send commands to
it, etc.
On each ENB, when the rfemu "gnuradio_zmq" rfemu implementation is selected
in configuration, it will configure its zmq connections and the UE ones to
go over the Broker.
As a result, that means the UE zmq port configuration is expected to be
different than when no broker is in used, since there's the multiplexing
per EARFCN in between.
In this commit, only 1 ENB is supported, but multi-enb support is
planned in the future.
The handover test passes in the docker setup with this config:
"""
OSMO_GSM_TESTER_OPTS="-T -l dbg -s 4g:srsue-rftype@zmq+srsenb-rftype@zmq+" \
"mod-enb-nprb@6+mod-enb-ncells@2+mod-enb-cells-2ca+suite-4g@10,2+" \
"mod-enb-meas-enable -t =handover.py"
"""
and in resources.conf (or scenario), added:
"""
enb:
...
cell_list:
- dl_rfemu:
type: gnuradio_zmq
- dl_rfemu:
type: gnuradio_zmq
"""
Note that since the broker is used, there's not need for mod-srsue-ncarriers@2
since the broker is joining the 2 enb cells into 1 stream on the UE side.
Change-Id: I6282cda400558dcb356276786d91e6388524c5b1
2020-10-05 17:23:38 +00:00
|
|
|
|
|
|
|
if self.gr_broker:
|
|
|
|
ul_rem_addr = self.addr()
|
|
|
|
else:
|
|
|
|
ul_rem_addr = self.ue.addr()
|
|
|
|
|
|
|
|
rf_dev_args = 'fail_on_disconnect=true'
|
|
|
|
idx = 0
|
|
|
|
cell_list = cfg_values['enb']['cell_list']
|
2020-04-20 18:39:34 +00:00
|
|
|
# Define all 8 possible RF ports (2x CA with 2x2 MIMO)
|
4g: Introduce ZMQ GnuRadio stream broker
srsENB currently creates 1 zmq stream (1 tx, 1 rx) for each cell (2 if
MIMO is enabled). Each cell transceives on a given EARFCN (and several
cells can transmit on same EARFCN).
However, for handover test purposes, we want to join all cells operating
on the same EARFCN to transceive on the same ZMQ conn, so that an srsUE
can interact with them at the same time (same as if the medium was shared).
Furthermore, we want to set different gains on each of those paths
before merging them in order to emulate RF conditions like handover.
In order to do so, a new element called the Broker is introduced, which
is placed in between ENBs and UEs ZMQ conenctions, multiplexing the
connections on the ENB side towards the UE side.
A separate process for the broker is run remotely (ENB run host) which
listens on a ctrl socket for commands. An internal Broker class is used
in osmo-gsm-tester to interact with the remote script, for instance to
configure the ports, start and stop the remote process, send commands to
it, etc.
On each ENB, when the rfemu "gnuradio_zmq" rfemu implementation is selected
in configuration, it will configure its zmq connections and the UE ones to
go over the Broker.
As a result, that means the UE zmq port configuration is expected to be
different than when no broker is in used, since there's the multiplexing
per EARFCN in between.
In this commit, only 1 ENB is supported, but multi-enb support is
planned in the future.
The handover test passes in the docker setup with this config:
"""
OSMO_GSM_TESTER_OPTS="-T -l dbg -s 4g:srsue-rftype@zmq+srsenb-rftype@zmq+" \
"mod-enb-nprb@6+mod-enb-ncells@2+mod-enb-cells-2ca+suite-4g@10,2+" \
"mod-enb-meas-enable -t =handover.py"
"""
and in resources.conf (or scenario), added:
"""
enb:
...
cell_list:
- dl_rfemu:
type: gnuradio_zmq
- dl_rfemu:
type: gnuradio_zmq
"""
Note that since the broker is used, there's not need for mod-srsue-ncarriers@2
since the broker is joining the 2 enb cells into 1 stream on the UE side.
Change-Id: I6282cda400558dcb356276786d91e6388524c5b1
2020-10-05 17:23:38 +00:00
|
|
|
for cell in cell_list:
|
|
|
|
rf_dev_args += ',tx_port%u=tcp://%s:%u' %(idx, self.addr(), cell['zmq_enb_bind_port'] + 0)
|
|
|
|
if self.num_ports() > 1:
|
|
|
|
rf_dev_args += ',tx_port%u=tcp://%s:%u' %(idx + 1, self.addr(), cell['zmq_enb_bind_port'] + 1)
|
|
|
|
rf_dev_args += ',rx_port%u=tcp://%s:%u' %(idx, ul_rem_addr, cell['zmq_enb_peer_port'] + 0)
|
|
|
|
if self.num_ports() > 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()
|
2020-04-20 18:39:34 +00:00
|
|
|
|
|
|
|
rf_dev_args += ',id=enb,base_srate=' + str(base_srate)
|
4g: Introduce ZMQ GnuRadio stream broker
srsENB currently creates 1 zmq stream (1 tx, 1 rx) for each cell (2 if
MIMO is enabled). Each cell transceives on a given EARFCN (and several
cells can transmit on same EARFCN).
However, for handover test purposes, we want to join all cells operating
on the same EARFCN to transceive on the same ZMQ conn, so that an srsUE
can interact with them at the same time (same as if the medium was shared).
Furthermore, we want to set different gains on each of those paths
before merging them in order to emulate RF conditions like handover.
In order to do so, a new element called the Broker is introduced, which
is placed in between ENBs and UEs ZMQ conenctions, multiplexing the
connections on the ENB side towards the UE side.
A separate process for the broker is run remotely (ENB run host) which
listens on a ctrl socket for commands. An internal Broker class is used
in osmo-gsm-tester to interact with the remote script, for instance to
configure the ports, start and stop the remote process, send commands to
it, etc.
On each ENB, when the rfemu "gnuradio_zmq" rfemu implementation is selected
in configuration, it will configure its zmq connections and the UE ones to
go over the Broker.
As a result, that means the UE zmq port configuration is expected to be
different than when no broker is in used, since there's the multiplexing
per EARFCN in between.
In this commit, only 1 ENB is supported, but multi-enb support is
planned in the future.
The handover test passes in the docker setup with this config:
"""
OSMO_GSM_TESTER_OPTS="-T -l dbg -s 4g:srsue-rftype@zmq+srsenb-rftype@zmq+" \
"mod-enb-nprb@6+mod-enb-ncells@2+mod-enb-cells-2ca+suite-4g@10,2+" \
"mod-enb-meas-enable -t =handover.py"
"""
and in resources.conf (or scenario), added:
"""
enb:
...
cell_list:
- dl_rfemu:
type: gnuradio_zmq
- dl_rfemu:
type: gnuradio_zmq
"""
Note that since the broker is used, there's not need for mod-srsue-ncarriers@2
since the broker is joining the 2 enb cells into 1 stream on the UE side.
Change-Id: I6282cda400558dcb356276786d91e6388524c5b1
2020-10-05 17:23:38 +00:00
|
|
|
return rf_dev_args
|
2020-04-20 18:39:34 +00:00
|
|
|
|
4g: Introduce ZMQ GnuRadio stream broker
srsENB currently creates 1 zmq stream (1 tx, 1 rx) for each cell (2 if
MIMO is enabled). Each cell transceives on a given EARFCN (and several
cells can transmit on same EARFCN).
However, for handover test purposes, we want to join all cells operating
on the same EARFCN to transceive on the same ZMQ conn, so that an srsUE
can interact with them at the same time (same as if the medium was shared).
Furthermore, we want to set different gains on each of those paths
before merging them in order to emulate RF conditions like handover.
In order to do so, a new element called the Broker is introduced, which
is placed in between ENBs and UEs ZMQ conenctions, multiplexing the
connections on the ENB side towards the UE side.
A separate process for the broker is run remotely (ENB run host) which
listens on a ctrl socket for commands. An internal Broker class is used
in osmo-gsm-tester to interact with the remote script, for instance to
configure the ports, start and stop the remote process, send commands to
it, etc.
On each ENB, when the rfemu "gnuradio_zmq" rfemu implementation is selected
in configuration, it will configure its zmq connections and the UE ones to
go over the Broker.
As a result, that means the UE zmq port configuration is expected to be
different than when no broker is in used, since there's the multiplexing
per EARFCN in between.
In this commit, only 1 ENB is supported, but multi-enb support is
planned in the future.
The handover test passes in the docker setup with this config:
"""
OSMO_GSM_TESTER_OPTS="-T -l dbg -s 4g:srsue-rftype@zmq+srsenb-rftype@zmq+" \
"mod-enb-nprb@6+mod-enb-ncells@2+mod-enb-cells-2ca+suite-4g@10,2+" \
"mod-enb-meas-enable -t =handover.py"
"""
and in resources.conf (or scenario), added:
"""
enb:
...
cell_list:
- dl_rfemu:
type: gnuradio_zmq
- dl_rfemu:
type: gnuradio_zmq
"""
Note that since the broker is used, there's not need for mod-srsue-ncarriers@2
since the broker is joining the 2 enb cells into 1 stream on the UE side.
Change-Id: I6282cda400558dcb356276786d91e6388524c5b1
2020-10-05 17:23:38 +00:00
|
|
|
def get_zmq_rf_dev_args_for_ue(self, ue):
|
|
|
|
cell_list = self.gen_conf['enb']['cell_list']
|
|
|
|
rf_dev_args = ''
|
|
|
|
idx = 0
|
|
|
|
earfcns_done = []
|
|
|
|
for cell in cell_list:
|
|
|
|
if self.gr_broker:
|
|
|
|
if cell['dl_earfcn'] in earfcns_done:
|
|
|
|
continue
|
|
|
|
earfcns_done.append(cell['dl_earfcn'])
|
|
|
|
rf_dev_args += ',tx_port%u=tcp://%s:%u' %(idx, ue.addr(), cell['zmq_ue_bind_port'] + 0)
|
|
|
|
if self.num_ports() > 1:
|
|
|
|
rf_dev_args += ',tx_port%u=tcp://%s:%u' %(idx + 1, ue.addr(), cell['zmq_ue_bind_port'] + 1)
|
|
|
|
rf_dev_args += ',rx_port%u=tcp://%s:%u' %(idx, self.addr(), cell['zmq_ue_peer_port'] + 0)
|
|
|
|
if self.num_ports() > 1:
|
|
|
|
rf_dev_args += ',rx_port%u=tcp://%s:%u' %(idx + 1, self.addr(), cell['zmq_ue_peer_port'] + 1)
|
|
|
|
idx += self.num_ports()
|
|
|
|
# remove trailing comma:
|
|
|
|
if rf_dev_args[0] == ',':
|
|
|
|
return rf_dev_args[1:]
|
2020-04-20 18:39:34 +00:00
|
|
|
return rf_dev_args
|
|
|
|
|
2020-05-05 10:54:37 +00:00
|
|
|
def get_instance_by_type(testenv, conf):
|
2020-05-04 15:16:39 +00:00
|
|
|
"""Allocate a ENB child class based on type. Opts are passed to the newly created object."""
|
|
|
|
enb_type = conf.get('type')
|
|
|
|
if enb_type is None:
|
|
|
|
raise RuntimeError('ENB type is not defined!')
|
|
|
|
|
|
|
|
if enb_type == 'amarisoftenb':
|
|
|
|
from .enb_amarisoft import AmarisoftENB
|
|
|
|
enb_class = AmarisoftENB
|
|
|
|
elif enb_type == 'srsenb':
|
|
|
|
from .enb_srs import srsENB
|
|
|
|
enb_class = srsENB
|
|
|
|
else:
|
|
|
|
raise log.Error('ENB type not supported:', enb_type)
|
2020-05-05 10:54:37 +00:00
|
|
|
return enb_class(testenv, conf)
|
2020-05-04 15:16:39 +00:00
|
|
|
|
2020-03-30 11:51:21 +00:00
|
|
|
###################
|
|
|
|
# PUBLIC (test API included)
|
|
|
|
###################
|
|
|
|
@abstractmethod
|
|
|
|
def start(self, epc):
|
|
|
|
'Starts ENB, it will connect to "epc"'
|
|
|
|
pass
|
|
|
|
|
|
|
|
@abstractmethod
|
|
|
|
def ue_add(self, ue):
|
|
|
|
pass
|
|
|
|
|
|
|
|
@abstractmethod
|
|
|
|
def running(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
@abstractmethod
|
2020-09-02 20:17:54 +00:00
|
|
|
def ue_max_rate(self, downlink=True, num_carriers=1):
|
2020-03-30 11:51:21 +00:00
|
|
|
pass
|
|
|
|
|
2020-04-20 11:29:31 +00:00
|
|
|
@abstractmethod
|
|
|
|
def get_rfemu(self, cell=0, dl=True):
|
|
|
|
'Get rfemu.RFemulation subclass implementation object for given cell index and direction.'
|
|
|
|
pass
|
|
|
|
|
2020-03-30 11:51:21 +00:00
|
|
|
def addr(self):
|
2020-05-26 10:32:19 +00:00
|
|
|
return self._run_node.run_addr()
|
2020-03-30 11:51:21 +00:00
|
|
|
|
|
|
|
# vim: expandtab tabstop=4 shiftwidth=4
|