<p>Walter Doekes has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/11602">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">contrib/scripts: Make spandspflow2pcap.py Python 2.7+/3.3+ compatible<br><br>Change-Id: Ica182a891743017ff3cda16de3d95335fffd9a91<br>---<br>M contrib/scripts/spandspflow2pcap.py<br>1 file changed, 173 insertions(+), 109 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/02/11602/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/contrib/scripts/spandspflow2pcap.py b/contrib/scripts/spandspflow2pcap.py</span><br><span>old mode 100755</span><br><span>new mode 100644</span><br><span>index 7c403f1..442e15f</span><br><span>--- a/contrib/scripts/spandspflow2pcap.py</span><br><span>+++ b/contrib/scripts/spandspflow2pcap.py</span><br><span>@@ -9,7 +9,7 @@</span><br><span> </span><br><span> Input data should look something like this::</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    [2013-08-07 15:17:34] FAX[23479] res_fax.c: FLOW T.38 Rx     5: IFP c0 01 ...</span><br><span style="color: hsl(120, 100%, 40%);">+    [2013-08-07 15:17:34] FAX[23479] res_fax.c: FLOW T.38 Rx     5: IFP c0 ...</span><br><span> </span><br><span> Output data will look like a valid pcap file ;-)</span><br><span> </span><br><span>@@ -21,14 +21,16 @@</span><br><span> or the git master branch: https://github.com/SIPp/sipp</span><br><span> </span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-Author: Walter Doekes, OSSO B.V. (2013,2015,2016)</span><br><span style="color: hsl(120, 100%, 40%);">+Author: Walter Doekes, OSSO B.V. (2013,2015,2016,2019)</span><br><span> License: Public Domain</span><br><span> '''</span><br><span> from base64 import b16decode</span><br><span style="color: hsl(120, 100%, 40%);">+from collections import namedtuple</span><br><span> from datetime import datetime, timedelta</span><br><span> from re import search</span><br><span> from time import mktime</span><br><span> from struct import pack</span><br><span style="color: hsl(120, 100%, 40%);">+import os</span><br><span> import sys</span><br><span> </span><br><span> </span><br><span>@@ -36,124 +38,176 @@</span><br><span> EMPTY_RECOVERY = False</span><br><span> </span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+IFP = namedtuple('IFP', 'date seqno data')  # datetime, int, bytearray</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> def n2b(text):</span><br><span style="color: hsl(0, 100%, 40%);">-    return b16decode(text.replace(' ', '').replace('\n', '').upper())</span><br><span style="color: hsl(120, 100%, 40%);">+    """</span><br><span style="color: hsl(120, 100%, 40%);">+    Convert "aa bb cc" to bytearray('\xaa\xbb\xcc').</span><br><span style="color: hsl(120, 100%, 40%);">+    """</span><br><span style="color: hsl(120, 100%, 40%);">+    return bytearray(</span><br><span style="color: hsl(120, 100%, 40%);">+        b16decode(text.replace(' ', '').replace('\n', '').upper()))</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%);">+class SkipPacket(Exception):</span><br><span style="color: hsl(120, 100%, 40%);">+    pass</span><br><span> </span><br><span> </span><br><span> class FaxPcap(object):</span><br><span style="color: hsl(0, 100%, 40%);">-    PCAP_PREAMBLE = n2b('d4 c3 b2 a1 02 00 04 00'</span><br><span style="color: hsl(0, 100%, 40%);">-                        '00 00 00 00 00 00 00 00'</span><br><span style="color: hsl(0, 100%, 40%);">-                        'ff ff 00 00 71 00 00 00')</span><br><span style="color: hsl(120, 100%, 40%);">+    PCAP_PREAMBLE = n2b(</span><br><span style="color: hsl(120, 100%, 40%);">+        'd4 c3 b2 a1 02 00 04 00'</span><br><span style="color: hsl(120, 100%, 40%);">+        '00 00 00 00 00 00 00 00'</span><br><span style="color: hsl(120, 100%, 40%);">+        'ff ff 00 00 71 00 00 00')</span><br><span> </span><br><span>     def __init__(self, outfile):</span><br><span>         self.outfile = outfile</span><br><span>         self.date = None</span><br><span style="color: hsl(0, 100%, 40%);">-        self.dateoff = timedelta(seconds=0)</span><br><span>         self.seqno = None</span><br><span>         self.udpseqno = 128</span><br><span>         self.prev_data = None</span><br><span> </span><br><span>         # Only do this if at pos 0?</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def add(self, ifp):</span><br><span style="color: hsl(120, 100%, 40%);">+        """</span><br><span style="color: hsl(120, 100%, 40%);">+        Add the IFP packet.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        T.38 basic format of UDPTL payload section with redundancy:</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        UDPTL_SEQNO</span><br><span style="color: hsl(120, 100%, 40%);">+        - 2 sequence number (big endian)</span><br><span style="color: hsl(120, 100%, 40%);">+        UDPTL_PRIMARY_PAYLOAD (T30?)</span><br><span style="color: hsl(120, 100%, 40%);">+        - 1 subpacket length (excluding this byte)</span><br><span style="color: hsl(120, 100%, 40%);">+        - 1 type of message (e.g. 0xd0 for data(?))</span><br><span style="color: hsl(120, 100%, 40%);">+        - 1 items in data field (e.g. 0x01)</span><br><span style="color: hsl(120, 100%, 40%);">+        - 2 length of data (big endian)</span><br><span style="color: hsl(120, 100%, 40%);">+        - N data</span><br><span style="color: hsl(120, 100%, 40%);">+        RECOVERY (optional)</span><br><span style="color: hsl(120, 100%, 40%);">+        - 2 count of previous seqno packets (big endian)</span><br><span style="color: hsl(120, 100%, 40%);">+        - N UDPTL_PRIMARY_PAYLOAD of (seqno-1)</span><br><span style="color: hsl(120, 100%, 40%);">+        - N UDPTL_PRIMARY_PAYLOAD of (seqno-2)</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%);">+        # First packet?</span><br><span style="color: hsl(120, 100%, 40%);">+        if self.seqno is None:</span><br><span style="color: hsl(120, 100%, 40%);">+            # Add preamble.</span><br><span style="color: hsl(120, 100%, 40%);">+            self._add_preamble()</span><br><span style="color: hsl(120, 100%, 40%);">+            # Start a second late (optional).</span><br><span style="color: hsl(120, 100%, 40%);">+            self._add_garbage(ifp.date)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            # Set sequence, and fill with missing leading zeroes.</span><br><span style="color: hsl(120, 100%, 40%);">+            self.seqno = 0</span><br><span style="color: hsl(120, 100%, 40%);">+            for i in range(ifp.seqno):</span><br><span style="color: hsl(120, 100%, 40%);">+                self.add(IFP(date=ifp.date, seqno=i, data=bytearray([0])))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        # Auto-increasing dates</span><br><span style="color: hsl(120, 100%, 40%);">+        if self.date is None or ifp.date > self.date:</span><br><span style="color: hsl(120, 100%, 40%);">+            self.date = ifp.date</span><br><span style="color: hsl(120, 100%, 40%);">+        elif ifp.date < self.date.replace(microsecond=0):</span><br><span style="color: hsl(120, 100%, 40%);">+            assert False, 'More packets than expected in 1s? {!r}/{!r}'.format(</span><br><span style="color: hsl(120, 100%, 40%);">+                ifp.date, self.date)</span><br><span style="color: hsl(120, 100%, 40%);">+        else:</span><br><span style="color: hsl(120, 100%, 40%);">+            self.date += timedelta(microseconds=9000)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        # Add packet.</span><br><span style="color: hsl(120, 100%, 40%);">+        self.seqno = ifp.seqno</span><br><span style="color: hsl(120, 100%, 40%);">+        try:</span><br><span style="color: hsl(120, 100%, 40%);">+            self.outfile.write(self._make_packet(ifp.data))</span><br><span style="color: hsl(120, 100%, 40%);">+        except SkipPacket:</span><br><span style="color: hsl(120, 100%, 40%);">+            pass</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def _add_preamble(self):</span><br><span>         self.outfile.write(self.PCAP_PREAMBLE)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    def data2packet(self, date, udpseqno, seqno, data, prev_data):</span><br><span style="color: hsl(0, 100%, 40%);">-        sum16 = '\x43\x21'  # checksum is irrelevant for sipp sending</span><br><span style="color: hsl(120, 100%, 40%);">+    def _add_garbage(self, date):</span><br><span style="color: hsl(120, 100%, 40%);">+        if self.date is None or date > self.date:</span><br><span style="color: hsl(120, 100%, 40%);">+            self.date = date</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        new_prev = data  # without seqno..</span><br><span style="color: hsl(0, 100%, 40%);">-        data = '%s%s' % (pack('>H', seqno), data)</span><br><span style="color: hsl(120, 100%, 40%);">+        self.seqno = 0xffff</span><br><span style="color: hsl(120, 100%, 40%);">+        self.outfile.write(self._make_packet(</span><br><span style="color: hsl(120, 100%, 40%);">+            bytearray(b'GARBAGE'), is_ifp=False))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def _make_packet(self, ifp_data, is_ifp=True):</span><br><span style="color: hsl(120, 100%, 40%);">+        sum16 = bytearray(b'\x43\x21')  # the OS fixes the checksums for us</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        data = bytearray()</span><br><span style="color: hsl(120, 100%, 40%);">+        if is_ifp:</span><br><span style="color: hsl(120, 100%, 40%);">+            data.append(len(ifp_data))  # length</span><br><span style="color: hsl(120, 100%, 40%);">+            data.extend(ifp_data)       # data</span><br><span style="color: hsl(120, 100%, 40%);">+            self.prev_data, prev_data = data[:], self.prev_data</span><br><span style="color: hsl(120, 100%, 40%);">+        else:</span><br><span style="color: hsl(120, 100%, 40%);">+            data.extend(ifp_data)</span><br><span style="color: hsl(120, 100%, 40%);">+            prev_data = None</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         if prev_data:</span><br><span style="color: hsl(0, 100%, 40%);">-            if LOSSY and (seqno % 3) == 2:</span><br><span style="color: hsl(0, 100%, 40%);">-                return '', new_prev</span><br><span style="color: hsl(120, 100%, 40%);">+            if LOSSY and (self.seqno % 3) == 2:</span><br><span style="color: hsl(120, 100%, 40%);">+                self.udpseqno += 1</span><br><span style="color: hsl(120, 100%, 40%);">+                raise SkipPacket()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>             if EMPTY_RECOVERY:</span><br><span>                 # struct ast_frame f[16], we have room for a few</span><br><span>                 # packets.</span><br><span>                 packets = 14</span><br><span style="color: hsl(0, 100%, 40%);">-                data += '\x00%c%s%s' % (</span><br><span style="color: hsl(0, 100%, 40%);">-                    chr(packets + 1), '\x00' * packets, prev_data)</span><br><span style="color: hsl(120, 100%, 40%);">+                data.extend([0, packets + 1] + [0] * packets)</span><br><span style="color: hsl(120, 100%, 40%);">+                data.extend(prev_data)</span><br><span>             else:</span><br><span>                 # Add 1 previous packet, without the seqno.</span><br><span style="color: hsl(0, 100%, 40%);">-                data += '\x00\x01' + prev_data</span><br><span style="color: hsl(120, 100%, 40%);">+                data.extend([0, 1])</span><br><span style="color: hsl(120, 100%, 40%);">+                data.extend(prev_data)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        kwargs = {'udpseqno': pack('>H', udpseqno), 'sum16': sum16}</span><br><span style="color: hsl(120, 100%, 40%);">+        # Wrap it in UDP</span><br><span style="color: hsl(120, 100%, 40%);">+        udp = bytearray(</span><br><span style="color: hsl(120, 100%, 40%);">+            b'\x00\x01\x00\x02%(len)s%(sum16)s%(seqno)s%(data)s' % {</span><br><span style="color: hsl(120, 100%, 40%);">+                b'len': pack('>H', len(data) + 10),</span><br><span style="color: hsl(120, 100%, 40%);">+                b'sum16': sum16,</span><br><span style="color: hsl(120, 100%, 40%);">+                b'seqno': pack('>H', self.seqno),</span><br><span style="color: hsl(120, 100%, 40%);">+                b'data': data})</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        kwargs['data'] = data</span><br><span style="color: hsl(0, 100%, 40%);">-        kwargs['lenb16'] = pack('>H', len(kwargs['data']) + 8)</span><br><span style="color: hsl(0, 100%, 40%);">-        udp = '\x00\x01\x00\x02%(lenb16)s%(sum16)s%(data)s' % kwargs</span><br><span style="color: hsl(120, 100%, 40%);">+        # Wrap it in IP</span><br><span style="color: hsl(120, 100%, 40%);">+        ip = bytearray(</span><br><span style="color: hsl(120, 100%, 40%);">+            b'\x45\xb8%(len)s%(udpseqno)s\x00\x00\xf9\x11%(sum16)s'</span><br><span style="color: hsl(120, 100%, 40%);">+            b'\x01\x01\x01\x01\x02\x02\x02\x02%(udp)s' % {</span><br><span style="color: hsl(120, 100%, 40%);">+                b'len': pack('>H', len(udp) + 20),</span><br><span style="color: hsl(120, 100%, 40%);">+                b'udpseqno': pack('>H', self.udpseqno),</span><br><span style="color: hsl(120, 100%, 40%);">+                b'sum16': sum16,</span><br><span style="color: hsl(120, 100%, 40%);">+                b'udp': udp})</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        kwargs['data'] = udp</span><br><span style="color: hsl(0, 100%, 40%);">-        kwargs['lenb16'] = pack('>H', len(kwargs['data']) + 20)</span><br><span style="color: hsl(0, 100%, 40%);">-        ip = ('\x45\xb8%(lenb16)s%(udpseqno)s\x00\x00\xf9\x11%(sum16)s\x01'</span><br><span style="color: hsl(0, 100%, 40%);">-              '\x01\x01\x01\x02\x02\x02\x02%(data)s') % kwargs</span><br><span style="color: hsl(120, 100%, 40%);">+        # Wrap it in Ethernet</span><br><span style="color: hsl(120, 100%, 40%);">+        ethernet = bytearray(</span><br><span style="color: hsl(120, 100%, 40%);">+            b'\x00\x00\x00\x01\x00\x06\x00\x30\x48\xb1\x1c\x34\x00\x00'</span><br><span style="color: hsl(120, 100%, 40%);">+            b'\x08\x00%(ip)s' % {b'ip': ip})</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        kwargs['data'] = ip</span><br><span style="color: hsl(0, 100%, 40%);">-        frame = ('\x00\x00\x00\x01\x00\x06\x00\x30\x48\xb1\x1c\x34\x00\x00'</span><br><span style="color: hsl(0, 100%, 40%);">-                 '\x08\x00%(data)s') % kwargs</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        kwargs['data'] = frame</span><br><span style="color: hsl(0, 100%, 40%);">-        sec = mktime(date.timetuple())</span><br><span style="color: hsl(0, 100%, 40%);">-        msec = date.microsecond</span><br><span style="color: hsl(0, 100%, 40%);">-        datalen = len(kwargs['data'])</span><br><span style="color: hsl(0, 100%, 40%);">-        kwargs['pre'] = pack('<IIII', sec, msec, datalen, datalen)</span><br><span style="color: hsl(0, 100%, 40%);">-        packet = '%(pre)s%(data)s' % kwargs</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        return (packet, new_prev)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    def add(self, date, seqno, data):</span><br><span style="color: hsl(0, 100%, 40%);">-        if self.seqno is None:</span><br><span style="color: hsl(0, 100%, 40%);">-            self.seqno = 0</span><br><span style="color: hsl(0, 100%, 40%);">-            for i in range(seqno):</span><br><span style="color: hsl(0, 100%, 40%);">-                # In case the first zeroes were dropped, add them.</span><br><span style="color: hsl(0, 100%, 40%);">-                self.add(date, i, '\x00')</span><br><span style="color: hsl(0, 100%, 40%);">-        assert seqno == self.seqno, '%s != %s' % (seqno, self.seqno)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        # Data is prepended by len(data).</span><br><span style="color: hsl(0, 100%, 40%);">-        data = chr(len(data)) + data</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        # Auto-increasing dates</span><br><span style="color: hsl(0, 100%, 40%);">-        if self.date is None or date > self.date:</span><br><span style="color: hsl(0, 100%, 40%);">-            # print 'date is larger', date, self.date</span><br><span style="color: hsl(0, 100%, 40%);">-            self.date = date</span><br><span style="color: hsl(0, 100%, 40%);">-        elif (date < self.date.replace(microsecond=0)):</span><br><span style="color: hsl(0, 100%, 40%);">-            assert False, ('We increased too fast.. decrease delta: %r/%r' %</span><br><span style="color: hsl(0, 100%, 40%);">-                           (date, self.date))</span><br><span style="color: hsl(0, 100%, 40%);">-        else:</span><br><span style="color: hsl(0, 100%, 40%);">-            self.date += timedelta(microseconds=9000)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        print(seqno, '\t', self.date + self.dateoff)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        # Make packet.</span><br><span style="color: hsl(0, 100%, 40%);">-        packet, prev_data = self.data2packet(self.date + self.dateoff,</span><br><span style="color: hsl(0, 100%, 40%);">-                                             self.udpseqno, self.seqno,</span><br><span style="color: hsl(0, 100%, 40%);">-                                             data, self.prev_data)</span><br><span style="color: hsl(0, 100%, 40%);">-        self.outfile.write(packet)</span><br><span style="color: hsl(120, 100%, 40%);">+        # Wrap it in a pcap packet</span><br><span style="color: hsl(120, 100%, 40%);">+        packet = bytearray(b'%(prelude)s%(ethernet)s' % {</span><br><span style="color: hsl(120, 100%, 40%);">+            b'prelude': pack(</span><br><span style="color: hsl(120, 100%, 40%);">+                '<IIII', int(mktime(self.date.timetuple())),</span><br><span style="color: hsl(120, 100%, 40%);">+                self.date.microsecond, len(ethernet), len(ethernet)),</span><br><span style="color: hsl(120, 100%, 40%);">+            b'ethernet': ethernet})</span><br><span> </span><br><span>         # Increase values.</span><br><span>         self.udpseqno += 1</span><br><span style="color: hsl(0, 100%, 40%);">-        self.seqno += 1</span><br><span style="color: hsl(0, 100%, 40%);">-        self.prev_data = prev_data</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    def add_garbage(self, date):</span><br><span style="color: hsl(0, 100%, 40%);">-        if self.date is None or date > self.date:</span><br><span style="color: hsl(0, 100%, 40%);">-            self.date = date</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        packet, ignored = self.data2packet(self.date, self.udpseqno,</span><br><span style="color: hsl(0, 100%, 40%);">-                                           0xffff, 'GARBAGE', '')</span><br><span style="color: hsl(0, 100%, 40%);">-        self.udpseqno += 1</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        self.outfile.write(packet)</span><br><span style="color: hsl(120, 100%, 40%);">+        return packet</span><br><span> </span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-with open(sys.argv[1], 'r') as infile:</span><br><span style="color: hsl(0, 100%, 40%);">-    with open(sys.argv[2], 'wb') as outfile:</span><br><span style="color: hsl(0, 100%, 40%);">-        first = True</span><br><span style="color: hsl(0, 100%, 40%);">-        p = FaxPcap(outfile)</span><br><span style="color: hsl(0, 100%, 40%);">-        # p.add(datetime.now(), 0, n2b('06'))</span><br><span style="color: hsl(0, 100%, 40%);">-        # p.add(datetime.now(), 1, n2b('c0 01 80 00 00 ff'))</span><br><span style="color: hsl(120, 100%, 40%);">+class SpandspLog:</span><br><span style="color: hsl(120, 100%, 40%);">+    def __init__(self, fp):</span><br><span style="color: hsl(120, 100%, 40%);">+        self._fp = fp</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        for lineno, line in enumerate(infile):</span><br><span style="color: hsl(0, 100%, 40%);">-            # Look for lines like:</span><br><span style="color: hsl(0, 100%, 40%);">-            # [2013-08-07 15:17:34] FAX[23479] res_fax.c: \</span><br><span style="color: hsl(0, 100%, 40%);">-            #   FLOW T.38 Rx     5: IFP c0 01 80 00 00 ff</span><br><span style="color: hsl(120, 100%, 40%);">+    def __iter__(self):</span><br><span style="color: hsl(120, 100%, 40%);">+        r"""</span><br><span style="color: hsl(120, 100%, 40%);">+        Looks for lines line:</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            [2013-08-07 15:17:34] FAX[23479] res_fax.c: \</span><br><span style="color: hsl(120, 100%, 40%);">+              FLOW T.38 Rx     5: IFP c0 01 80 00 00 ff</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        And yields:</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            IFP(date=..., seqno=..., data=...)</span><br><span style="color: hsl(120, 100%, 40%);">+        """</span><br><span style="color: hsl(120, 100%, 40%);">+        prev_seqno = None</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        for lineno, line in enumerate(self._fp):</span><br><span>             if 'FLOW T.38 Rx' not in line:</span><br><span>                 continue</span><br><span>             if 'IFP' not in line:</span><br><span>@@ -171,27 +225,37 @@</span><br><span>             assert match</span><br><span>             data = n2b(match.groups()[0])</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-            # Have the file start a second early.</span><br><span style="color: hsl(0, 100%, 40%);">-            if first:</span><br><span style="color: hsl(0, 100%, 40%);">-                p.add_garbage(date)</span><br><span style="color: hsl(0, 100%, 40%);">-                first = False</span><br><span style="color: hsl(120, 100%, 40%);">+            if prev_seqno is not None:</span><br><span style="color: hsl(120, 100%, 40%);">+                # Expected all sequence numbers. But you can safely disable</span><br><span style="color: hsl(120, 100%, 40%);">+                # this check.</span><br><span style="color: hsl(120, 100%, 40%);">+                assert seqno == prev_seqno + 1, '%s+1 != %s' % (</span><br><span style="color: hsl(120, 100%, 40%);">+                    seqno, prev_seqno)</span><br><span style="color: hsl(120, 100%, 40%);">+                pass</span><br><span style="color: hsl(120, 100%, 40%);">+            prev_seqno = seqno</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-            # Add the packets.</span><br><span style="color: hsl(0, 100%, 40%);">-            #</span><br><span style="color: hsl(0, 100%, 40%);">-            # T.38 basic format of UDPTL payload section with redundancy:</span><br><span style="color: hsl(0, 100%, 40%);">-            #</span><br><span style="color: hsl(0, 100%, 40%);">-            # UDPTL_SEQNO</span><br><span style="color: hsl(0, 100%, 40%);">-            # - 2 sequence number (big endian)</span><br><span style="color: hsl(0, 100%, 40%);">-            # UDPTL_PRIMARY_PAYLOAD (T30?)</span><br><span style="color: hsl(0, 100%, 40%);">-            # - 1 subpacket length (excluding this byte)</span><br><span style="color: hsl(0, 100%, 40%);">-            # - 1 type of message (e.g. 0xd0 for data(?))</span><br><span style="color: hsl(0, 100%, 40%);">-            # - 1 items in data field (e.g. 0x01)</span><br><span style="color: hsl(0, 100%, 40%);">-            # - 2 length of data (big endian)</span><br><span style="color: hsl(0, 100%, 40%);">-            # - N data</span><br><span style="color: hsl(0, 100%, 40%);">-            # RECOVERY (optional)</span><br><span style="color: hsl(0, 100%, 40%);">-            # - 2 count of previous seqno packets (big endian)</span><br><span style="color: hsl(0, 100%, 40%);">-            # - N UDPTL_PRIMARY_PAYLOAD of (seqno-1)</span><br><span style="color: hsl(0, 100%, 40%);">-            # - N UDPTL_PRIMARY_PAYLOAD of (seqno-2)</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%);">-            p.add(date, seqno, data)</span><br><span style="color: hsl(120, 100%, 40%);">+            yield IFP(date=date, seqno=seqno, data=data)</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 main(logname, pcapname):</span><br><span style="color: hsl(120, 100%, 40%);">+    with open(sys.argv[1], 'r') as infile:</span><br><span style="color: hsl(120, 100%, 40%);">+        log = SpandspLog(infile)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        # with open(sys.argv[2], 'xb') as outfile:  # py3 exclusive write, bin</span><br><span style="color: hsl(120, 100%, 40%);">+        create_or_fail = os.O_CREAT | os.O_EXCL | os.O_WRONLY</span><br><span style="color: hsl(120, 100%, 40%);">+        try:</span><br><span style="color: hsl(120, 100%, 40%);">+            fd = os.open(sys.argv[2], create_or_fail, 0o600)</span><br><span style="color: hsl(120, 100%, 40%);">+        except Exception:</span><br><span style="color: hsl(120, 100%, 40%);">+            raise</span><br><span style="color: hsl(120, 100%, 40%);">+        else:</span><br><span style="color: hsl(120, 100%, 40%);">+            with os.fdopen(fd, 'wb') as outfile:</span><br><span style="color: hsl(120, 100%, 40%);">+                pcap = FaxPcap(outfile)</span><br><span style="color: hsl(120, 100%, 40%);">+                for data in log:</span><br><span style="color: hsl(120, 100%, 40%);">+                    pcap.add(data)</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%);">+if __name__ == '__main__':</span><br><span style="color: hsl(120, 100%, 40%);">+    if len(sys.argv) != 3:</span><br><span style="color: hsl(120, 100%, 40%);">+        sys.stderr.write('Usage: {} LOGFILE PCAP\n'.format(sys.argv[0]))</span><br><span style="color: hsl(120, 100%, 40%);">+        sys.exit(1)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    main(sys.argv[1], sys.argv[2])</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/11602">change 11602</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.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.asterisk.org/c/asterisk/+/11602"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Ica182a891743017ff3cda16de3d95335fffd9a91 </div>
<div style="display:none"> Gerrit-Change-Number: 11602 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Walter Doekes <walter+asterisk@wjd.nu> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>