<p>pespin <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-gsm-tester/+/20687">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Jenkins Builder: Verified
  pespin: Looks good to me, approved

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">gnuradio zmq broker refactoring<br><br>First step towards support everal ENBs and installing the remote script<br>at runtime:<br><br>* The gnuradio broker class is moved to its own file, to decouple it<br>  from RFemu.<br>* The ENBs are registered earlier in the test so that the GrBroker knows<br>  when to start (delay start + setup until all ENBs have been configured).<br>* Handle ENBs internally as a list.<br><br>Change-Id: I4f1095bbc7ed0a816fe47caef44f7becadd9d737<br>---<br>M src/osmo_gsm_tester/obj/enb.py<br>A src/osmo_gsm_tester/obj/gnuradio_zmq_broker.py<br>M src/osmo_gsm_tester/obj/rfemu_gnuradio_zmq.py<br>3 files changed, 172 insertions(+), 141 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/osmo_gsm_tester/obj/enb.py b/src/osmo_gsm_tester/obj/enb.py</span><br><span>index 906164e..3b0ae8f 100644</span><br><span>--- a/src/osmo_gsm_tester/obj/enb.py</span><br><span>+++ b/src/osmo_gsm_tester/obj/enb.py</span><br><span>@@ -21,7 +21,7 @@</span><br><span> from ..core import log, config</span><br><span> from ..core import schema</span><br><span> from . import run_node</span><br><span style="color: hsl(0, 100%, 40%);">-from .rfemu_gnuradio_zmq import GrBroker</span><br><span style="color: hsl(120, 100%, 40%);">+from .gnuradio_zmq_broker import GrBroker</span><br><span> </span><br><span> def on_register_schemas():</span><br><span>     resource_schema = {</span><br><span>@@ -91,7 +91,9 @@</span><br><span>         self._num_cells = None</span><br><span>         self._epc = None</span><br><span>         self.gen_conf = None</span><br><span style="color: hsl(0, 100%, 40%);">-        self.gr_broker = None</span><br><span style="color: hsl(120, 100%, 40%);">+        self.gr_broker = GrBroker.ref()</span><br><span style="color: hsl(120, 100%, 40%);">+        self.gr_broker.register_enb(self)</span><br><span style="color: hsl(120, 100%, 40%);">+        self._use_gr_broker = False</span><br><span> </span><br><span>     def using_grbroker(self, cfg_values):</span><br><span>         # whether we are to use Grbroker in between ENB and UE.</span><br><span>@@ -189,7 +191,8 @@</span><br><span>             enb_bind_port = resourcep.next_zmq_port_range(self, num_ports)</span><br><span>             self.assign_enb_zmq_ports(values, 'zmq_enb_bind_port', enb_bind_port)</span><br><span>             # If we are to use a GrBroker, then initialize here to have remote zmq ports available:</span><br><span style="color: hsl(0, 100%, 40%);">-            if self.using_grbroker(values):</span><br><span style="color: hsl(120, 100%, 40%);">+            self._use_gr_broker = self.using_grbroker(values)</span><br><span style="color: hsl(120, 100%, 40%);">+            if self._use_gr_broker:</span><br><span>                 zmq_enb_peer_port = resourcep.next_zmq_port_range(self, num_ports)</span><br><span>                 self.assign_enb_zmq_ports(values, 'zmq_enb_peer_port', zmq_enb_peer_port) # These are actually bound to GrBroker</span><br><span>                 self.assign_enb_zmq_ports_joined_earfcn(values, 'zmq_ue_bind_port', ue_bind_port) # This is were GrBroker binds on the UE side</span><br><span>@@ -197,8 +200,7 @@</span><br><span>                 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</span><br><span>                 # Already set gen_conf here in advance since gr_broker needs the cell list</span><br><span>                 self.gen_conf = values</span><br><span style="color: hsl(0, 100%, 40%);">-                self.gr_broker = GrBroker.ref()</span><br><span style="color: hsl(0, 100%, 40%);">-                self.gr_broker.handle_enb(self)</span><br><span style="color: hsl(120, 100%, 40%);">+                self.gr_broker.start()</span><br><span>             else:</span><br><span>                 self.assign_enb_zmq_ports(values, 'zmq_enb_peer_port', ue_bind_port)</span><br><span>                 self.assign_enb_zmq_ports(values, 'zmq_ue_bind_port', ue_bind_port) #If no broker we need to match amount of ports</span><br><span>@@ -223,6 +225,7 @@</span><br><span>     def cleanup(self):</span><br><span>         'Nothing to do by default. Subclass can override if required.'</span><br><span>         if self.gr_broker:</span><br><span style="color: hsl(120, 100%, 40%);">+            self.gr_broker.unregister_enb(self)</span><br><span>             GrBroker.unref()</span><br><span>             self.gr_broker = None</span><br><span> </span><br><span>@@ -247,7 +250,7 @@</span><br><span>     def get_zmq_rf_dev_args(self, cfg_values):</span><br><span>         base_srate = self.num_prb2base_srate(self.num_prb())</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        if self.gr_broker:</span><br><span style="color: hsl(120, 100%, 40%);">+        if self._use_gr_broker:</span><br><span>             ul_rem_addr = self.addr()</span><br><span>         else:</span><br><span>             ul_rem_addr = self.ue.addr()</span><br><span>@@ -274,7 +277,7 @@</span><br><span>         idx = 0</span><br><span>         earfcns_done = []</span><br><span>         for cell in cell_list:</span><br><span style="color: hsl(0, 100%, 40%);">-            if self.gr_broker:</span><br><span style="color: hsl(120, 100%, 40%);">+            if self._use_gr_broker:</span><br><span>                 if cell['dl_earfcn'] in earfcns_done:</span><br><span>                     continue</span><br><span>                 earfcns_done.append(cell['dl_earfcn'])</span><br><span>diff --git a/src/osmo_gsm_tester/obj/gnuradio_zmq_broker.py b/src/osmo_gsm_tester/obj/gnuradio_zmq_broker.py</span><br><span>new file mode 100644</span><br><span>index 0000000..ba43794</span><br><span>--- /dev/null</span><br><span>+++ b/src/osmo_gsm_tester/obj/gnuradio_zmq_broker.py</span><br><span>@@ -0,0 +1,161 @@</span><br><span style="color: hsl(120, 100%, 40%);">+# osmo_gsm_tester: class defining a RF emulation object implemented using SRS ENB stdin interface</span><br><span style="color: hsl(120, 100%, 40%);">+#</span><br><span style="color: hsl(120, 100%, 40%);">+# Copyright (C) 2020 by sysmocom - s.f.m.c. GmbH</span><br><span style="color: hsl(120, 100%, 40%);">+#</span><br><span style="color: hsl(120, 100%, 40%);">+# Author: Pau Espin Pedrol <pespin@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+#</span><br><span style="color: hsl(120, 100%, 40%);">+# This program is free software: you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+# it under the terms of the GNU General Public License as</span><br><span style="color: hsl(120, 100%, 40%);">+# published by the Free Software Foundation, either version 3 of the</span><br><span style="color: hsl(120, 100%, 40%);">+# License, or (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+#</span><br><span style="color: hsl(120, 100%, 40%);">+# This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+# but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+# GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+#</span><br><span style="color: hsl(120, 100%, 40%);">+# You should have received a copy of the GNU General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+# along with this program.  If not, see <http://www.gnu.org/licenses/>.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+import json</span><br><span style="color: hsl(120, 100%, 40%);">+import socket</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+from ..core import log</span><br><span style="color: hsl(120, 100%, 40%);">+from ..core import util</span><br><span style="color: hsl(120, 100%, 40%);">+from ..core import process</span><br><span style="color: hsl(120, 100%, 40%);">+from ..core import remote</span><br><span style="color: hsl(120, 100%, 40%);">+from ..core.event_loop import MainLoop</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+class GrBroker(log.Origin):</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    # static fields:</span><br><span style="color: hsl(120, 100%, 40%);">+    refcount = 0</span><br><span style="color: hsl(120, 100%, 40%);">+    instance = None</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def __init__(self):</span><br><span style="color: hsl(120, 100%, 40%);">+        super().__init__(log.C_RUN, 'gr_zmq_broker')</span><br><span style="color: hsl(120, 100%, 40%);">+        self.process = None</span><br><span style="color: hsl(120, 100%, 40%);">+        self.ctrl_port = 5005</span><br><span style="color: hsl(120, 100%, 40%);">+        self.run_dir = None</span><br><span style="color: hsl(120, 100%, 40%);">+        self.rem_host = None</span><br><span style="color: hsl(120, 100%, 40%);">+        self.enb_li = []</span><br><span style="color: hsl(120, 100%, 40%);">+        self.addr = None</span><br><span style="color: hsl(120, 100%, 40%);">+        self.ctrl_sk = None</span><br><span style="color: hsl(120, 100%, 40%);">+        self.num_enb_started = 0</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    @staticmethod</span><br><span style="color: hsl(120, 100%, 40%);">+    def ref():</span><br><span style="color: hsl(120, 100%, 40%);">+        if GrBroker.refcount == 0:</span><br><span style="color: hsl(120, 100%, 40%);">+            GrBroker.instance = GrBroker()</span><br><span style="color: hsl(120, 100%, 40%);">+        GrBroker.refcount = GrBroker.refcount + 1</span><br><span style="color: hsl(120, 100%, 40%);">+        return GrBroker.instance</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    @staticmethod</span><br><span style="color: hsl(120, 100%, 40%);">+    def unref():</span><br><span style="color: hsl(120, 100%, 40%);">+        GrBroker.refcount = GrBroker.refcount - 1</span><br><span style="color: hsl(120, 100%, 40%);">+        if GrBroker.refcount == 0:</span><br><span style="color: hsl(120, 100%, 40%);">+            GrBroker.instance.cleanup()</span><br><span style="color: hsl(120, 100%, 40%);">+            GrBroker.instance = None</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def cleanup(self):</span><br><span style="color: hsl(120, 100%, 40%);">+        if self.ctrl_sk is not None:</span><br><span style="color: hsl(120, 100%, 40%);">+            self.cmd_exit()</span><br><span style="color: hsl(120, 100%, 40%);">+            self.ctrl_sk.close()</span><br><span style="color: hsl(120, 100%, 40%);">+            self.ctrl_sk = None</span><br><span style="color: hsl(120, 100%, 40%);">+        self.enb_li = []</span><br><span style="color: hsl(120, 100%, 40%);">+        self.testenv = None</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def register_enb(self, enb):</span><br><span style="color: hsl(120, 100%, 40%);">+        self.enb_li.append(enb)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def unregister_enb(self, enb):</span><br><span style="color: hsl(120, 100%, 40%);">+        self.enb_li.remove(enb)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def gen_json_enb(self, enb):</span><br><span style="color: hsl(120, 100%, 40%);">+        res = []</span><br><span style="color: hsl(120, 100%, 40%);">+        cell_list = enb.gen_conf['enb']['cell_list']</span><br><span style="color: hsl(120, 100%, 40%);">+        for cell in cell_list:</span><br><span style="color: hsl(120, 100%, 40%);">+            # TODO: probably add enb_id, cell_id to support several ENB</span><br><span style="color: hsl(120, 100%, 40%);">+            data = {'earfcn': int(cell['dl_earfcn']),</span><br><span style="color: hsl(120, 100%, 40%);">+                    'bind_port': int(cell['zmq_enb_peer_port']),</span><br><span style="color: hsl(120, 100%, 40%);">+                    'peer_addr': enb.addr(),</span><br><span style="color: hsl(120, 100%, 40%);">+                    'peer_port': int(cell['zmq_enb_bind_port']),</span><br><span style="color: hsl(120, 100%, 40%);">+                    'use_mimo': True if enb.num_ports() > 1 else False</span><br><span style="color: hsl(120, 100%, 40%);">+                    }</span><br><span style="color: hsl(120, 100%, 40%);">+            res.append(data)</span><br><span style="color: hsl(120, 100%, 40%);">+        return res</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def gen_json_ue(self, enb):</span><br><span style="color: hsl(120, 100%, 40%);">+        res = {}</span><br><span style="color: hsl(120, 100%, 40%);">+        res = []</span><br><span style="color: hsl(120, 100%, 40%);">+        earfcns_done = []</span><br><span style="color: hsl(120, 100%, 40%);">+        cell_list = enb.gen_conf['enb']['cell_list']</span><br><span style="color: hsl(120, 100%, 40%);">+        for cell in cell_list:</span><br><span style="color: hsl(120, 100%, 40%);">+            data = {}</span><br><span style="color: hsl(120, 100%, 40%);">+            if int(cell['dl_earfcn']) in earfcns_done:</span><br><span style="color: hsl(120, 100%, 40%);">+                continue</span><br><span style="color: hsl(120, 100%, 40%);">+            earfcns_done.append(int(cell['dl_earfcn']))</span><br><span style="color: hsl(120, 100%, 40%);">+            data = {'earfcn': int(cell['dl_earfcn']),</span><br><span style="color: hsl(120, 100%, 40%);">+                    'bind_port': int(cell['zmq_ue_peer_port']),</span><br><span style="color: hsl(120, 100%, 40%);">+                    'peer_addr': enb.ue.addr(),</span><br><span style="color: hsl(120, 100%, 40%);">+                    'peer_port': int(cell['zmq_ue_bind_port']),</span><br><span style="color: hsl(120, 100%, 40%);">+                    'use_mimo': True if enb.num_ports() > 1 else False</span><br><span style="color: hsl(120, 100%, 40%);">+                    }</span><br><span style="color: hsl(120, 100%, 40%);">+            res.append(data)</span><br><span style="color: hsl(120, 100%, 40%);">+        return res</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def gen_json(self):</span><br><span style="color: hsl(120, 100%, 40%);">+        res = {'enb': [self.gen_json_enb(enb) for enb in self.enb_li],</span><br><span style="color: hsl(120, 100%, 40%);">+               'ue': [self.gen_json_ue(self.enb_li[0])]}</span><br><span style="color: hsl(120, 100%, 40%);">+        return res</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def configure(self):</span><br><span style="color: hsl(120, 100%, 40%);">+        self.addr = self.enb_li[0].addr()</span><br><span style="color: hsl(120, 100%, 40%);">+        self.testenv = self.enb_li[0].testenv</span><br><span style="color: hsl(120, 100%, 40%);">+        self.run_dir = util.Dir(self.testenv.test().get_run_dir().new_dir(self.name()))</span><br><span style="color: hsl(120, 100%, 40%);">+        if not self.enb_li[0]._run_node.is_local():</span><br><span style="color: hsl(120, 100%, 40%);">+            self.rem_host = remote.RemoteHost(self.run_dir, self.enb_li[0]._run_node.ssh_user(), self.enb_li[0]._run_node.ssh_addr())</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def start(self):</span><br><span style="color: hsl(120, 100%, 40%);">+        self.num_enb_started += 1</span><br><span style="color: hsl(120, 100%, 40%);">+        self.dbg('start(%d/%d)' % (self.num_enb_started, len(self.enb_li)))</span><br><span style="color: hsl(120, 100%, 40%);">+        if self.num_enb_started == 1:</span><br><span style="color: hsl(120, 100%, 40%);">+            self.configure()</span><br><span style="color: hsl(120, 100%, 40%);">+            args = ('osmo-gsm-tester_zmq_broker.py',</span><br><span style="color: hsl(120, 100%, 40%);">+                    '-c', str(self.ctrl_port),</span><br><span style="color: hsl(120, 100%, 40%);">+                    '-b', self.addr)</span><br><span style="color: hsl(120, 100%, 40%);">+            if self.enb_li[0]._run_node.is_local():</span><br><span style="color: hsl(120, 100%, 40%);">+                self.process = process.Process(self.name(), self.run_dir, args)</span><br><span style="color: hsl(120, 100%, 40%);">+            else:</span><br><span style="color: hsl(120, 100%, 40%);">+                self.process = self.rem_host.RemoteProcessSafeExit('zmq_gr_broker', util.Dir('/tmp/ogt_%s' % self.name()), args, wait_time_sec=7)</span><br><span style="color: hsl(120, 100%, 40%);">+            self.testenv.remember_to_stop(self.process)</span><br><span style="color: hsl(120, 100%, 40%);">+            self.process.launch()</span><br><span style="color: hsl(120, 100%, 40%);">+        # Wait until all ENBs are configured/started:</span><br><span style="color: hsl(120, 100%, 40%);">+        if self.num_enb_started == len(self.enb_li):</span><br><span style="color: hsl(120, 100%, 40%);">+            self.dbg('waiting for gr script to be available...')</span><br><span style="color: hsl(120, 100%, 40%);">+            MainLoop.sleep(5)</span><br><span style="color: hsl(120, 100%, 40%);">+            self.ctrl_sk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)</span><br><span style="color: hsl(120, 100%, 40%);">+            self.cmd_setup()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def send_cmd(self, str_buf):</span><br><span style="color: hsl(120, 100%, 40%);">+        self.dbg('sending cmd: "%s"' % str_buf)</span><br><span style="color: hsl(120, 100%, 40%);">+        self.ctrl_sk.sendto(str_buf.encode('utf-8'), (self.addr, self.ctrl_port))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def cmd_setup(self):</span><br><span style="color: hsl(120, 100%, 40%);">+        cfg = self.gen_json()</span><br><span style="color: hsl(120, 100%, 40%);">+        buf = json.dumps(cfg)</span><br><span style="color: hsl(120, 100%, 40%);">+        self.send_cmd(buf)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def cmd_set_relative_gain_on_local_port(self, port, rel_gain):</span><br><span style="color: hsl(120, 100%, 40%);">+        d = { 'action': 'set_relative_gain',</span><br><span style="color: hsl(120, 100%, 40%);">+              'port': port,</span><br><span style="color: hsl(120, 100%, 40%);">+              'rel_gain': rel_gain</span><br><span style="color: hsl(120, 100%, 40%);">+            }</span><br><span style="color: hsl(120, 100%, 40%);">+        buf = json.dumps(d)</span><br><span style="color: hsl(120, 100%, 40%);">+        self.send_cmd(buf)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def cmd_exit(self):</span><br><span style="color: hsl(120, 100%, 40%);">+        d = { 'action': 'exit' }</span><br><span style="color: hsl(120, 100%, 40%);">+        buf = json.dumps(d)</span><br><span style="color: hsl(120, 100%, 40%);">+        self.send_cmd(buf)</span><br><span>diff --git a/src/osmo_gsm_tester/obj/rfemu_gnuradio_zmq.py b/src/osmo_gsm_tester/obj/rfemu_gnuradio_zmq.py</span><br><span>index 3725760..5e3a7ac 100644</span><br><span>--- a/src/osmo_gsm_tester/obj/rfemu_gnuradio_zmq.py</span><br><span>+++ b/src/osmo_gsm_tester/obj/rfemu_gnuradio_zmq.py</span><br><span>@@ -17,142 +17,9 @@</span><br><span> # You should have received a copy of the GNU General Public License</span><br><span> # along with this program.  If not, see <http://www.gnu.org/licenses/>.</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-import json</span><br><span style="color: hsl(0, 100%, 40%);">-import socket</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> from ..core import log</span><br><span style="color: hsl(0, 100%, 40%);">-from ..core import util</span><br><span style="color: hsl(0, 100%, 40%);">-from ..core import process</span><br><span style="color: hsl(0, 100%, 40%);">-from ..core import remote</span><br><span style="color: hsl(0, 100%, 40%);">-from ..core.event_loop import MainLoop</span><br><span> from .rfemu import RFemulation</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-class GrBroker(log.Origin):</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    # static fields:</span><br><span style="color: hsl(0, 100%, 40%);">-    refcount = 0</span><br><span style="color: hsl(0, 100%, 40%);">-    instance = None</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    def __init__(self):</span><br><span style="color: hsl(0, 100%, 40%);">-        super().__init__(log.C_RUN, 'zmq_gr_broker')</span><br><span style="color: hsl(0, 100%, 40%);">-        self.process = None</span><br><span style="color: hsl(0, 100%, 40%);">-        self.ctrl_port = 5005</span><br><span style="color: hsl(0, 100%, 40%);">-        self.run_dir = None</span><br><span style="color: hsl(0, 100%, 40%);">-        self.rem_host = None</span><br><span style="color: hsl(0, 100%, 40%);">-        self.cfg = None</span><br><span style="color: hsl(0, 100%, 40%);">-        self.enb = None</span><br><span style="color: hsl(0, 100%, 40%);">-        self.addr = None</span><br><span style="color: hsl(0, 100%, 40%);">-        self.ctrl_sk = None</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    @staticmethod</span><br><span style="color: hsl(0, 100%, 40%);">-    def ref():</span><br><span style="color: hsl(0, 100%, 40%);">-        if GrBroker.refcount == 0:</span><br><span style="color: hsl(0, 100%, 40%);">-            GrBroker.instance = GrBroker()</span><br><span style="color: hsl(0, 100%, 40%);">-        GrBroker.refcount = GrBroker.refcount + 1</span><br><span style="color: hsl(0, 100%, 40%);">-        return GrBroker.instance</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    @staticmethod</span><br><span style="color: hsl(0, 100%, 40%);">-    def unref():</span><br><span style="color: hsl(0, 100%, 40%);">-        GrBroker.refcount = GrBroker.refcount - 1</span><br><span style="color: hsl(0, 100%, 40%);">-        if GrBroker.refcount == 0:</span><br><span style="color: hsl(0, 100%, 40%);">-            GrBroker.instance.cleanup()</span><br><span style="color: hsl(0, 100%, 40%);">-            GrBroker.instance = None</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    def cleanup(self):</span><br><span style="color: hsl(0, 100%, 40%);">-        if self.ctrl_sk is not None:</span><br><span style="color: hsl(0, 100%, 40%);">-            self.cmd_exit()</span><br><span style="color: hsl(0, 100%, 40%);">-            self.ctrl_sk.close()</span><br><span style="color: hsl(0, 100%, 40%);">-            self.ctrl_sk = None</span><br><span style="color: hsl(0, 100%, 40%);">-        self.enb = None</span><br><span style="color: hsl(0, 100%, 40%);">-        self.testenv = None</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    def handle_enb(self, enb):</span><br><span style="color: hsl(0, 100%, 40%);">-        self.enb = enb</span><br><span style="color: hsl(0, 100%, 40%);">-        self.addr = self.enb.addr()</span><br><span style="color: hsl(0, 100%, 40%);">-        self.testenv = self.enb.testenv</span><br><span style="color: hsl(0, 100%, 40%);">-        self.cfg = self.gen_json(enb)</span><br><span style="color: hsl(0, 100%, 40%);">-        # FIXME: we may need to delay this somehow if we want to support several ENBs</span><br><span style="color: hsl(0, 100%, 40%);">-        self.start()</span><br><span style="color: hsl(0, 100%, 40%);">-        self.setup()</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    def gen_json_enb(self, enb):</span><br><span style="color: hsl(0, 100%, 40%);">-        res = []</span><br><span style="color: hsl(0, 100%, 40%);">-        cell_list = enb.gen_conf['enb']['cell_list']</span><br><span style="color: hsl(0, 100%, 40%);">-        for cell in cell_list:</span><br><span style="color: hsl(0, 100%, 40%);">-            # TODO: probably add enb_id, cell_id to support several ENB</span><br><span style="color: hsl(0, 100%, 40%);">-            data = {'earfcn': int(cell['dl_earfcn']),</span><br><span style="color: hsl(0, 100%, 40%);">-                    'bind_port': int(cell['zmq_enb_peer_port']),</span><br><span style="color: hsl(0, 100%, 40%);">-                    'peer_addr': enb.addr(),</span><br><span style="color: hsl(0, 100%, 40%);">-                    'peer_port': int(cell['zmq_enb_bind_port']),</span><br><span style="color: hsl(0, 100%, 40%);">-                    'use_mimo': True if enb.num_ports() > 1 else False</span><br><span style="color: hsl(0, 100%, 40%);">-                    }</span><br><span style="color: hsl(0, 100%, 40%);">-            res.append(data)</span><br><span style="color: hsl(0, 100%, 40%);">-        return res</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    def gen_json_ue(self, enb):</span><br><span style="color: hsl(0, 100%, 40%);">-        res = {}</span><br><span style="color: hsl(0, 100%, 40%);">-        res = []</span><br><span style="color: hsl(0, 100%, 40%);">-        earfcns_done = []</span><br><span style="color: hsl(0, 100%, 40%);">-        cell_list = enb.gen_conf['enb']['cell_list']</span><br><span style="color: hsl(0, 100%, 40%);">-        for cell in cell_list:</span><br><span style="color: hsl(0, 100%, 40%);">-            data = {}</span><br><span style="color: hsl(0, 100%, 40%);">-            if int(cell['dl_earfcn']) in earfcns_done:</span><br><span style="color: hsl(0, 100%, 40%);">-                continue</span><br><span style="color: hsl(0, 100%, 40%);">-            earfcns_done.append(int(cell['dl_earfcn']))</span><br><span style="color: hsl(0, 100%, 40%);">-            data = {'earfcn': int(cell['dl_earfcn']),</span><br><span style="color: hsl(0, 100%, 40%);">-                    'bind_port': int(cell['zmq_ue_peer_port']),</span><br><span style="color: hsl(0, 100%, 40%);">-                    'peer_addr': enb.ue.addr(),</span><br><span style="color: hsl(0, 100%, 40%);">-                    'peer_port': int(cell['zmq_ue_bind_port']),</span><br><span style="color: hsl(0, 100%, 40%);">-                    'use_mimo': True if enb.num_ports() > 1 else False</span><br><span style="color: hsl(0, 100%, 40%);">-                    }</span><br><span style="color: hsl(0, 100%, 40%);">-            res.append(data)</span><br><span style="color: hsl(0, 100%, 40%);">-        return res</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    def gen_json(self, enb):</span><br><span style="color: hsl(0, 100%, 40%);">-        res = {'enb': [self.gen_json_enb(enb)],</span><br><span style="color: hsl(0, 100%, 40%);">-               'ue': [self.gen_json_ue(enb)]}</span><br><span style="color: hsl(0, 100%, 40%);">-        return res</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    def start(self):</span><br><span style="color: hsl(0, 100%, 40%);">-        self.run_dir = util.Dir(self.testenv.test().get_run_dir().new_dir(self.name()))</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        args = ('osmo-gsm-tester_zmq_broker.py',</span><br><span style="color: hsl(0, 100%, 40%);">-                '-c', str(self.ctrl_port),</span><br><span style="color: hsl(0, 100%, 40%);">-                '-b', self.enb.addr())</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        if self.enb._run_node.is_local():</span><br><span style="color: hsl(0, 100%, 40%);">-            self.process = process.Process(self.name(), self.run_dir, args)</span><br><span style="color: hsl(0, 100%, 40%);">-        else:</span><br><span style="color: hsl(0, 100%, 40%);">-            self.rem_host = remote.RemoteHost(self.run_dir, self.enb._run_node.ssh_user(), self.enb._run_node.ssh_addr())</span><br><span style="color: hsl(0, 100%, 40%);">-            self.process = self.rem_host.RemoteProcessSafeExit('zmq_gr_broker', util.Dir('/tmp/ogt_%s' % self.name()), args, wait_time_sec=7)</span><br><span style="color: hsl(0, 100%, 40%);">-        self.testenv.remember_to_stop(self.process)</span><br><span style="color: hsl(0, 100%, 40%);">-        self.process.launch()</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    def setup(self):</span><br><span style="color: hsl(0, 100%, 40%);">-        self.dbg('waiting for gr script to be available...')</span><br><span style="color: hsl(0, 100%, 40%);">-        MainLoop.sleep(5)</span><br><span style="color: hsl(0, 100%, 40%);">-        self.ctrl_sk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)</span><br><span style="color: hsl(0, 100%, 40%);">-        buf = json.dumps(self.cfg)</span><br><span style="color: hsl(0, 100%, 40%);">-        self.send_cmd(buf)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    def send_cmd(self, str_buf):</span><br><span style="color: hsl(0, 100%, 40%);">-        self.dbg('sending cmd: "%s"' % str_buf)</span><br><span style="color: hsl(0, 100%, 40%);">-        self.ctrl_sk.sendto(str_buf.encode('utf-8'), (self.addr, self.ctrl_port))</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    def cmd_set_relative_gain_on_local_port(self, port, rel_gain):</span><br><span style="color: hsl(0, 100%, 40%);">-        d = { 'action': 'set_relative_gain',</span><br><span style="color: hsl(0, 100%, 40%);">-              'port': port,</span><br><span style="color: hsl(0, 100%, 40%);">-              'rel_gain': rel_gain</span><br><span style="color: hsl(0, 100%, 40%);">-            }</span><br><span style="color: hsl(0, 100%, 40%);">-        buf = json.dumps(d)</span><br><span style="color: hsl(0, 100%, 40%);">-        self.send_cmd(buf)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    def cmd_exit(self):</span><br><span style="color: hsl(0, 100%, 40%);">-        d = { 'action': 'exit' }</span><br><span style="color: hsl(0, 100%, 40%);">-        buf = json.dumps(d)</span><br><span style="color: hsl(0, 100%, 40%);">-        self.send_cmd(buf)</span><br><span style="color: hsl(120, 100%, 40%);">+from .gnuradio_zmq_broker import GrBroker</span><br><span> </span><br><span> class RFemulationGnuradioZmq(RFemulation):</span><br><span> ##############</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-gsm-tester/+/20687">change 20687</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-gsm-tester/+/20687"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-gsm-tester </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I4f1095bbc7ed0a816fe47caef44f7becadd9d737 </div>
<div style="display:none"> Gerrit-Change-Number: 20687 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>