<p>fixeria <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmocom-bb/+/24018">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Jenkins Builder: Verified
  laforge: Looks good to me, but someone else must approve
  pespin: Looks good to me, approved

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">trx_toolkit: use RxMsg/TxMsg instead of TRX2L1/L12TRX<br><br>I intentionally do not use 'Downlink' and 'Uplink' terms in this project<br>because both MS and BTS transmit and receive on the opposite directions.<br>A burst coming from demodulator may be a Downlink or an Uplink burst<br>depending on the context, so we definitely need more precise terms.<br><br>Back then when I started to work on TRX toolkit, I decided to use the<br>'TRX2L1' and 'L12TRX' for receive and transmit directions respectively.<br>Now I find them hard to read, so let's replace them with 'Rx' and 'Tx'.<br><br>Change-Id: I688f24a3c09dd7e1cc00b5530ec26c8e8cfd8f7c<br>Related: OS#4006, SYS#4895<br>---<br>M src/target/trx_toolkit/burst_fwd.py<br>M src/target/trx_toolkit/burst_gen.py<br>M src/target/trx_toolkit/burst_send.py<br>M src/target/trx_toolkit/ctrl_if_trx.py<br>M src/target/trx_toolkit/data_dump.py<br>M src/target/trx_toolkit/data_if.py<br>M src/target/trx_toolkit/data_msg.py<br>M src/target/trx_toolkit/fake_trx.py<br>M src/target/trx_toolkit/test_data_dump.py<br>M src/target/trx_toolkit/test_data_msg.py<br>M src/target/trx_toolkit/transceiver.py<br>M src/target/trx_toolkit/trx_sniff.py<br>12 files changed, 117 insertions(+), 121 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/target/trx_toolkit/burst_fwd.py b/src/target/trx_toolkit/burst_fwd.py</span><br><span>index 0b69fe2..2e9e97b 100644</span><br><span>--- a/src/target/trx_toolkit/burst_fwd.py</span><br><span>+++ b/src/target/trx_toolkit/burst_fwd.py</span><br><span>@@ -37,8 +37,8 @@</span><br><span>      - actual RX / TX frequencies,</span><br><span>        - list of active timeslots.</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       Each to be distributed L12TRX message is being transformed</span><br><span style="color: hsl(0, 100%, 40%);">-      into a TRX2L1 message, and then forwarded to transceivers</span><br><span style="color: hsl(120, 100%, 40%);">+     Each to be distributed 'TxMsg' message is being transformed</span><br><span style="color: hsl(120, 100%, 40%);">+   into a 'RxMsg' message, and then forwarded to transceivers</span><br><span>   with partially initialized header. All uninitialized header</span><br><span>  fields (such as rssi and toa256) shall be set by each</span><br><span>        transceiver individually before sending towards the L1.</span><br><span>@@ -69,6 +69,6 @@</span><br><span>                  if trx.get_rx_freq(rx_msg.fn) != tx_freq:</span><br><span>                            continue</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                    # Transform from L12TRX to TRX2L1 and forward</span><br><span style="color: hsl(0, 100%, 40%);">-                   tx_msg = rx_msg.gen_trx2l1(ver = trx.data_if._hdr_ver)</span><br><span style="color: hsl(120, 100%, 40%);">+                        # Transform from TxMsg to RxMsg and forward</span><br><span style="color: hsl(120, 100%, 40%);">+                   tx_msg = rx_msg.trans(ver = trx.data_if._hdr_ver)</span><br><span>                    trx.handle_data_msg(src_trx, rx_msg, tx_msg)</span><br><span>diff --git a/src/target/trx_toolkit/burst_gen.py b/src/target/trx_toolkit/burst_gen.py</span><br><span>index 7f154b3..f93d868 100755</span><br><span>--- a/src/target/trx_toolkit/burst_gen.py</span><br><span>+++ b/src/target/trx_toolkit/burst_gen.py</span><br><span>@@ -68,9 +68,9 @@</span><br><span> </span><br><span>                # Init an empty DATA message</span><br><span>                 if self.argv.conn_mode == "TRX":</span><br><span style="color: hsl(0, 100%, 40%);">-                      msg = DATAMSG_L12TRX(ver = self.argv.hdr_ver)</span><br><span style="color: hsl(120, 100%, 40%);">+                 msg = TxMsg(ver = self.argv.hdr_ver)</span><br><span>                 elif self.argv.conn_mode == "L1":</span><br><span style="color: hsl(0, 100%, 40%);">-                     msg = DATAMSG_TRX2L1(ver = self.argv.hdr_ver)</span><br><span style="color: hsl(120, 100%, 40%);">+                 msg = RxMsg(ver = self.argv.hdr_ver)</span><br><span> </span><br><span>             # Generate a random frame number or use provided one</span><br><span>                 fn_init = msg.rand_fn() if self.argv.tdma_fn is None \</span><br><span>@@ -176,7 +176,7 @@</span><br><span>                         help = "How many bursts to send (default %(default)s)")</span><br><span>            bg_group.add_argument("-v", "--hdr-version", metavar = "VER",</span><br><span>                  dest = "hdr_ver", type = int,</span><br><span style="color: hsl(0, 100%, 40%);">-                 default = 0, choices = DATAMSG.KNOWN_VERSIONS,</span><br><span style="color: hsl(120, 100%, 40%);">+                        default = 0, choices = Msg.KNOWN_VERSIONS,</span><br><span>                   help = "TRXD header version (default %(default)s)")</span><br><span>                bg_group.add_argument("-f", "--frame-number", metavar = "FN",</span><br><span>                  dest = "tdma_fn", type = int,</span><br><span>diff --git a/src/target/trx_toolkit/burst_send.py b/src/target/trx_toolkit/burst_send.py</span><br><span>index 717414d..4e16571 100755</span><br><span>--- a/src/target/trx_toolkit/burst_send.py</span><br><span>+++ b/src/target/trx_toolkit/burst_send.py</span><br><span>@@ -79,11 +79,10 @@</span><br><span> </span><br><span>       def msg_pass_filter(self, msg):</span><br><span>              # Direction filter</span><br><span style="color: hsl(0, 100%, 40%);">-              l12trx = self.argv.conn_mode == "TRX"</span><br><span style="color: hsl(0, 100%, 40%);">-         if isinstance(msg, DATAMSG_L12TRX) and not l12trx:</span><br><span style="color: hsl(0, 100%, 40%);">-                      return False</span><br><span style="color: hsl(0, 100%, 40%);">-            elif isinstance(msg, DATAMSG_TRX2L1) and l12trx:</span><br><span style="color: hsl(0, 100%, 40%);">-                        return False</span><br><span style="color: hsl(120, 100%, 40%);">+          if isinstance(msg, RxMsg) and self.argv.conn_mode == "TRX":</span><br><span style="color: hsl(120, 100%, 40%);">+                 return False # cannot send RxMsg to TRX</span><br><span style="color: hsl(120, 100%, 40%);">+               if isinstance(msg, TxMsg) and self.argv.conn_mode == "L1":</span><br><span style="color: hsl(120, 100%, 40%);">+                  return False # cannot send TxMsg to L1</span><br><span> </span><br><span>           # Timeslot filter</span><br><span>            if self.argv.pf_tn is not None:</span><br><span>diff --git a/src/target/trx_toolkit/ctrl_if_trx.py b/src/target/trx_toolkit/ctrl_if_trx.py</span><br><span>index 22d4b4e..c03dcc6 100644</span><br><span>--- a/src/target/trx_toolkit/ctrl_if_trx.py</span><br><span>+++ b/src/target/trx_toolkit/ctrl_if_trx.py</span><br><span>@@ -25,7 +25,7 @@</span><br><span> import logging as log</span><br><span> </span><br><span> from ctrl_if import CTRLInterface</span><br><span style="color: hsl(0, 100%, 40%);">-from data_msg import DATAMSG</span><br><span style="color: hsl(120, 100%, 40%);">+from data_msg import Msg</span><br><span> </span><br><span> class CTRLInterfaceTRX(CTRLInterface):</span><br><span>   """ CTRL interface handler for common transceiver management commands.</span><br><span>@@ -222,7 +222,7 @@</span><br><span>                  # ... and store current for logging</span><br><span>                  ver_cur = self.trx.data_if._hdr_ver</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                 if ver_req < 0 or ver_req > DATAMSG.CHDR_VERSION_MAX:</span><br><span style="color: hsl(120, 100%, 40%);">+                   if ver_req < 0 or ver_req > Msg.CHDR_VERSION_MAX:</span><br><span>                              log.error("(%s) Incorrect TRXD header version %u"</span><br><span>                                  % (self.trx, ver_req))</span><br><span>                               return -1</span><br><span>diff --git a/src/target/trx_toolkit/data_dump.py b/src/target/trx_toolkit/data_dump.py</span><br><span>index 9a68556..8510e2d 100644</span><br><span>--- a/src/target/trx_toolkit/data_dump.py</span><br><span>+++ b/src/target/trx_toolkit/data_dump.py</span><br><span>@@ -28,18 +28,18 @@</span><br><span> </span><br><span> class DATADump:</span><br><span>      # Constants</span><br><span style="color: hsl(0, 100%, 40%);">-     TAG_L12TRX = b'\x01'</span><br><span style="color: hsl(0, 100%, 40%);">-    TAG_TRX2L1 = b'\x02'</span><br><span style="color: hsl(120, 100%, 40%);">+  TAG_TxMsg = b'\x01'</span><br><span style="color: hsl(120, 100%, 40%);">+   TAG_RxMsg = b'\x02'</span><br><span>  HDR_LENGTH = 3</span><br><span> </span><br><span>   # Generates raw bytes from a DATA message</span><br><span>    # Return value: raw message bytes</span><br><span>    def dump_msg(self, msg):</span><br><span>             # Determine a message type</span><br><span style="color: hsl(0, 100%, 40%);">-              if isinstance(msg, DATAMSG_L12TRX):</span><br><span style="color: hsl(0, 100%, 40%);">-                     tag = self.TAG_L12TRX</span><br><span style="color: hsl(0, 100%, 40%);">-           elif isinstance(msg, DATAMSG_TRX2L1):</span><br><span style="color: hsl(0, 100%, 40%);">-                   tag = self.TAG_TRX2L1</span><br><span style="color: hsl(120, 100%, 40%);">+         if isinstance(msg, TxMsg):</span><br><span style="color: hsl(120, 100%, 40%);">+                    tag = self.TAG_TxMsg</span><br><span style="color: hsl(120, 100%, 40%);">+          elif isinstance(msg, RxMsg):</span><br><span style="color: hsl(120, 100%, 40%);">+                  tag = self.TAG_RxMsg</span><br><span>                 else:</span><br><span>                        raise ValueError("Unknown message type")</span><br><span> </span><br><span>@@ -61,12 +61,10 @@</span><br><span>                 tag = hdr[:1]</span><br><span> </span><br><span>            # Check if tag is known</span><br><span style="color: hsl(0, 100%, 40%);">-         if tag == self.TAG_L12TRX:</span><br><span style="color: hsl(0, 100%, 40%);">-                      # L1 -> TRX</span><br><span style="color: hsl(0, 100%, 40%);">-                  msg = DATAMSG_L12TRX()</span><br><span style="color: hsl(0, 100%, 40%);">-          elif tag == self.TAG_TRX2L1:</span><br><span style="color: hsl(0, 100%, 40%);">-                    # TRX -> L1</span><br><span style="color: hsl(0, 100%, 40%);">-                  msg = DATAMSG_TRX2L1()</span><br><span style="color: hsl(120, 100%, 40%);">+                if tag == self.TAG_TxMsg:</span><br><span style="color: hsl(120, 100%, 40%);">+                     msg = TxMsg()</span><br><span style="color: hsl(120, 100%, 40%);">+         elif tag == self.TAG_RxMsg:</span><br><span style="color: hsl(120, 100%, 40%);">+                   msg = RxMsg()</span><br><span>                else:</span><br><span>                        # Unknown tag</span><br><span>                        return False</span><br><span>diff --git a/src/target/trx_toolkit/data_if.py b/src/target/trx_toolkit/data_if.py</span><br><span>index 07f3d32..1cded9b 100644</span><br><span>--- a/src/target/trx_toolkit/data_if.py</span><br><span>+++ b/src/target/trx_toolkit/data_if.py</span><br><span>@@ -35,7 +35,7 @@</span><br><span>            log.debug("Init TRXD interface (%s)" % self.desc_link())</span><br><span> </span><br><span>       def set_hdr_ver(self, ver):</span><br><span style="color: hsl(0, 100%, 40%);">-             if not ver in DATAMSG.KNOWN_VERSIONS:</span><br><span style="color: hsl(120, 100%, 40%);">+         if not ver in Msg.KNOWN_VERSIONS:</span><br><span>                    return False</span><br><span> </span><br><span>             self._hdr_ver = ver</span><br><span>@@ -43,7 +43,7 @@</span><br><span> </span><br><span>  def pick_hdr_ver(self, ver_req):</span><br><span>             # Pick a version that is lower or equal to ver_req</span><br><span style="color: hsl(0, 100%, 40%);">-              for ver in DATAMSG.KNOWN_VERSIONS[::-1]:</span><br><span style="color: hsl(120, 100%, 40%);">+              for ver in Msg.KNOWN_VERSIONS[::-1]:</span><br><span>                         if ver <= ver_req:</span><br><span>                                return ver</span><br><span> </span><br><span>@@ -64,16 +64,16 @@</span><br><span>                 data, _ = self.sock.recvfrom(512)</span><br><span>            return data</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- def recv_l12trx_msg(self):</span><br><span style="color: hsl(120, 100%, 40%);">+    def recv_tx_msg(self):</span><br><span>               # Read raw data from socket</span><br><span>          data = self.recv_raw_data()</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-         # Attempt to parse as a L12TRX message</span><br><span style="color: hsl(120, 100%, 40%);">+                # Attempt to parse a TRXD Tx message</span><br><span>                 try:</span><br><span style="color: hsl(0, 100%, 40%);">-                    msg = DATAMSG_L12TRX()</span><br><span style="color: hsl(120, 100%, 40%);">+                        msg = TxMsg()</span><br><span>                        msg.parse_msg(bytearray(data))</span><br><span>               except:</span><br><span style="color: hsl(0, 100%, 40%);">-                 log.error("Failed to parse a L12TRX message "</span><br><span style="color: hsl(120, 100%, 40%);">+                       log.error("Failed to parse a TRXD Tx message "</span><br><span>                             "from R:%s:%u" % (self.remote_addr, self.remote_port))</span><br><span>                     return None</span><br><span> </span><br><span>@@ -84,16 +84,16 @@</span><br><span> </span><br><span>            return msg</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  def recv_trx2l1_msg(self):</span><br><span style="color: hsl(120, 100%, 40%);">+    def recv_rx_msg(self):</span><br><span>               # Read raw data from socket</span><br><span>          data = self.recv_raw_data()</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-         # Attempt to parse as a L12TRX message</span><br><span style="color: hsl(120, 100%, 40%);">+                # Attempt to parse a TRXD Rx message</span><br><span>                 try:</span><br><span style="color: hsl(0, 100%, 40%);">-                    msg = DATAMSG_TRX2L1()</span><br><span style="color: hsl(120, 100%, 40%);">+                        msg = RxMsg()</span><br><span>                        msg.parse_msg(bytearray(data))</span><br><span>               except:</span><br><span style="color: hsl(0, 100%, 40%);">-                 log.error("Failed to parse a TRX2L1 message "</span><br><span style="color: hsl(120, 100%, 40%);">+                       log.error("Failed to parse a TRXD Rx message "</span><br><span>                             "from R:%s:%u" % (self.remote_addr, self.remote_port))</span><br><span>                     return None</span><br><span> </span><br><span>@@ -106,10 +106,10 @@</span><br><span> </span><br><span>  def send_msg(self, msg, legacy = False):</span><br><span>             try:</span><br><span style="color: hsl(0, 100%, 40%);">-                    # Validate and encode TRXD message</span><br><span style="color: hsl(120, 100%, 40%);">+                    # Validate and encode a TRXD message</span><br><span>                         payload = msg.gen_msg(legacy)</span><br><span>                except ValueError as e:</span><br><span style="color: hsl(0, 100%, 40%);">-                 log.error("Failed to encode a TRX2L1 message ('%s') "</span><br><span style="color: hsl(120, 100%, 40%);">+                       log.error("Failed to encode a TRXD message ('%s') "</span><br><span>                                "due to error: %s" % (msg.desc_hdr(), e))</span><br><span>                  # TODO: we may want to send a NOPE.ind here</span><br><span>                  return</span><br><span>diff --git a/src/target/trx_toolkit/data_msg.py b/src/target/trx_toolkit/data_msg.py</span><br><span>index a1410fc..72e248d 100644</span><br><span>--- a/src/target/trx_toolkit/data_msg.py</span><br><span>+++ b/src/target/trx_toolkit/data_msg.py</span><br><span>@@ -59,7 +59,7 @@</span><br><span>                              return mod</span><br><span>           return None</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-class DATAMSG(abc.ABC):</span><br><span style="color: hsl(120, 100%, 40%);">+class Msg(abc.ABC):</span><br><span>  ''' TRXD (DATA) message coding API (common part). '''</span><br><span> </span><br><span>    # NOTE: up to 16 versions can be encoded</span><br><span>@@ -228,8 +228,8 @@</span><br><span>               else:</span><br><span>                        self.burst = None</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-class DATAMSG_L12TRX(DATAMSG):</span><br><span style="color: hsl(0, 100%, 40%);">-     ''' L12TRX (L1 -> TRX) message coding API. '''</span><br><span style="color: hsl(120, 100%, 40%);">+class TxMsg(Msg):</span><br><span style="color: hsl(120, 100%, 40%);">+  ''' Tx (L1 -> TRX) message coding API. '''</span><br><span> </span><br><span>    # Constants</span><br><span>  PWR_MIN = 0x00</span><br><span>@@ -257,7 +257,7 @@</span><br><span>                 ''' Validate the message fields (throws ValueError). '''</span><br><span> </span><br><span>                 # Validate common fields</span><br><span style="color: hsl(0, 100%, 40%);">-                DATAMSG.validate(self)</span><br><span style="color: hsl(120, 100%, 40%);">+                Msg.validate(self)</span><br><span> </span><br><span>               if self.pwr is None:</span><br><span>                         raise ValueError("Tx Attenuation level is not set")</span><br><span>@@ -287,14 +287,14 @@</span><br><span>        def rand_hdr(self):</span><br><span>          ''' Randomize message specific header. '''</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-          DATAMSG.rand_hdr(self)</span><br><span style="color: hsl(120, 100%, 40%);">+                Msg.rand_hdr(self)</span><br><span>           self.pwr = self.rand_pwr()</span><br><span> </span><br><span>       def desc_hdr(self):</span><br><span>          ''' Generate human-readable header description. '''</span><br><span> </span><br><span>              # Describe the common part</span><br><span style="color: hsl(0, 100%, 40%);">-              result = DATAMSG.desc_hdr(self)</span><br><span style="color: hsl(120, 100%, 40%);">+               result = Msg.desc_hdr(self)</span><br><span> </span><br><span>              if self.pwr is not None:</span><br><span>                     result += ("pwr=%u " % self.pwr)</span><br><span>@@ -340,11 +340,11 @@</span><br><span>           ''' Generate a random message specific burst. '''</span><br><span>            self.burst = [random.randint(0, 1) for _ in range(length)]</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  def gen_trx2l1(self, ver = None):</span><br><span style="color: hsl(0, 100%, 40%);">-               ''' Transform this message to TRX2L1 message. '''</span><br><span style="color: hsl(120, 100%, 40%);">+     def trans(self, ver = None):</span><br><span style="color: hsl(120, 100%, 40%);">+          ''' Transform this message into RxMsg. '''</span><br><span> </span><br><span>               # Allocate a new message</span><br><span style="color: hsl(0, 100%, 40%);">-                msg = DATAMSG_TRX2L1(fn = self.fn, tn = self.tn,</span><br><span style="color: hsl(120, 100%, 40%);">+              msg = RxMsg(fn = self.fn, tn = self.tn,</span><br><span>                      ver = self.ver if ver is None else ver)</span><br><span> </span><br><span>          # Convert burst bits</span><br><span>@@ -355,8 +355,8 @@</span><br><span> </span><br><span>               return msg</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-class DATAMSG_TRX2L1(DATAMSG):</span><br><span style="color: hsl(0, 100%, 40%);">-    ''' TRX2L1 (TRX -> L1) message coding API. '''</span><br><span style="color: hsl(120, 100%, 40%);">+class RxMsg(Msg):</span><br><span style="color: hsl(120, 100%, 40%);">+  ''' Rx (TRX -> L1) message coding API. '''</span><br><span> </span><br><span>    # rxlev2dbm(0..63) gives us [-110..-47], plus -10 dbm for noise</span><br><span>      RSSI_MIN = -120</span><br><span>@@ -442,7 +442,7 @@</span><br><span>                ''' Validate the message header fields (throws ValueError). '''</span><br><span> </span><br><span>          # Validate common fields</span><br><span style="color: hsl(0, 100%, 40%);">-                DATAMSG.validate(self)</span><br><span style="color: hsl(120, 100%, 40%);">+                Msg.validate(self)</span><br><span> </span><br><span>               if self.rssi is None:</span><br><span>                        raise ValueError("RSSI is not set")</span><br><span>@@ -512,7 +512,7 @@</span><br><span>  def rand_hdr(self):</span><br><span>          ''' Randomize message specific header. '''</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-          DATAMSG.rand_hdr(self)</span><br><span style="color: hsl(120, 100%, 40%);">+                Msg.rand_hdr(self)</span><br><span>           self.rssi = self.rand_rssi()</span><br><span>                 self.toa256 = self.rand_toa256()</span><br><span> </span><br><span>@@ -531,7 +531,7 @@</span><br><span>           ''' Generate human-readable header description. '''</span><br><span> </span><br><span>              # Describe the common part</span><br><span style="color: hsl(0, 100%, 40%);">-              result = DATAMSG.desc_hdr(self)</span><br><span style="color: hsl(120, 100%, 40%);">+               result = Msg.desc_hdr(self)</span><br><span> </span><br><span>              if self.rssi is not None:</span><br><span>                    result += ("rssi=%d " % self.rssi)</span><br><span>@@ -679,11 +679,11 @@</span><br><span> </span><br><span>             self.burst = [random.randint(-127, 127) for _ in range(length)]</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     def gen_l12trx(self, ver = None):</span><br><span style="color: hsl(0, 100%, 40%);">-               ''' Transform this message to L12TRX message. '''</span><br><span style="color: hsl(120, 100%, 40%);">+     def trans(self, ver = None):</span><br><span style="color: hsl(120, 100%, 40%);">+          ''' Transform this message to TxMsg. '''</span><br><span> </span><br><span>                 # Allocate a new message</span><br><span style="color: hsl(0, 100%, 40%);">-                msg = DATAMSG_L12TRX(fn = self.fn, tn = self.tn,</span><br><span style="color: hsl(120, 100%, 40%);">+              msg = TxMsg(fn = self.fn, tn = self.tn,</span><br><span>                      ver = self.ver if ver is None else ver)</span><br><span> </span><br><span>          # Convert burst bits</span><br><span>diff --git a/src/target/trx_toolkit/fake_trx.py b/src/target/trx_toolkit/fake_trx.py</span><br><span>index 88417f7..d519a9a 100755</span><br><span>--- a/src/target/trx_toolkit/fake_trx.py</span><br><span>+++ b/src/target/trx_toolkit/fake_trx.py</span><br><span>@@ -213,7 +213,7 @@</span><br><span>                      msg.tsc_set = 0</span><br><span>                      msg.tsc = 0</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- # Takes (partially initialized) TRX2L1 message,</span><br><span style="color: hsl(120, 100%, 40%);">+       # Takes (partially initialized) TRXD Rx message,</span><br><span>     # simulates RF path parameters (such as RSSI),</span><br><span>       # and sends towards the L1</span><br><span>   def handle_data_msg(self, src_trx, src_msg, msg):</span><br><span>diff --git a/src/target/trx_toolkit/test_data_dump.py b/src/target/trx_toolkit/test_data_dump.py</span><br><span>index 9cd9b79..f7b4fde 100644</span><br><span>--- a/src/target/trx_toolkit/test_data_dump.py</span><br><span>+++ b/src/target/trx_toolkit/test_data_dump.py</span><br><span>@@ -50,12 +50,12 @@</span><br><span>                 # Burst bits (if present)</span><br><span>            self.assertEqual(a.burst, b.burst)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-          # TRX2L1 specific fields</span><br><span style="color: hsl(0, 100%, 40%);">-                if isinstance(a, DATAMSG_L12TRX):</span><br><span style="color: hsl(120, 100%, 40%);">+             # TxMsg specific fields</span><br><span style="color: hsl(120, 100%, 40%);">+               if isinstance(a, TxMsg):</span><br><span>                     self.assertEqual(a.pwr, b.pwr)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-              # L12TRX specific fields</span><br><span style="color: hsl(0, 100%, 40%);">-                if isinstance(a, DATAMSG_TRX2L1):</span><br><span style="color: hsl(120, 100%, 40%);">+             # RxMsg specific fields</span><br><span style="color: hsl(120, 100%, 40%);">+               if isinstance(a, RxMsg):</span><br><span>                     # Version independent fields</span><br><span>                         self.assertEqual(a.toa256, b.toa256)</span><br><span>                         self.assertEqual(a.rssi, b.rssi)</span><br><span>@@ -88,8 +88,8 @@</span><br><span>         # Generate a mixed list of random messages</span><br><span>   def _gen_rand_message_mix(self, count, ver = 1):</span><br><span>             msg_list = []</span><br><span style="color: hsl(0, 100%, 40%);">-           msg_list += self._gen_rand_messages(DATAMSG_TRX2L1, count)</span><br><span style="color: hsl(0, 100%, 40%);">-              msg_list += self._gen_rand_messages(DATAMSG_L12TRX, count)</span><br><span style="color: hsl(120, 100%, 40%);">+            msg_list += self._gen_rand_messages(RxMsg, count)</span><br><span style="color: hsl(120, 100%, 40%);">+             msg_list += self._gen_rand_messages(TxMsg, count)</span><br><span>            random.shuffle(msg_list)</span><br><span>             return msg_list</span><br><span> </span><br><span>@@ -100,15 +100,15 @@</span><br><span>          msg = self._ddf.parse_msg(0)</span><br><span>                 self._compare_msg(msg, msg_ref)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     # Store one TRX2L1 message in a file, read it back and compare</span><br><span style="color: hsl(0, 100%, 40%);">-  def test_store_and_parse_trx2l1(self):</span><br><span style="color: hsl(0, 100%, 40%);">-          self._test_store_and_parse(DATAMSG_TRX2L1)</span><br><span style="color: hsl(120, 100%, 40%);">+    # Store one Rx message in a file, read it back and compare</span><br><span style="color: hsl(120, 100%, 40%);">+    def test_store_and_parse_rx_msg(self):</span><br><span style="color: hsl(120, 100%, 40%);">+                self._test_store_and_parse(RxMsg)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   # Store one L12TRX message in a file, read it back and compare</span><br><span style="color: hsl(0, 100%, 40%);">-  def test_store_and_parse_l12trx(self):</span><br><span style="color: hsl(0, 100%, 40%);">-          self._test_store_and_parse(DATAMSG_L12TRX)</span><br><span style="color: hsl(120, 100%, 40%);">+    # Store one Tx message in a file, read it back and compare</span><br><span style="color: hsl(120, 100%, 40%);">+    def test_store_and_parse_tx_msg(self):</span><br><span style="color: hsl(120, 100%, 40%);">+                self._test_store_and_parse(TxMsg)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   # Store multiple TRX2L1/L12TRX messages in a file, read them back and compare</span><br><span style="color: hsl(120, 100%, 40%);">+ # Store multiple Rx/Tx messages in a file, read them back and compare</span><br><span>        def test_store_and_parse_all(self):</span><br><span>          # Store a mixed list of random messages (19 + 19)</span><br><span>            msg_list_ref = self._gen_rand_message_mix(19)</span><br><span>@@ -143,7 +143,7 @@</span><br><span> </span><br><span>      def test_parse_len_overflow(self):</span><br><span>           # Write a malformed message directly</span><br><span style="color: hsl(0, 100%, 40%);">-            self._tf.write(DATADump.TAG_L12TRX)</span><br><span style="color: hsl(120, 100%, 40%);">+           self._tf.write(DATADump.TAG_TxMsg)</span><br><span>           self._tf.write(b'\x00\x63') # 99</span><br><span>             self._tf.write(b'\xff' * 90)</span><br><span> </span><br><span>diff --git a/src/target/trx_toolkit/test_data_msg.py b/src/target/trx_toolkit/test_data_msg.py</span><br><span>index 991dd25..24fda67 100644</span><br><span>--- a/src/target/trx_toolkit/test_data_msg.py</span><br><span>+++ b/src/target/trx_toolkit/test_data_msg.py</span><br><span>@@ -24,9 +24,9 @@</span><br><span> </span><br><span> import unittest</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-from data_msg import DATAMSG, DATAMSG_L12TRX, DATAMSG_TRX2L1</span><br><span style="color: hsl(120, 100%, 40%);">+from data_msg import Msg, TxMsg, RxMsg</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-class DATAMSG_Test(unittest.TestCase):</span><br><span style="color: hsl(120, 100%, 40%);">+class Msg_Test(unittest.TestCase):</span><br><span>   # Compare message a with message b</span><br><span>   def _compare_msg(self, a, b):</span><br><span>                # Make sure we're comparing messages of the same type</span><br><span>@@ -40,12 +40,12 @@</span><br><span>              # Burst bits (if present)</span><br><span>            self.assertEqual(a.burst, b.burst)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-          # TRX2L1 specific fields</span><br><span style="color: hsl(0, 100%, 40%);">-                if isinstance(a, DATAMSG_L12TRX):</span><br><span style="color: hsl(120, 100%, 40%);">+             # TxMsg specific fields</span><br><span style="color: hsl(120, 100%, 40%);">+               if isinstance(a, TxMsg):</span><br><span>                     self.assertEqual(a.pwr, b.pwr)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-              # L12TRX specific fields</span><br><span style="color: hsl(0, 100%, 40%);">-                if isinstance(a, DATAMSG_TRX2L1):</span><br><span style="color: hsl(120, 100%, 40%);">+             # RxMsg specific fields</span><br><span style="color: hsl(120, 100%, 40%);">+               if isinstance(a, RxMsg):</span><br><span>                     # Version independent fields</span><br><span>                         self.assertEqual(a.toa256, b.toa256)</span><br><span>                         self.assertEqual(a.rssi, b.rssi)</span><br><span>@@ -62,38 +62,38 @@</span><br><span>       def test_validate(self):</span><br><span>             # Unknown version</span><br><span>            with self.assertRaises(ValueError):</span><br><span style="color: hsl(0, 100%, 40%);">-                     msg = DATAMSG_TRX2L1(fn = 0, tn = 0, ver = 100)</span><br><span style="color: hsl(120, 100%, 40%);">+                       msg = RxMsg(fn = 0, tn = 0, ver = 100)</span><br><span>                       msg.validate()</span><br><span> </span><br><span>           # Uninitialized field</span><br><span>                with self.assertRaises(ValueError):</span><br><span style="color: hsl(0, 100%, 40%);">-                     msg = DATAMSG_TRX2L1()</span><br><span style="color: hsl(120, 100%, 40%);">+                        msg = RxMsg()</span><br><span>                        msg.validate()</span><br><span>               with self.assertRaises(ValueError):</span><br><span style="color: hsl(0, 100%, 40%);">-                     msg = DATAMSG_TRX2L1(fn = None, tn = 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                       msg = RxMsg(fn = None, tn = 0)</span><br><span>                       msg.validate()</span><br><span> </span><br><span>           # Out-of-range value(s)</span><br><span>              with self.assertRaises(ValueError):</span><br><span style="color: hsl(0, 100%, 40%);">-                     msg = DATAMSG_TRX2L1(fn = -1, tn = 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                 msg = RxMsg(fn = -1, tn = 0)</span><br><span>                         msg.validate()</span><br><span>               with self.assertRaises(ValueError):</span><br><span style="color: hsl(0, 100%, 40%);">-                     msg = DATAMSG_TRX2L1(fn = 0, tn = 10)</span><br><span style="color: hsl(120, 100%, 40%);">+                 msg = RxMsg(fn = 0, tn = 10)</span><br><span>                         msg.validate()</span><br><span> </span><br><span>   # Validate header and burst randomization</span><br><span>    def test_rand_hdr_burst(self):</span><br><span style="color: hsl(0, 100%, 40%);">-          msg_l12trx = DATAMSG_L12TRX()</span><br><span style="color: hsl(0, 100%, 40%);">-           msg_trx2l1 = DATAMSG_TRX2L1()</span><br><span style="color: hsl(120, 100%, 40%);">+         tx_msg = TxMsg()</span><br><span style="color: hsl(120, 100%, 40%);">+              rx_msg = RxMsg()</span><br><span> </span><br><span>                 for i in range(100):</span><br><span style="color: hsl(0, 100%, 40%);">-                    msg_l12trx.rand_burst()</span><br><span style="color: hsl(0, 100%, 40%);">-                 msg_trx2l1.rand_burst()</span><br><span style="color: hsl(0, 100%, 40%);">-                 msg_l12trx.rand_hdr()</span><br><span style="color: hsl(0, 100%, 40%);">-                   msg_trx2l1.rand_hdr()</span><br><span style="color: hsl(120, 100%, 40%);">+                 tx_msg.rand_burst()</span><br><span style="color: hsl(120, 100%, 40%);">+                   rx_msg.rand_burst()</span><br><span style="color: hsl(120, 100%, 40%);">+                   tx_msg.rand_hdr()</span><br><span style="color: hsl(120, 100%, 40%);">+                     rx_msg.rand_hdr()</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                   msg_l12trx.validate()</span><br><span style="color: hsl(0, 100%, 40%);">-                   msg_trx2l1.validate()</span><br><span style="color: hsl(120, 100%, 40%);">+                 tx_msg.validate()</span><br><span style="color: hsl(120, 100%, 40%);">+                     rx_msg.validate()</span><br><span> </span><br><span>        def _test_enc_dec(self, msg, legacy = False, nope_ind = False):</span><br><span>              # Prepare a given message (randomize)</span><br><span>@@ -120,22 +120,22 @@</span><br><span> </span><br><span>    # Validate encoding and decoding</span><br><span>     def test_enc_dec(self):</span><br><span style="color: hsl(0, 100%, 40%);">-         for ver in DATAMSG.KNOWN_VERSIONS:</span><br><span style="color: hsl(0, 100%, 40%);">-                      with self.subTest("L1 -> TRX message", ver = ver):</span><br><span style="color: hsl(0, 100%, 40%);">-                         msg = DATAMSG_L12TRX(ver = ver)</span><br><span style="color: hsl(120, 100%, 40%);">+               for ver in Msg.KNOWN_VERSIONS:</span><br><span style="color: hsl(120, 100%, 40%);">+                        with self.subTest("TxMsg", ver = ver):</span><br><span style="color: hsl(120, 100%, 40%);">+                              msg = TxMsg(ver = ver)</span><br><span>                               self._test_enc_dec(msg)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                     with self.subTest("TRX -> L1 message", ver = ver):</span><br><span style="color: hsl(0, 100%, 40%);">-                         msg = DATAMSG_TRX2L1(ver = ver)</span><br><span style="color: hsl(120, 100%, 40%);">+                       with self.subTest("RxMsg", ver = ver):</span><br><span style="color: hsl(120, 100%, 40%);">+                              msg = RxMsg(ver = ver)</span><br><span>                               self._test_enc_dec(msg)</span><br><span> </span><br><span>                  if ver >= 1:</span><br><span style="color: hsl(0, 100%, 40%);">-                         with self.subTest("TRX -> L1 NOPE.ind", ver = ver):</span><br><span style="color: hsl(0, 100%, 40%);">-                                        msg = DATAMSG_TRX2L1(ver = ver)</span><br><span style="color: hsl(120, 100%, 40%);">+                               with self.subTest("RxMsg NOPE.ind", ver = ver):</span><br><span style="color: hsl(120, 100%, 40%);">+                                     msg = RxMsg(ver = ver)</span><br><span>                                       self._test_enc_dec(msg, nope_ind = True)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-            with self.subTest("TRX -> L1 message (legacy)"):</span><br><span style="color: hsl(0, 100%, 40%);">-                   msg = DATAMSG_TRX2L1(ver = 0)</span><br><span style="color: hsl(120, 100%, 40%);">+         with self.subTest("RxMsg (legacy transceiver)"):</span><br><span style="color: hsl(120, 100%, 40%);">+                    msg = RxMsg(ver = 0)</span><br><span>                         self._test_enc_dec(msg, legacy = True)</span><br><span> </span><br><span>   # Validate bit conversations</span><br><span>@@ -144,16 +144,16 @@</span><br><span>                 sbits_ref = list(range(-127, 128))</span><br><span> </span><br><span>               # Test both usbit2sbit() and sbit2usbit()</span><br><span style="color: hsl(0, 100%, 40%);">-               sbits = DATAMSG.usbit2sbit(usbits_ref)</span><br><span style="color: hsl(0, 100%, 40%);">-          usbits = DATAMSG.sbit2usbit(sbits)</span><br><span style="color: hsl(120, 100%, 40%);">+            sbits = Msg.usbit2sbit(usbits_ref)</span><br><span style="color: hsl(120, 100%, 40%);">+            usbits = Msg.sbit2usbit(sbits)</span><br><span>               self.assertEqual(usbits[:255], usbits_ref[:255])</span><br><span>             self.assertEqual(usbits[255], 254)</span><br><span> </span><br><span>               # Test both sbit2ubit() and ubit2sbit()</span><br><span style="color: hsl(0, 100%, 40%);">-         ubits = DATAMSG.sbit2ubit(sbits_ref)</span><br><span style="color: hsl(120, 100%, 40%);">+          ubits = Msg.sbit2ubit(sbits_ref)</span><br><span>             self.assertEqual(ubits, ([1] * 127 + [0] * 128))</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-            sbits = DATAMSG.ubit2sbit(ubits)</span><br><span style="color: hsl(120, 100%, 40%);">+              sbits = Msg.ubit2sbit(ubits)</span><br><span>                 self.assertEqual(sbits, ([-127] * 127 + [127] * 128))</span><br><span> </span><br><span>    def _test_transform(self, msg):</span><br><span>@@ -162,31 +162,31 @@</span><br><span>              msg.rand_burst()</span><br><span> </span><br><span>                 # Perform message transformation</span><br><span style="color: hsl(0, 100%, 40%);">-                if isinstance(msg, DATAMSG_L12TRX):</span><br><span style="color: hsl(0, 100%, 40%);">-                     msg_trans = msg.gen_trx2l1()</span><br><span style="color: hsl(120, 100%, 40%);">+          if isinstance(msg, TxMsg):</span><br><span style="color: hsl(120, 100%, 40%);">+                    msg_trans = msg.trans()</span><br><span>              else:</span><br><span style="color: hsl(0, 100%, 40%);">-                   msg_trans = msg.gen_l12trx()</span><br><span style="color: hsl(120, 100%, 40%);">+                  msg_trans = msg.trans()</span><br><span> </span><br><span>          self.assertEqual(msg_trans.ver, msg.ver)</span><br><span>             self.assertEqual(msg_trans.fn, msg.fn)</span><br><span>               self.assertEqual(msg_trans.tn, msg.tn)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-              if isinstance(msg, DATAMSG_TRX2L1):</span><br><span style="color: hsl(0, 100%, 40%);">-                     burst = DATAMSG.sbit2ubit(msg.burst)</span><br><span style="color: hsl(120, 100%, 40%);">+          if isinstance(msg, RxMsg):</span><br><span style="color: hsl(120, 100%, 40%);">+                    burst = Msg.sbit2ubit(msg.burst)</span><br><span>                     self.assertEqual(msg_trans.burst, burst)</span><br><span>             else:</span><br><span style="color: hsl(0, 100%, 40%);">-                   burst = DATAMSG.ubit2sbit(msg.burst)</span><br><span style="color: hsl(120, 100%, 40%);">+                  burst = Msg.ubit2sbit(msg.burst)</span><br><span>                     self.assertEqual(msg_trans.burst, burst)</span><br><span> </span><br><span>         # Validate message transformation</span><br><span>    def test_transform(self):</span><br><span style="color: hsl(0, 100%, 40%);">-               for ver in DATAMSG.KNOWN_VERSIONS:</span><br><span style="color: hsl(0, 100%, 40%);">-                      with self.subTest("L1 -> TRX message", ver = ver):</span><br><span style="color: hsl(0, 100%, 40%);">-                         msg = DATAMSG_L12TRX(ver = ver)</span><br><span style="color: hsl(120, 100%, 40%);">+               for ver in Msg.KNOWN_VERSIONS:</span><br><span style="color: hsl(120, 100%, 40%);">+                        with self.subTest("TxMsg", ver = ver):</span><br><span style="color: hsl(120, 100%, 40%);">+                              msg = TxMsg(ver = ver)</span><br><span>                               self._test_transform(msg)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                   with self.subTest("TRX -> L1 message", ver = ver):</span><br><span style="color: hsl(0, 100%, 40%);">-                         msg = DATAMSG_TRX2L1(ver = ver)</span><br><span style="color: hsl(120, 100%, 40%);">+                       with self.subTest("RxMsg", ver = ver):</span><br><span style="color: hsl(120, 100%, 40%);">+                              msg = RxMsg(ver = ver)</span><br><span>                               self._test_transform(msg)</span><br><span> </span><br><span> if __name__ == '__main__':</span><br><span>diff --git a/src/target/trx_toolkit/transceiver.py b/src/target/trx_toolkit/transceiver.py</span><br><span>index 19b998e..d041070 100644</span><br><span>--- a/src/target/trx_toolkit/transceiver.py</span><br><span>+++ b/src/target/trx_toolkit/transceiver.py</span><br><span>@@ -258,7 +258,7 @@</span><br><span> </span><br><span>       def recv_data_msg(self):</span><br><span>             # Read and parse data from socket</span><br><span style="color: hsl(0, 100%, 40%);">-               msg = self.data_if.recv_l12trx_msg()</span><br><span style="color: hsl(120, 100%, 40%);">+          msg = self.data_if.recv_tx_msg()</span><br><span>             if not msg:</span><br><span>                  return None</span><br><span> </span><br><span>diff --git a/src/target/trx_toolkit/trx_sniff.py b/src/target/trx_toolkit/trx_sniff.py</span><br><span>index 0cb62d3..8b6f80c 100755</span><br><span>--- a/src/target/trx_toolkit/trx_sniff.py</span><br><span>+++ b/src/target/trx_toolkit/trx_sniff.py</span><br><span>@@ -101,10 +101,10 @@</span><br><span>             msg_raw = bytearray(trx.load)</span><br><span> </span><br><span>            # Determine a burst direction (L1 <-> TRX)</span><br><span style="color: hsl(0, 100%, 40%);">-                l12trx = udp.sport > udp.dport</span><br><span style="color: hsl(120, 100%, 40%);">+             tx_dir = udp.sport > udp.dport</span><br><span> </span><br><span>                # Create an empty DATA message</span><br><span style="color: hsl(0, 100%, 40%);">-          msg = DATAMSG_L12TRX() if l12trx else DATAMSG_TRX2L1()</span><br><span style="color: hsl(120, 100%, 40%);">+                msg = TxMsg() if tx_dir else RxMsg()</span><br><span> </span><br><span>             # Attempt to parse the payload as a DATA message</span><br><span>             try:</span><br><span>@@ -124,8 +124,7 @@</span><br><span>                   return</span><br><span> </span><br><span>           # Debug print</span><br><span style="color: hsl(0, 100%, 40%);">-           log.debug("%s burst: %s" \</span><br><span style="color: hsl(0, 100%, 40%);">-                    % ("L1 -> TRX" if l12trx else "TRX -> L1", msg.desc_hdr()))</span><br><span style="color: hsl(120, 100%, 40%);">+         log.debug("%s burst: %s", "L1 -> TRX" if tx_dir else "TRX -> L1", msg.desc_hdr())</span><br><span> </span><br><span>            # Poke message handler</span><br><span>               self.msg_handle(msg)</span><br><span>@@ -139,10 +138,10 @@</span><br><span>                 # Direction filter</span><br><span>           if self.argv.direction is not None:</span><br><span>                  if self.argv.direction == "TRX": # L1 -> TRX</span><br><span style="color: hsl(0, 100%, 40%);">-                               if not isinstance(msg, DATAMSG_L12TRX):</span><br><span style="color: hsl(120, 100%, 40%);">+                               if not isinstance(msg, TxMsg):</span><br><span>                                       return False</span><br><span>                         elif self.argv.direction == "L1": # TRX -> L1</span><br><span style="color: hsl(0, 100%, 40%);">-                              if not isinstance(msg, DATAMSG_TRX2L1):</span><br><span style="color: hsl(120, 100%, 40%);">+                               if not isinstance(msg, RxMsg):</span><br><span>                                       return False</span><br><span> </span><br><span>             # Timeslot filter</span><br><span>@@ -159,7 +158,7 @@</span><br><span>                              return False</span><br><span> </span><br><span>             # Message type specific filtering</span><br><span style="color: hsl(0, 100%, 40%);">-               if isinstance(msg, DATAMSG_TRX2L1):</span><br><span style="color: hsl(120, 100%, 40%);">+           if isinstance(msg, RxMsg):</span><br><span>                   # NOPE.ind filter</span><br><span>                    if not self.argv.pf_nope_ind and msg.nope_ind:</span><br><span>                               return False</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmocom-bb/+/24018">change 24018</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/osmocom-bb/+/24018"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmocom-bb </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I688f24a3c09dd7e1cc00b5530ec26c8e8cfd8f7c </div>
<div style="display:none"> Gerrit-Change-Number: 24018 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </div>
<div style="display:none"> Gerrit-Owner: fixeria <vyanitskiy@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: fixeria <vyanitskiy@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>