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

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">trx_toolkit/data_msg.py: implement header version coding<br><br>It may be necessary to extend the message specific header with<br>more information. Since this is not a TLV-based protocol, we<br>need to include the header format version.<br><br>  +-----------------+------------------------+<br>  | 7 6 5 4 3 2 1 0 | bit numbers            |<br>  +-----------------+------------------------+<br>  | X X X X . . . . | header version (0..15) |<br>  +-----------------+------------------------+<br>  | . . . . . X X X | TDMA TN (0..7)         |<br>  +-----------------+------------------------+<br>  | . . . . X . . . | RESERVED (0)           |<br>  +-----------------+------------------------+<br><br>Instead of prepending an additional byte, it was decided to use<br>4 MSB bits of the first octet, which used to be zero-initialized<br>due to the value range of TDMA TN. Therefore, the current header<br>format has implicit version 0x00.<br><br>Otherwise Wireshark (or trx_sniff.py) would need to guess the<br>header version, or alternatively follow the control channel<br>looking for the version setting command.<br><br>The reserved bit number 3 can be used in the future to extend<br>the TDMA TN range to (0..15), in case anybody would need<br>to transfer UMTS bursts.<br><br>Change-Id: Idb0377d66290eb9c15d6998a5806a84fa2e5dd02<br>Related: OS#4006<br>---<br>M src/target/trx_toolkit/data_msg.py<br>1 file changed, 115 insertions(+), 15 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/target/trx_toolkit/data_msg.py b/src/target/trx_toolkit/data_msg.py</span><br><span>index 86d0827..5bd04ca 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>@@ -4,7 +4,7 @@</span><br><span> # TRX Toolkit</span><br><span> # DATA interface message definitions and helpers</span><br><span> #</span><br><span style="color: hsl(0, 100%, 40%);">-# (C) 2018 by Vadim Yanitskiy <axilirator@gmail.com></span><br><span style="color: hsl(120, 100%, 40%);">+# (C) 2018-2019 by Vadim Yanitskiy <axilirator@gmail.com></span><br><span> #</span><br><span> # All Rights Reserved</span><br><span> #</span><br><span>@@ -49,20 +49,55 @@</span><br><span>         parent of both DATAMSG_L12TRX and DATAMSG_TRX2L2 (see below),</span><br><span>        and has the following fields:</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-         +--------------+-------------------+</span><br><span style="color: hsl(0, 100%, 40%);">-    | TN (1 octet) | FN (4 octets, BE) |</span><br><span style="color: hsl(0, 100%, 40%);">-    +--------------+-------------------+</span><br><span style="color: hsl(120, 100%, 40%);">+          +-----------------+----------------+-------------------+</span><br><span style="color: hsl(120, 100%, 40%);">+      | VER (1/2 octet) | TN (1/2 octet) | FN (4 octets, BE) |</span><br><span style="color: hsl(120, 100%, 40%);">+      +-----------------+----------------+-------------------+</span><br><span> </span><br><span>       where:</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        - TN is TDMA time-slot number (1 octet), and</span><br><span style="color: hsl(120, 100%, 40%);">+          - VER is the header version indicator (1/2 octet MSB),</span><br><span style="color: hsl(120, 100%, 40%);">+        - TN is TDMA time-slot number (1/2 octet LSB), and</span><br><span>           - FN is TDMA frame number (4 octets, big endian).</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+       == Header version indication</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        It may be necessary to extend the message specific header</span><br><span style="color: hsl(120, 100%, 40%);">+     with more information. Since this is not a TLV-based</span><br><span style="color: hsl(120, 100%, 40%);">+  protocol, we need to include the header format version.</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%);">+          | 7 6 5 4 3 2 1 0 | bit numbers            |</span><br><span style="color: hsl(120, 100%, 40%);">+          +-----------------+------------------------+</span><br><span style="color: hsl(120, 100%, 40%);">+          | X X X X . . . . | header version (0..15) |</span><br><span style="color: hsl(120, 100%, 40%);">+          +-----------------+------------------------+</span><br><span style="color: hsl(120, 100%, 40%);">+          | . . . . . X X X | TDMA TN (0..7)         |</span><br><span style="color: hsl(120, 100%, 40%);">+          +-----------------+------------------------+</span><br><span style="color: hsl(120, 100%, 40%);">+          | . . . . X . . . | RESERVED (0)           |</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%);">+      Instead of prepending an additional byte, it was decided to use</span><br><span style="color: hsl(120, 100%, 40%);">+       4 MSB bits of the first octet, which used to be zero-initialized</span><br><span style="color: hsl(120, 100%, 40%);">+      due to the value range of TDMA TN. Therefore, the legacy header</span><br><span style="color: hsl(120, 100%, 40%);">+       format has implicit version 0x00.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   Otherwise Wireshark (or trx_sniff.py) would need to guess the</span><br><span style="color: hsl(120, 100%, 40%);">+ header version, or alternatively follow the control channel</span><br><span style="color: hsl(120, 100%, 40%);">+   looking for the version setting command.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    The reserved bit number 3 can be used in the future to extend</span><br><span style="color: hsl(120, 100%, 40%);">+ the TDMA TN range to (0..15), in case anybody would need</span><br><span style="color: hsl(120, 100%, 40%);">+      to transfer UMTS bursts.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>   """</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+        # NOTE: up to 16 versions can be encoded</span><br><span style="color: hsl(120, 100%, 40%);">+      CHDR_VERSION_MAX = 0b1111</span><br><span style="color: hsl(120, 100%, 40%);">+     known_versions = [0x00]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>    # Common constructor</span><br><span style="color: hsl(0, 100%, 40%);">-    def __init__(self, fn = None, tn = None, burst = None):</span><br><span style="color: hsl(120, 100%, 40%);">+       def __init__(self, fn = None, tn = None, burst = None, ver = 0):</span><br><span>             self.burst = burst</span><br><span style="color: hsl(120, 100%, 40%);">+            self.ver = ver</span><br><span>               self.fn = fn</span><br><span>                 self.tn = tn</span><br><span> </span><br><span>@@ -103,6 +138,9 @@</span><br><span>       def desc_hdr(self):</span><br><span>          result = ""</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+             if self.ver > 0:</span><br><span style="color: hsl(120, 100%, 40%);">+                   result += ("ver=%u " % self.ver)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>                 if self.fn is not None:</span><br><span>                      result += ("fn=%u " % self.fn)</span><br><span> </span><br><span>@@ -156,6 +194,9 @@</span><br><span> </span><br><span>       # Validates the message fields</span><br><span>       def validate(self):</span><br><span style="color: hsl(120, 100%, 40%);">+           if not self.ver in self.known_versions:</span><br><span style="color: hsl(120, 100%, 40%);">+                       return False</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>               if self.burst is None:</span><br><span>                       return False</span><br><span> </span><br><span>@@ -185,10 +226,10 @@</span><br><span>             # Allocate an empty byte-array</span><br><span>               buf = bytearray()</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-           # Put timeslot index</span><br><span style="color: hsl(0, 100%, 40%);">-            buf.append(self.tn)</span><br><span style="color: hsl(120, 100%, 40%);">+           # Put version (4 bits) and TDMA TN (3 bits)</span><br><span style="color: hsl(120, 100%, 40%);">+           buf.append((self.ver << 4) | (self.tn & 0x07))</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-            # Put frame number (4 octets, BE)</span><br><span style="color: hsl(120, 100%, 40%);">+             # Put TDMA FN (4 octets, BE)</span><br><span>                 buf += struct.pack(">L", self.fn)</span><br><span> </span><br><span>           # Generate message specific header part</span><br><span>@@ -214,9 +255,12 @@</span><br><span>               if length < (self.HDR_LEN + GSM_BURST_LEN):</span><br><span>                       raise ValueError("Message is to short")</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-           # Parse both fn and tn</span><br><span style="color: hsl(120, 100%, 40%);">+                # Parse version and TDMA TN</span><br><span style="color: hsl(120, 100%, 40%);">+           self.ver = (msg[0] >> 4)</span><br><span style="color: hsl(120, 100%, 40%);">+                self.tn = (msg[0] & 0x07)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+               # Parse TDMA FN</span><br><span>              self.fn = struct.unpack(">L", msg[1:5])[0]</span><br><span style="color: hsl(0, 100%, 40%);">-         self.tn = msg[0]</span><br><span> </span><br><span>                 # Specific message part</span><br><span>              self.parse_hdr(msg)</span><br><span>@@ -332,9 +376,10 @@</span><br><span>                   self.burst.append(ubit)</span><br><span> </span><br><span>  # Transforms this message to TRX2L1 message</span><br><span style="color: hsl(0, 100%, 40%);">-     def gen_trx2l1(self):</span><br><span style="color: hsl(120, 100%, 40%);">+ def gen_trx2l1(self, ver = None):</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 = DATAMSG_TRX2L1(fn = self.fn, tn = self.tn,</span><br><span style="color: hsl(120, 100%, 40%);">+                      ver = self.ver if ver is None else ver)</span><br><span> </span><br><span>          # Convert burst bits</span><br><span>                 if self.burst is not None:</span><br><span>@@ -501,9 +546,10 @@</span><br><span>                    self.burst.append(sbit)</span><br><span> </span><br><span>  # Transforms this message to L12TRX message</span><br><span style="color: hsl(0, 100%, 40%);">-     def gen_l12trx(self):</span><br><span style="color: hsl(120, 100%, 40%);">+ def gen_l12trx(self, ver = None):</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 = DATAMSG_L12TRX(fn = self.fn, tn = self.tn,</span><br><span style="color: hsl(120, 100%, 40%);">+                      ver = self.ver if ver is None else ver)</span><br><span> </span><br><span>          # Convert burst bits</span><br><span>                 if self.burst is not None:</span><br><span>@@ -618,3 +664,57 @@</span><br><span>    assert(msg_trx2l1_dec.burst == DATAMSG.ubit2sbit(msg_l12trx_ref.burst))</span><br><span> </span><br><span>  log.info("Check L12TRX <-> TRX2L1 type transformations: OK")</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        # Test header version coding</span><br><span style="color: hsl(120, 100%, 40%);">+  for ver in DATAMSG.known_versions:</span><br><span style="color: hsl(120, 100%, 40%);">+            # Create messages of both types</span><br><span style="color: hsl(120, 100%, 40%);">+               msg_l12trx = DATAMSG_L12TRX(ver = ver)</span><br><span style="color: hsl(120, 100%, 40%);">+                msg_trx2l1 = DATAMSG_TRX2L1(ver = ver)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+              # Randomize message specific headers</span><br><span style="color: hsl(120, 100%, 40%);">+          msg_l12trx.rand_hdr()</span><br><span style="color: hsl(120, 100%, 40%);">+         msg_trx2l1.rand_hdr()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+               # Randomize bursts</span><br><span style="color: hsl(120, 100%, 40%);">+            msg_l12trx.rand_burst()</span><br><span style="color: hsl(120, 100%, 40%);">+               msg_trx2l1.rand_burst()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+             # Encode DATA messages</span><br><span style="color: hsl(120, 100%, 40%);">+                msg_l12trx_enc = msg_l12trx.gen_msg()</span><br><span style="color: hsl(120, 100%, 40%);">+         msg_trx2l1_enc = msg_trx2l1.gen_msg()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+               # Parse generated DATA messages</span><br><span style="color: hsl(120, 100%, 40%);">+               msg_l12trx_dec = DATAMSG_L12TRX()</span><br><span style="color: hsl(120, 100%, 40%);">+             msg_trx2l1_dec = DATAMSG_TRX2L1()</span><br><span style="color: hsl(120, 100%, 40%);">+             msg_l12trx_dec.parse_msg(msg_l12trx_enc)</span><br><span style="color: hsl(120, 100%, 40%);">+              msg_trx2l1_dec.parse_msg(msg_trx2l1_enc)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            # Match the header version</span><br><span style="color: hsl(120, 100%, 40%);">+            assert(msg_l12trx_dec.ver == ver)</span><br><span style="color: hsl(120, 100%, 40%);">+             assert(msg_trx2l1_dec.ver == ver)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           # Match common TDMA fields</span><br><span style="color: hsl(120, 100%, 40%);">+            assert(msg_l12trx_dec.tn == msg_l12trx.tn)</span><br><span style="color: hsl(120, 100%, 40%);">+            assert(msg_trx2l1_dec.fn == msg_trx2l1.fn)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+          # Compare bursts</span><br><span style="color: hsl(120, 100%, 40%);">+              assert(msg_l12trx_dec.burst == msg_l12trx.burst)</span><br><span style="color: hsl(120, 100%, 40%);">+              assert(msg_trx2l1_dec.burst == msg_trx2l1.burst)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            log.info("Check header version %u coding: OK" % ver)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+              msg_trx2l1_gen = msg_l12trx.gen_trx2l1()</span><br><span style="color: hsl(120, 100%, 40%);">+              msg_l12trx_gen = msg_trx2l1.gen_l12trx()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            assert(msg_trx2l1_gen is not None)</span><br><span style="color: hsl(120, 100%, 40%);">+            assert(msg_l12trx_gen is not None)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+          # Match the header version</span><br><span style="color: hsl(120, 100%, 40%);">+            assert(msg_trx2l1_gen.ver == ver)</span><br><span style="color: hsl(120, 100%, 40%);">+             assert(msg_l12trx_gen.ver == ver)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           # Match common TDMA fields</span><br><span style="color: hsl(120, 100%, 40%);">+            assert(msg_trx2l1_gen.tn == msg_l12trx.tn)</span><br><span style="color: hsl(120, 100%, 40%);">+            assert(msg_l12trx_gen.fn == msg_trx2l1.fn)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+          log.info("Verify direct transformation: OK")</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmocom-bb/+/14576">change 14576</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/+/14576"/><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: Idb0377d66290eb9c15d6998a5806a84fa2e5dd02 </div>
<div style="display:none"> Gerrit-Change-Number: 14576 </div>
<div style="display:none"> Gerrit-PatchSet: 4 </div>
<div style="display:none"> Gerrit-Owner: fixeria <axilirator@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: Hoernchen <ewild@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: fixeria <axilirator@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>