<?xml version="1.0" encoding="ISO-8859-1"?>
<rss version='2.0' xmlns:lj='http://www.livejournal.org/rss/lj/1.0/'>
	<channel>
		<title>The Corelatus Blog - Entries from March 2009</title>
		<description>Entries from March 2009</description>
                <link>../../../</link>

	
	<item>
		<title>GTH audio streaming: why stream over TCP?</title>
		<link>../../../GTH_audio_streaming__why_stream_over_TCP_.html</link>        
		<guid isPermaLink="true">../../../GTH_audio_streaming__why_stream_over_TCP_.html</guid>
                <pubDate>Fri, 6 Mar 2009 16:30:38 GMT</pubDate>
		<description>&lt;p&gt;
GTH lets you stream audio from a TCP socket to a timeslot on an E1/T1
line. Some people are surprised by the choice to use TCP. When I added
that support back in 2002, my first thought was to use RTP (&lt;a
href=&quot;http://www.faqs.org/rfcs/rfc1889.html&quot;&gt;RFC 1889&lt;/a&gt;). RTP is
simple: you just dump the audio in a UDP packet with some timestamping
information and shoot it out on ethernet at the right rate.
&lt;/p&gt;

&lt;p&gt;
I&#39;d worked with RTP before and I&#39;d been at a couple of SIP interops
where &lt;em&gt;most&lt;/em&gt; of the attendees had trouble emitting audio at
&#39;the right rate&#39;, i.e. 8000 samples/s. One manufacturer&#39;s system would
emit 8007 samples/s. Another would play it back at 7999
samples/s. What do you do with the extra 8 samples per second? If you
do nothing, you get endlessly growing delays and, eventually, a buffer
overflow. If you come up with a strategy for throwing away samples,
it&#39;s bound to interact badly with something, sooner or later.
&lt;/p&gt;

&lt;p&gt;
The thing is, when you&#39;re streaming in pre-recorded audio, you don&#39;t
need it to be at the right rate. You just need to make sure it doesn&#39;t
overrun or underrun the GTH&#39;s internal buffer. I.e. you need flow
control, not rate control. TCP has flow control, and everyone knows
how to use TCP sockets. In 2002, doing things that way was right at
the limit of what our 50MHz embedded CPU could keep up with. Now it&#39;s
no problem at all.
&lt;/p&gt;

&lt;h3&gt;Python&lt;/h3&gt;

&lt;p&gt;
I&#39;m playing around with python at the moment. Here&#39;s how to put some
data on an E1 timeslot, straight from the python shell. First, set up
a listening TCP socket:
&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
&lt;span class=&quot;synPreProc&quot;&gt;import&lt;/span&gt; socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.listen(&lt;span class=&quot;synConstant&quot;&gt;0&lt;/span&gt;)
addr, port = s.getsockname()
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Next, open another socket to the GTH command port (2089) and tell it we want to stream in audio on the socket we opened above:
&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
a = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
a.connect((&lt;span class=&quot;synConstant&quot;&gt;&amp;quot;172.16.2.7&amp;quot;&lt;/span&gt;, &lt;span class=&quot;synConstant&quot;&gt;2089&lt;/span&gt;))
my_ip, _port = a.getsockname()
command = &lt;span class=&quot;synConstant&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt; % (my_ip, port)
header = &lt;span class=&quot;synConstant&quot;&gt;&amp;quot;Content-type: text/xml&lt;/span&gt;&lt;span class=&quot;synSpecial&quot;&gt;\r\n&lt;/span&gt;&lt;span class=&quot;synConstant&quot;&gt;Content-length: %d&lt;/span&gt;&lt;span class=&quot;synSpecial&quot;&gt;\r\n\r\n&lt;/span&gt;&lt;span class=&quot;synConstant&quot;&gt;&amp;quot;&lt;/span&gt; % &lt;span class=&quot;synIdentifier&quot;&gt;len&lt;/span&gt;(command)
a.sendall(header + command)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Finally, accept() and send the data:
&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
d, _ = s.accept()
d.sendall(&lt;span class=&quot;synConstant&quot;&gt;&amp;quot;hello world&amp;quot;&lt;/span&gt;)
d.close()
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt; That looks OK to me, though I imagine the style betrays my Erlang
mindset. There&#39;s a more complete python example at the bottom of the
&lt;a href=&quot;http://www.corelatus.com/gth/api/&quot;&gt;API page&lt;/a&gt;.&lt;/p&gt;
</description>
	</item>
	
	<item>
		<title>The timestamp field in signalling headers</title>
		<link>../../../The_timestamp_field_in_signalling_headers.html</link>        
		<guid isPermaLink="true">../../../The_timestamp_field_in_signalling_headers.html</guid>
                <pubDate>Mon, 23 Mar 2009 20:40:32 +0100</pubDate>
		<description>&lt;p&gt;
When the Corelatus GTH is used to monitor (sniff) signalling, it sends
each sniffed packet to your server over a TCP socket, along with a
header. For instance, for SS7 MTP-2 the header looks like this:
&lt;/p&gt;

&lt;pre&gt;
octet 0x00:  Length (16 bits)
octet 0x02:  Tag (16 bits)
octet 0x04:  Flags (16 bits)
octet 0x06: Timestamp (48 bits)
&lt;/pre&gt;

&lt;p&gt;
Every field is big-endian, i.e. the most significant byte comes
first. Here&#39;s an actual header from a GTH, octet by octet:
&lt;/p&gt;

&lt;pre&gt;
00 1c 00 00 00 00 01 20  34 ee fa 61 99 99 99 99 ...
&lt;/pre&gt;

&lt;p&gt;
The timestamp is thus 0x012034eefa61, or decimal 1237838658145. For
most applications, you just want to know which packet came first, so
the interpretation of that number doesn&#39;t matter much, though it&#39;s
useful to know that it&#39;s the number of &lt;strong&gt;milli&lt;/strong&gt;seconds
since the unix epoch. (wikipedia has a decent &lt;a
href=&quot;http://en.wikipedia.org/wiki/Unix_time&quot;&gt;article about unix
time&lt;/a&gt;)
&lt;/p&gt;

&lt;p&gt;
Sometimes, though, you want to represent that as a human-readable
time. Unix (and, most likely, Win32) provides functions to do that in
the C library, so, after throwing away the last three digits (the
milliseconds), this C program does it:
&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
&lt;span class=&quot;synPreProc&quot;&gt;#include &lt;/span&gt;&lt;span class=&quot;synConstant&quot;&gt;&amp;lt;time.h&amp;gt;&lt;/span&gt;
&lt;span class=&quot;synPreProc&quot;&gt;#include &lt;/span&gt;&lt;span class=&quot;synConstant&quot;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;

&lt;span class=&quot;synType&quot;&gt;int&lt;/span&gt; main() {
  &lt;span class=&quot;synType&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;synType&quot;&gt;time_t&lt;/span&gt; time_stamp = &lt;span class=&quot;synConstant&quot;&gt;1237838658&lt;/span&gt;;
  printf(&lt;span class=&quot;synConstant&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;synSpecial&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;synConstant&quot;&gt; corresponds to &lt;/span&gt;&lt;span class=&quot;synSpecial&quot;&gt;%s\n&lt;/span&gt;&lt;span class=&quot;synConstant&quot;&gt;&amp;quot;&lt;/span&gt;, time_stamp, ctime(&amp;amp;time_stamp));

  &lt;span class=&quot;synStatement&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;synConstant&quot;&gt;0&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;

The output agrees with what the clock on my wall says:
&lt;pre&gt;
1237838658 corresponds to Mon Mar 23 21:04:18 2009
&lt;/pre&gt;


&lt;h3&gt;Python&lt;/h3&gt;

&lt;p&gt;Since I&#39;ve been messing around with python, the same thing in python:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
&amp;gt;&amp;gt;&amp;gt; &lt;span class=&quot;synPreProc&quot;&gt;import&lt;/span&gt; time
&amp;gt;&amp;gt;&amp;gt; time.ctime(&lt;span class=&quot;synConstant&quot;&gt;1237838658&lt;/span&gt;)
&lt;span class=&quot;synConstant&quot;&gt;&#39;Mon Mar 23 21:04:18 2009&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Erlang&lt;/h3&gt;

&lt;p&gt;
Erlang doesn&#39;t have an interface to the &#39;ctime&#39; call, but you can use the gregorian calendar functions:
&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
&lt;span class=&quot;synConstant&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;synStatement&quot;&gt;&amp;gt;&lt;/span&gt; Epoch &lt;span class=&quot;synStatement&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;synIdentifier&quot;&gt;calendar:datetime_to_gregorian_seconds&lt;/span&gt;({{&lt;span class=&quot;synConstant&quot;&gt;1970&lt;/span&gt;, &lt;span class=&quot;synConstant&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;synConstant&quot;&gt;1&lt;/span&gt;}, {&lt;span class=&quot;synConstant&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;synConstant&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;synConstant&quot;&gt;0&lt;/span&gt;}})&lt;span class=&quot;synSpecial&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;synConstant&quot;&gt;62167219200&lt;/span&gt;
&lt;span class=&quot;synConstant&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;synStatement&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;synIdentifier&quot;&gt;calendar:gregorian_seconds_to_datetime&lt;/span&gt;(&lt;span class=&quot;synConstant&quot;&gt;1237838658&lt;/span&gt; &lt;span class=&quot;synStatement&quot;&gt;+&lt;/span&gt; Epoch)&lt;span class=&quot;synSpecial&quot;&gt;.&lt;/span&gt;
{{&lt;span class=&quot;synConstant&quot;&gt;2009&lt;/span&gt;,&lt;span class=&quot;synConstant&quot;&gt;3&lt;/span&gt;,&lt;span class=&quot;synConstant&quot;&gt;23&lt;/span&gt;},{&lt;span class=&quot;synConstant&quot;&gt;20&lt;/span&gt;,&lt;span class=&quot;synConstant&quot;&gt;4&lt;/span&gt;,&lt;span class=&quot;synConstant&quot;&gt;18&lt;/span&gt;}}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Why use milliseconds?&lt;/h3&gt;

&lt;p&gt;
Why is the GTH timestamp in milliseconds instead of either seconds or
a &#39;timeval&#39;-like seconds + microseconds?
&lt;/p&gt;

&lt;p&gt;
We chose millisecond resolution for several reasons. Firstly, the
shortest possible useful packet in SS7 takes a bit more than a
millisecond to transmit at 64kbit/s. Secondly, the practical limit of
NTP time synchronisation over the internet is about one millisecond at
a typical site.
&lt;/p&gt;
</description>
	</item>
	
	<item>
		<title>Decoding MTP-3 and ISUP</title>
		<link>../../../Decoding_MTP_3_and_ISUP.html</link>        
		<guid isPermaLink="true">../../../Decoding_MTP_3_and_ISUP.html</guid>
                <pubDate>Wed, 25 Mar 2009 13:55:20 GMT</pubDate>
		<description>&lt;p&gt;
  Sometimes, you want to look at the signalling on an E1 and use
  it to figure out when telephone calls start and stop. In SS7 networks,
  call setup and tear-down is done by the ISUP layer, which fits in to
  the SS7 stack like this:
&lt;/p&gt;

Layer 4: ISUP&lt;br/&gt;
Layer 3: MTP-3&lt;br/&gt;
Layer 2: MTP-2&lt;br/&gt;
Layer 1: MTP-1 (typically an 2Mbit/s E1 or a 1.5Mbit/s/T1)&lt;br/&gt;

&lt;p&gt;
  If you have a &lt;a href=&quot;http://www.corelatus.com/&quot;&gt;GTH&lt;/a&gt; connected to
  the E1 you&#39;re interested in, either via a DXC or a monitor point, the
  GTH takes care of layers one and two. That leaves MTP-3 and ISUP to
  you.
&lt;/p&gt;

&lt;p&gt;
  The easiest way to decode MTP-3 and ISUP is to let &lt;a
							href=&quot;http://www.wireshark.org/&quot;&gt;wireshark&lt;/a&gt; do it for you. There&#39;s
  a &lt;a
       href=&quot;//www.corelatus.com/gth/api/save_to_pcap/index.html&quot;&gt;note&lt;/a&gt;
  about how to do that on Corelatus&#39; official site. But this blog entry
  is about how to decode MTP-3 and ISUP yourself.
&lt;/p&gt;

&lt;h3&gt;A signal unit (packet)&lt;/h3&gt;

&lt;p&gt;
  In SS7, packets are usually called &quot;signal units&quot;. Here&#39;s what an SS7
  signal unit looks like &#39;on the wire&#39;, octet by octet, with MTP-2 and
  MTP-1 already decoded:
&lt;/p&gt;

&lt;pre&gt;
  8d c8 1f 85 02 40 00 00  35 00 01 00 21 00 0a 02
  02 08 06 01 10 12 52 55  21 0a 06 07 01 11 13 53
  55 00 6e 00
&lt;/pre&gt;

&lt;h3&gt;MTP-3&lt;/h3&gt;

&lt;p&gt; The start of the packet is the MTP-2 (ITU-T Q.703) and MTP-3
  (ITU-T Q.704) headers. These headers are easy to decode because they
  are always fixed-length:
&lt;/p&gt;

&lt;table style=&quot;height:118px;&quot; border=&quot;0&quot;&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;th&gt;Octet(s)&lt;/th&gt;
      &lt;th&gt;Value&lt;/th&gt;
      &lt;th&gt;Purpose&lt;/th&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;00--01&lt;/td&gt;
      &lt;td&gt;8d c8&lt;/td&gt;
      &lt;td&gt;MTP-2 sequence numbers, safe to ignore&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;02&lt;/td&gt;
      &lt;td&gt;1f&lt;/td&gt;
      &lt;td&gt;MTP-2 length indicator. Anything less than 3 is reserved for MTP-2 itself and should be discarded.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;03&lt;/td&gt;
      &lt;td&gt;85&lt;/td&gt;
      &lt;td&gt;MTP-2 SIO. The SIO tells us which &#39;service&#39; the signal unit is intended for. Q.704 sections14.2.1 and 14.2.2 tell us that anything ending in hex 5 is for ISUP.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;04--07&lt;/td&gt;
      &lt;td&gt;02 40 00 00&lt;/td&gt;
      &lt;td&gt;MTP-3 Routing label. The routing label is just a &quot;from&quot; and &quot;to&quot; address in the SS7 network. For most applications we can ignore it. Q.704 figure 3 shows what&#39;s in the routing label.&lt;/td&gt;
    &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;
  Upshot: to see calls start and stop, all we have to do for MTP-3 is:
&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Look at the length indicator (offset 2) and discard 
    any signal unit where it&#39;s less than 3.&lt;/li&gt;

  &lt;li&gt;Look at the SIO (offset 3). Discard if (SIO &amp;amp; 0x0f != 5)&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;ISUP&lt;/h3&gt;

&lt;p&gt;
  The rest of the signal unit is ISUP. Annex C in ITU-T Q.767 tells us how to decode ISUP. ISUP is fiddly because there are several types of ISUP packets, because several of those types have optional fields and because some of those fields are variable length. Here are the octets we have left after removing MTP-2 and MTP-3:
&lt;/p&gt;

&lt;pre&gt;
  35 00 01 00 21 00 0a 02  
  02 08 06 01 10 12 52 55 
  21 0a 06 07 01 11 13 53 
  55 00 6e 00
&lt;/pre&gt;

&lt;p&gt;
  The first two octets are the CIC. The third octet is the Message type.
&lt;/p&gt;

&lt;p&gt; The &lt;strong&gt;CIC&lt;/strong&gt; (Q.767 C.1.2) tells us which circuit this
  call uses. All the signalling for one call has the same CIC. In ITU
  networks, it&#39;s a 12-bit value packed into the field in little-endian
  byte order. In this case CIC=0x0035. We&#39;re sniffing an E1 line, so
  C.1.2.a tells us that the lower five bits correspond to the timeslot
  (timeslot 5) and the rest identifies the E1 itself.  &lt;/p&gt;

&lt;p&gt; The &lt;strong&gt;Message Type&lt;/strong&gt; (Q.767 Table C-3) field tells us
  what sort of ISUP message this signal unit is. 0x01 is an IAM. 0x10 is
  RLC. For a minimal &quot;show me what calls are going through the system&quot;
  hack, we only need to look at the IAM (comes at the start of the call,
  contains the A and B numbers) and the RLC (sent when the call is
  finished) messages.
&lt;/p&gt;

&lt;p&gt; Now we know that the CIC=0x35, that the message is an IAM and we
  still have about a dozen octets to decode. Q.767 table C-16 tells us
  how to decode an IAM. There are some uninteresting fixed-length fields
  followed by the B number and then the A number. Look at the code (or
  Q.767, section C.3.7) if you&#39;re interested in the details. All we
  really care about is that these octets &lt;/p&gt;

&lt;pre&gt;
  06 01 10 12 52 55 21
&lt;/pre&gt;

&lt;p&gt; represent the B number: 21255512. You can see the number in the
  raw data if you skip the first three octets and swap every second
  digit.  &lt;/p&gt;

&lt;p&gt;
  Turning those ISUP steps into an algorithm to decode one signal unit:
&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Save the CIC&lt;/li&gt;
  &lt;li&gt;Is the message an IAM? Decode it as an IAM, which is fiddly.&lt;/li&gt;
  &lt;li&gt;Is the message an RLC? Just print the CIC.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt; That&#39;s all you need to do to make a simple system which prints the
  start and end of each call. To do something useful, you need to
  maintain a table of in-progress calls and match up the IAM and RLC
  messages with the same CIC. You also need to handle things like
  systems restarting.  &lt;/p&gt;

&lt;h3&gt;Further reading&lt;/h3&gt;

&lt;p&gt; The ITU now have most of their standards freely available at
  www.itu.int. So one way to learn more about MTP-3 and ISUP is to read
  the standards, e.g. all the Q-series standards about signalling are &lt;a
									 href=&quot;http://www.itu.int/rec/T-REC-Q/en&quot;&gt;here&lt;/a&gt;.  &lt;/p&gt;

&lt;h3&gt;Erlang code&lt;/h3&gt;

&lt;p&gt; Everything discussed above is implemented in the ss7_sniffer.erl
  &lt;a
     href=&quot;http://www.corelatus.com/gth/api/gth_erlang_api.zip&quot;&gt;example&lt;/a&gt;
  on corelatus.com. It makes good use of Erlang&#39;s binary syntax,
  e.g. here&#39;s the MTP-3 decoder:
&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
    mtp3(&lt;span class=&quot;synStatement&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;_Sub:4&lt;/span&gt;, &lt;span class=&quot;synIdentifier&quot;&gt;Service_indicator:4&lt;/span&gt;&lt;span class=&quot;synStatement&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;, &lt;span class=&quot;synStatement&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;DPC:14&lt;/span&gt;, &lt;span class=&quot;synIdentifier&quot;&gt;OPC:14&lt;/span&gt;, &lt;span class=&quot;synIdentifier&quot;&gt;SLS:4&lt;/span&gt;,
						    Rest&lt;span class=&quot;synStatement&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;binary&lt;/span&gt;&lt;span class=&quot;synStatement&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;) &lt;span class=&quot;synStatement&quot;&gt;-&amp;gt;&lt;/span&gt; 
	&lt;span class=&quot;synStatement&quot;&gt;case&lt;/span&gt; Service_indicator &lt;span class=&quot;synStatement&quot;&gt;of&lt;/span&gt; 
	&lt;span class=&quot;synConstant&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;synStatement&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;synComment&quot;&gt;% Management &lt;/span&gt;
        ignore; 
	&lt;span class=&quot;synConstant&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;synStatement&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;synComment&quot;&gt;% Test/maintenance &lt;/span&gt;
        ignore; 
	&lt;span class=&quot;synConstant&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;synStatement&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;synComment&quot;&gt;% SCCP &lt;/span&gt;
        ignore; 
	&lt;span class=&quot;synConstant&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;synStatement&quot;&gt;-&amp;gt;&lt;/span&gt; 
        isup(DPC, OPC, SLS, Rest); 
	&lt;span class=&quot;synConstant&quot;&gt;9&lt;/span&gt; &lt;span class=&quot;synStatement&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;synComment&quot;&gt;% B-ISUP; similar to ISUP, but not compatible. &lt;/span&gt;
        ignore; 
	X &lt;span class=&quot;synStatement&quot;&gt;-&amp;gt;&lt;/span&gt; 
        &lt;span class=&quot;synIdentifier&quot;&gt;io:fwrite&lt;/span&gt;(&lt;span class=&quot;synConstant&quot;&gt;&amp;quot;ignoring SU with unexpected service indicator=&lt;/span&gt;&lt;span class=&quot;synSpecial&quot;&gt;~p\n&lt;/span&gt;&lt;span class=&quot;synConstant&quot;&gt;&amp;quot;&lt;/span&gt;, [X]) 
	&lt;span class=&quot;synStatement&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;synSpecial&quot;&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
  It looks a lot like one of the examples in the original paper about
  the binary syntax.
&lt;/p&gt;

&lt;h3&gt;Python Code&lt;/h3&gt;

&lt;p&gt;
  The same thing done in Python is fairly straightforward once you
  discover the Python &#39;struct&#39; library, which is basically the same
  thing as PERL&#39;s pack/unpack. The code is in sniff_isup.py, inside the
  &lt;a href=&quot;http://www.corelatus.com/gth/api/gth_python_examples.zip&quot;&gt;GTH
    python examples&lt;/a&gt; zip.
&lt;/p&gt;

&lt;p&gt;
  It feels like I haven&#39;t discovered whatever it is python people use to
  unpack bitfields, e.g. something neater than:
&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
    is_even = ((&lt;span class=&quot;synIdentifier&quot;&gt;ord&lt;/span&gt;(num[&lt;span class=&quot;synConstant&quot;&gt;1&lt;/span&gt;]) &amp;amp;amp; &lt;span class=&quot;synConstant&quot;&gt;0x80&lt;/span&gt;) == &lt;span class=&quot;synConstant&quot;&gt;0&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
  or, better still, a clean way to decode the MTP-3 routing label.
&lt;/p&gt;


&lt;!-- ============================== --&gt;
&lt;div class=&quot;comments&quot;&gt;
  &lt;h2&gt;Comments&lt;/h2&gt;
  &lt;h4&gt;Bartosz, 28. January 2010&lt;/h4&gt;

  &lt;p&gt;
    Hey. Just stumbled on this page while I was googling after Mtp3
    procedures. I&#39;m wondering if you have any materials that you could
    share regarding link setup - I&#39;m working on open source stacks for
    ss7. Im able to setup mtp2,3 and layer 4(signle link), now I&#39;m working
    on getting it work with more than one and frankly Qs for mtp3 are not
    very helpful.
  &lt;/p&gt;
  &lt;p&gt;
    &lt;a href=&quot;http://mobicents.org&quot;&gt;(website)&lt;/a&gt;
  &lt;/p&gt;


  &lt;!-- ============================== --&gt;
  &lt;h4&gt;Matt, 28. January 2010&lt;/h4&gt;

  &lt;p&gt;
    @Bartosz: I only really work with MTP2. My customers use MTP3, so I
    know quite a bit about it, but you probably know more. For MTP2, the
    standard is difficult to read, but comprehensive. MTP3 seems harder. I
    have a copy of &quot;Signalling in Telecommunications Networks&quot; by van
    Bosse et al, it&#39;s useful for getting started, but I always end up
    trudging through the standards.
  &lt;/p&gt;

  &lt;p&gt;
    Interesting to see someone working on an open SS7 stack. Up until now,
    I&#39;ve only been aware of openss7.org (written in C, some parts seem
    complete, the project seems to be a one-man effort).
  &lt;/p&gt;

  &lt;p&gt;
    Or: I don&#39;t think I can help much, but what you&#39;re doing looks interesting.
  &lt;/p&gt;

  &lt;p&gt;
    Matt
  &lt;/p&gt;

  &lt;!-- ============================== --&gt;
  &lt;h4&gt;Emza, September 15, 2009&lt;/h4&gt;

  &lt;p&gt;
    I found it very important but still not enough for me.  I was looking
    for ISUP MTP-3 and ISUP decoding in C or in C#(not only start and end
    singnal unit but general which includes all message types).  I would
    like to thank you but can help in my case please.
  &lt;/p&gt;

  &lt;p&gt;
    Thanks again&lt;br/&gt;
    Embza
  &lt;/p&gt;

  &lt;!-- ============================== --&gt;
  &lt;h4&gt;Matt, September 15, 2009&lt;/h4&gt;

  &lt;p&gt;
    @Emza, decoding the rest of the message types is &#39;just&#39; a matter of
    working your way through ITU-T Q.767 (ITU standards are now available
    for free at http://www.itu.int) and writing code to handle each and
    every section in the standard. Same basic idea as the messages I
    did. Doing it all is a few days of drudge work, which is why I haven&#39;t
    done it here.
  &lt;/p&gt;

  &lt;p&gt;
    About doing it in C or C#. I know nothing about C#. I work with C most
    days, though. Doing this sort of protocol decoding in C is fairly
    straightforward, but it&#39;s inevitably going to be more tedious than
    doing it in something like python, perl or erlang. In some
    applications the performance gain might be worth the extra effort.
  &lt;/p&gt;

  &lt;!-- ============================= --&gt;
  &lt;h4&gt;Meskerem David, September 15, 2009&lt;/h4&gt;

  &lt;p&gt;
    It is a great job. Keep working...
  &lt;/p&gt;

  &lt;p&gt;
    Can u please me one brief algorithm of decoding ISUP. Especially I am
    not clear how to decode the variable length parameters and the
    optional ones.
  &lt;/p&gt;

  &lt;p&gt;
    Thanks&lt;br/&gt;
    Meskerem
  &lt;/p&gt;

  &lt;!-- ============================== --&gt;
  &lt;h4&gt;Matt, September 15, 2009&lt;/h4&gt;

  &lt;p&gt;
    @Meskerem, In an IAM, the A-number and B-number parameters are
    variable length. The algorithm for finding the start is trivial, it&#39;s
    just a pointer offset. Here&#39;s what it looks like in the python example
    code:
  &lt;/p&gt;

  &lt;pre&gt;
    &lt;code&gt;

      &lt;span class=&quot;synStatement&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;synIdentifier&quot;&gt;isup_iam&lt;/span&gt;(_, CIC, sif):
      &lt;span class=&quot;synComment&quot;&gt;# First 5 octets can be ignored&lt;/span&gt;
      bnum_pointer = &lt;span class=&quot;synIdentifier&quot;&gt;ord&lt;/span&gt;(sif[&lt;span class=&quot;synConstant&quot;&gt;5&lt;/span&gt;])
      anum_pointer = &lt;span class=&quot;synIdentifier&quot;&gt;ord&lt;/span&gt;(sif[&lt;span class=&quot;synConstant&quot;&gt;6&lt;/span&gt;])
      bnum = sif[&lt;span class=&quot;synConstant&quot;&gt;5&lt;/span&gt; + bnum_pointer:]
      anum = sif[&lt;span class=&quot;synConstant&quot;&gt;7&lt;/span&gt; + anum_pointer:]
      &lt;span class=&quot;synIdentifier&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;synConstant&quot;&gt;&amp;quot;IAM called party: %s calling party: %s CIC=%d&amp;quot;&lt;/span&gt; &lt;span class=&quot;synSpecial&quot;&gt;\&lt;/span&gt;
      % (isup_number(bnum), isup_number(anum), CIC)

      &lt;span class=&quot;synComment&quot;&gt;# And here&#39;s how the example code figures out the length:&lt;/span&gt;

      &lt;span class=&quot;synComment&quot;&gt;# Decode an ISUP number, as per C 3.7&lt;/span&gt;
      &lt;span class=&quot;synStatement&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;synIdentifier&quot;&gt;isup_number&lt;/span&gt;(num):
      length = &lt;span class=&quot;synIdentifier&quot;&gt;ord&lt;/span&gt;(num[&lt;span class=&quot;synConstant&quot;&gt;0&lt;/span&gt;]) - &lt;span class=&quot;synConstant&quot;&gt;2&lt;/span&gt;
    
&lt;/code&gt;
  &lt;/pre&gt;

  &lt;p&gt;
    the complete code is at
    http://www.corelatus.com/gth/api/gth_python_examples.zip
  &lt;/p&gt;

  &lt;p&gt;
    (the site also has exactly the same decoding routines in Perl and Erlang)
  &lt;/p&gt;
&lt;/div&gt;

</description>
	</item>
	
        </channel>
</rss>

