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