osmo-gsm-tester/src/osmo_gsm_tester/obj/enb.py

332 lines
14 KiB
Python
Raw Normal View History

# 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
from ..core import log, config
from ..core import schema
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
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,
'rf_dev_sync': schema.STR,
'additional_args[]': schema.STR,
'inactivity_timer': schema.INT,
'enable_measurements': schema.BOOL_STR,
'enable_dl_awgn': schema.BOOL_STR,
'dl_awgn_snr': schema.INT,
'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,
'cell_list[].rf_port': schema.UINT,
'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,
}
for key, val in run_node.RunNode.schema().items():
resource_schema['run_node.%s' % key] = val
schema.register_resource_schema('enb', resource_schema)
class eNodeB(log.Origin, metaclass=ABCMeta):
##############
# PROTECTED
##############
def __init__(self, testenv, conf, name):
super().__init__(log.C_RUN, '%s' % name)
self._conf = conf
self._run_node = run_node.RunNode.from_conf(conf.get('run_node', {}))
self._gtp_bind_addr = conf.get('gtp_bind_addr', None)
if self._gtp_bind_addr is None:
self._gtp_bind_addr = self._run_node.run_addr()
self.set_name('%s_%s' % (name, self._run_node.run_addr()))
self._txmode = 0
self._id = None
self._num_prb = 0
self._num_cells = None
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()
def configure(self, config_specifics_li):
values = dict(enb=config.get_defaults('enb'))
for config_specifics in config_specifics_li:
config.overlay(values, dict(enb=config.get_defaults(config_specifics)))
config.overlay(values, dict(enb=self.testenv.suite().config().get('enb', {})))
for config_specifics in config_specifics_li:
config.overlay(values, dict(enb=self.testenv.suite().config().get(config_specifics, {})))
config.overlay(values, dict(enb=self._conf))
self._id = int(values['enb'].get('id', None))
assert self._id is not None
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() }))
self._inactivity_timer = int(values['enb'].get('inactivity_timer', None))
assert self._inactivity_timer
assert self._epc is not None
config.overlay(values, dict(enb={ 'addr': self.addr() }))
config.overlay(values, dict(enb={ 'mme_addr': self._epc.addr() }))
config.overlay(values, dict(enb={ 'gtp_bind_addr': self._gtp_bind_addr }))
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)
return values
def id(self):
return self._id
def num_ports(self):
if self._txmode == 1:
return 1
return 2
def num_cells(self):
return self._num_cells
########################
# 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
def num_prb(self):
return self._num_prb
#reference: srsLTE.git srslte_symbol_sz()
def num_prb2symbol_sz(self, num_prb):
if num_prb == 6:
return 128
if num_prb == 50:
return 768
if num_prb == 75:
return 1024
return 1536
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):
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']
# 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()
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
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:]
return rf_dev_args
def get_instance_by_type(testenv, conf):
"""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)
return enb_class(testenv, conf)
###################
# 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
def ue_max_rate(self, downlink=True, num_carriers=1):
pass
@abstractmethod
def get_rfemu(self, cell=0, dl=True):
'Get rfemu.RFemulation subclass implementation object for given cell index and direction.'
pass
def addr(self):
return self._run_node.run_addr()
# vim: expandtab tabstop=4 shiftwidth=4