This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
pespin gerrit-no-reply at lists.osmocom.orgpespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-gsm-tester/+/17842 ) Change subject: wip: websocket amarisoft ...................................................................... wip: websocket amarisoft Change-Id: I4fd30a3e37789b76bfaddc2beba1815154daab7f --- M check_dependencies.py M src/osmo_gsm_tester/obj/enb_amarisoft.py A src/osmo_gsm_tester/obj/rfemu.py A src/osmo_gsm_tester/obj/rfemu_amarisoftctrl.py A src/osmo_gsm_tester/obj/rfemu_minicircuits.py M src/osmo_gsm_tester/resource.py M src/osmo_gsm_tester/templates/amarisoft_enb.cfg.tmpl M sysmocom/defaults.conf A sysmocom/suites/4g/handover.py 9 files changed, 273 insertions(+), 24 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-tester refs/changes/42/17842/1 diff --git a/check_dependencies.py b/check_dependencies.py index c3b1d64..c983065 100755 --- a/check_dependencies.py +++ b/check_dependencies.py @@ -6,6 +6,7 @@ from inspect import getframeinfo, stack from mako.lookup import TemplateLookup from mako.template import Template +from websocket import create_connection import argparse import contextlib import copy diff --git a/src/osmo_gsm_tester/obj/enb_amarisoft.py b/src/osmo_gsm_tester/obj/enb_amarisoft.py index 1772173..3d04357 100644 --- a/src/osmo_gsm_tester/obj/enb_amarisoft.py +++ b/src/osmo_gsm_tester/obj/enb_amarisoft.py @@ -22,6 +22,7 @@ from ..core import log, util, config, template, process, remote from . import enb +from . import rfemu def rf_type_valid(rf_type_str): return rf_type_str in ('uhd', 'zmq') @@ -62,6 +63,7 @@ self.run_dir = None self.inst = None self._bin_prefix = None + self.gen_conf = None self.config_file = None self.config_sib1_file = None self.config_sib23_file = None @@ -168,6 +170,22 @@ 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 + # Convert parsed boolean string to Python boolean: self.enable_measurements = util.str2bool(values['enb'].get('enable_measurements', 'false')) config.overlay(values, dict(enb={'enable_measurements': self.enable_measurements})) @@ -211,6 +229,8 @@ config.overlay(values, dict(trx=dict(rf_dev_type=values['enb'].get('rf_dev_type', None), rf_dev_args=values['enb'].get('rf_dev_args', None)))) + self.gen_conf = values + self.gen_conf_file(self.config_file, AmarisoftENB.CFGFILE, values) self.gen_conf_file(self.config_sib1_file, AmarisoftENB.CFGFILE_SIB1, values) self.gen_conf_file(self.config_sib23_file, AmarisoftENB.CFGFILE_SIB23, values) @@ -235,4 +255,19 @@ def running(self): return not self.process.terminated() + def get_rfemu(self, cell=0, dl=True): + cell_list = self.gen_conf['enb'].get('cell_list', None) + if cell_list is None or len(cell_list) < cell + 1: + raise log.Error('cell_list attribute or subitem not found!') + rfemu_cfg = cell_list[cell].get('dl_rfemu', None) + if rfemu_cfg is None: # craft amarisfot by default: + rfemu_cfg = {'type': 'amarisoftctl', + 'addr': self.addr(), + 'port': 9001 + } + if rfemu_cfg['type'] == 'amarisoftctl': # this one requires extra config: + config.overlay(rfemu_cfg, dict(cell_id=cell_list[cell]['cell_id'])) + rfemu_obj = rfemu.get_instance_by_type(rfemu_cfg['type'], rfemu_cfg) + return rfemu_obj + # vim: expandtab tabstop=4 shiftwidth=4 diff --git a/src/osmo_gsm_tester/obj/rfemu.py b/src/osmo_gsm_tester/obj/rfemu.py new file mode 100644 index 0000000..80869bb --- /dev/null +++ b/src/osmo_gsm_tester/obj/rfemu.py @@ -0,0 +1,59 @@ +# osmo_gsm_tester: class defining a RF emulation object +# +# Copyright (C) 2020 by sysmocom - s.f.m.c. GmbH +# +# Author: Pau Espin Pedrol <pespin at 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 +from ..core.event_loop import MainLoop + +class RFemulation(log.Origin, metaclass=ABCMeta): + +############## +# PROTECTED +############## + def __init__(self, conf, name): + """Base constructor. Must be called by subclass.""" + super().__init__(log.C_RUN, name) + self.conf = conf + +############################# +# PUBLIC (test API included) +############################# + @abstractmethod + def set_attenuation(self, db): + """Set attenuation in dB on the configured channel""" + pass + + +from . import rfemu_amarisoftctrl, rfemu_minicircuits + +KNOWN_RFEMU_TYPES = { + 'amarisoftctl' : rfemu_amarisoftctrl.RFemulationAmarisoftCtrl, + 'minicircuits' : rfemu_minicircuits.RFemulationMinicircuitsHTTP, +} + +def get_instance_by_type(rfemu_type, rfemu_opt): + """Allocate a RFemulation child class based on type. Opts are passed to the newly created object.""" + obj = KNOWN_RFEMU_TYPES.get(rfemu_type, None) + if not obj: + raise log.Error('RFemulation type not supported:', rfemu_type) + return obj(rfemu_opt) + + + +# vim: expandtab tabstop=4 shiftwidth=4 diff --git a/src/osmo_gsm_tester/obj/rfemu_amarisoftctrl.py b/src/osmo_gsm_tester/obj/rfemu_amarisoftctrl.py new file mode 100644 index 0000000..1b980f1 --- /dev/null +++ b/src/osmo_gsm_tester/obj/rfemu_amarisoftctrl.py @@ -0,0 +1,61 @@ +# osmo_gsm_tester: class defining a RF emulation object implemented using Amarisoft Ctl interface +# +# Copyright (C) 2020 by sysmocom - s.f.m.c. GmbH +# +# Author: Pau Espin Pedrol <pespin at 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/>. + +import json +from websocket import create_connection + +from ..core import log +from .rfemu import RFemulation + +class RFemulationAmarisoftCtrl(RFemulation): +############## +# PROTECTED +############## + def __init__(self, conf): + super().__init__(conf, 'amarisoftctl') + self.addr = conf.get('addr') + self.port = conf.get('port') + if self.addr is None: + raise log.Error('No "addr" attribute provided in supply conf!') + if self.port is None: + raise log.Error('No "port" attribute provided in supply conf!') + self.set_name('amarisoftctl(%s:%d)' % (self.addr, self.port)) + self.cell_id = conf.get('cell_id') + if self.cell_id is None: + raise log.Error('No "cell_id" attribute provided in supply conf!') + self.ws = create_connection("ws://%s:%s" % (self.addr, self.port)) + + def __del__(self): + self.dbg('closing CTRL websocket') + self.ws.close() + +############################# +# PUBLIC (test API included) +############################# + def set_attenuation(self, db): + msg = { "message": "cell_gain", "cell_id": int(self.cell_id), "gain": -db } + msg_str = json.dumps(msg) + self.dbg('sending CTRL msg: "%s"' % msg_str) + self.ws.send(msg_str) + self.dbg('waiting CTRL recv...') + result = self.ws.recv() + self.dbg('Received CTRL msg: "%s"' % result) + + +# vim: expandtab tabstop=4 shiftwidth=4 diff --git a/src/osmo_gsm_tester/obj/rfemu_minicircuits.py b/src/osmo_gsm_tester/obj/rfemu_minicircuits.py new file mode 100644 index 0000000..896dada --- /dev/null +++ b/src/osmo_gsm_tester/obj/rfemu_minicircuits.py @@ -0,0 +1,64 @@ +# osmo_gsm_tester: class defining a RF emulation object implemented using a Minicircuits RC4DAT-6G-60 device +# +# Copyright (C) 2020 by sysmocom - s.f.m.c. GmbH +# +# Author: Pau Espin Pedrol <pespin at 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/>. + +import urllib.request +import xml.etree.ElementTree as ET + +from ..core import log +from .rfemu import RFemulation + +# https://www.minicircuits.com/softwaredownload/Prog_Manual-6-Programmable_Attenuator.pdf +class RFemulationMinicircuitsHTTP(RFemulation): + + # HTTP request timeout, in seconds + HTTP_TIMEOUT = 5 + +############## +# PROTECTED +############## + def __init__(self, conf): + super().__init__(conf, 'minicircuits') + self.addr = conf.get('addr') + self.port = conf.get('port') + if self.addr is None: + raise log.Error('No "addr" attribute provided in supply conf!') + if self.port is None: + raise log.Error('No "port" attribute provided in supply conf!') + self.set_name('minicircuits(%s:%d)' % (self.addr, self.port)) + + def _url_prefix(self): + #http://10.12.1.216/:SetAttPerChan:1:0_2:0_3:0_4:0 + return 'http://' + self.addr + + def _utl_set_attenauation(self, db): + return self._url_prefix() + '/:CHAN:' + str(port) + ':SETATT:' + str(db) + +############################# +# PUBLIC (test API included) +############################# + def set_attenuation(self, db): + url = self._utl_set_attenauation(db) + self.dbg('sending HTTP req: "%s"' % url) + data = urllib.request.urlopen(url, timeout = self.HTTP_TIMEOUT).read() + self.dbg('Received response: "%s"' % data) + #[Status] + # 0 Command failed or invalid attenuation set + # 1 Command completed successfully + +# vim: expandtab tabstop=4 shiftwidth=4 diff --git a/src/osmo_gsm_tester/resource.py b/src/osmo_gsm_tester/resource.py index 61f2b11..09b6f8e 100644 --- a/src/osmo_gsm_tester/resource.py +++ b/src/osmo_gsm_tester/resource.py @@ -90,7 +90,6 @@ 'enb[].addr': schema.IPV4, 'enb[].num_prb': schema.UINT, 'enb[].transmission_mode': schema.LTE_TRANSMISSION_MODE, - 'enb[].num_cells': schema.UINT, 'enb[].rf_dev_type': schema.STR, 'enb[].rf_dev_args': schema.STR, 'enb[].additional_args': schema.STR, @@ -107,6 +106,13 @@ 'enb[].a3_report_value': schema.INT, 'enb[].a3_hysteresis': schema.INT, 'enb[].a3_time_to_trigger': schema.INT, + 'enb[].num_cells': schema.UINT, + 'enb[].cell_list[].cell_id': schema.UINT, + 'enb[].cell_list[].scell_list[]': schema.UINT, + 'enb[].cell_list[].dl_earfcn': schema.UINT, + 'enb[].cell_list[].dl_rfemu.type': schema.STR, + 'enb[].cell_list[].dl_rfemu.addr': schema.IPV4, + 'enb[].cell_list[].dl_rfemu.port': schema.UINT, 'arfcn[].arfcn': schema.INT, 'arfcn[].band': schema.BAND, 'modem[].type': schema.STR, diff --git a/src/osmo_gsm_tester/templates/amarisoft_enb.cfg.tmpl b/src/osmo_gsm_tester/templates/amarisoft_enb.cfg.tmpl index d87e66a..5752ab8 100644 --- a/src/osmo_gsm_tester/templates/amarisoft_enb.cfg.tmpl +++ b/src/osmo_gsm_tester/templates/amarisoft_enb.cfg.tmpl @@ -55,36 +55,23 @@ /* list of cells */ cell_list: [ - { - // First cell - dl_earfcn: 2850, - rf_port: 0, - cell_id: 0x01, - n_id_cell: 1, - tac: 0x0001, - root_sequence_index: 204, /* PRACH root sequence index */ -% if enb.get('num_cells') == '2': - scell_list: [ - { cell_id: 0x02, cross_carrier_scheduling: false, scheduling_cell_id: 0x01, ul_allowed: true}, - ], -% endif - }, -% if enb.get('num_cells') == '2': +%for cell in enb.cell_list: { - // Second Cell - dl_earfcn: 3050, - rf_port: 1, - cell_id: 0x02, - n_id_cell: 2, + dl_earfcn: ${cell.dl_earfcn}, + rf_port: ${loop.index}, + cell_id: ${cell.cell_id}, + n_id_cell: ${loop.index + 1}, tac: 0x0001, - root_sequence_index: 205, + root_sequence_index: ${loop.index + 204}, /* PRACH root sequence index */ scell_list: [ - { cell_id: 0x01, cross_carrier_scheduling: false, scheduling_cell_id: 0x02, ul_allowed: true}, +%for scell_id in cell.scell_list: + { cell_id: ${scell_id}, cross_carrier_scheduling: false, scheduling_cell_id: ${cell.cell_id}, ul_allowed: true}, +%endfor ], }, -% endif +%endfor ], /* cell_list */ /* default cell parameters */ diff --git a/sysmocom/defaults.conf b/sysmocom/defaults.conf index f3994bb..bf5bce1 100644 --- a/sysmocom/defaults.conf +++ b/sysmocom/defaults.conf @@ -123,6 +123,13 @@ a3_report_value: 6 a3_hysteresis: 0 a3_time_to_trigger: 480 + cell_list: + - cell_id: 0x01 + dl_earfcn: 2850 + scell_list: [0x02] + - cell_id: 0x02 + dl_earfcn: 3050 + scell_list: [0x01] srsenb: num_prb: 100 diff --git a/sysmocom/suites/4g/handover.py b/sysmocom/suites/4g/handover.py new file mode 100755 index 0000000..3a49321 --- /dev/null +++ b/sysmocom/suites/4g/handover.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 +from osmo_gsm_tester.testenv import * + +epc = suite.epc() +enb = suite.enb() +ue = suite.modem() + +epc.subscriber_add(ue) +epc.start() +enb.ue_add(ue) +enb.start(epc) + +print('waiting for ENB to connect to EPC...') +wait(epc.enb_is_connected, enb) +print('ENB is connected to EPC') + +ue.connect(enb) +print('waiting for UE to attach...') +wait(ue.is_connected, None) +print('UE is attached') + +sleep(2) + +rfemu = enb.get_rfemu() +for att in range(1, 10, 1): + print("Setting cell attenuation %d..." % att) + rfemu.set_attenuation(att) + sleep(1) +print("Done") -- To view, visit https://gerrit.osmocom.org/c/osmo-gsm-tester/+/17842 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-gsm-tester Gerrit-Branch: master Gerrit-Change-Id: I4fd30a3e37789b76bfaddc2beba1815154daab7f Gerrit-Change-Number: 17842 Gerrit-PatchSet: 1 Gerrit-Owner: pespin <pespin at sysmocom.de> Gerrit-MessageType: newchange -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200417/73e5f1c3/attachment.htm>