Change in osmo-gsm-tester[master]: wip: websocket amarisoft

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.org
Fri Apr 17 12:13:36 UTC 2020


pespin 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>


More information about the gerrit-log mailing list