<?xml version="1.0" encoding="utf-8"?>
<rss version='2.0' xmlns:lj='http://www.livejournal.org/rss/lj/1.0/'>
	<channel>
		<title>The Corelatus Blog - Entries tagged gth</title>
		<description>Entries tagged gth</description>
                <link>../../</link>

	
	<item>
		<title>Erlang example code for GTH</title>
		<link>../../Erlang_example_code_for_GTH.html</link>        
		<guid isPermaLink="true">../../Erlang_example_code_for_GTH.html</guid>
                <pubDate>Sun, 1 Feb 2009 16:55:04 GMT</pubDate>
		<description>&lt;p&gt;
Years ago, I wrote a few bits of example code to help customers get
started with controlling a &lt;a
href=&quot;http://www.corelatus.com/&quot;&gt;GTH&lt;/a&gt;.  If you were kind, you&#39;d
call them minimal, e.g. the Erlang one was about 20 lines long.
&lt;/p&gt;

&lt;p&gt; None of our customers that use Erlang were very impressed by that,
so I&#39;d hand out part of the code we use to do API testing (a cut-down
XML parser and a little library to handle sockets) along with sternly
issued instructions that this was just example code and that live
systems needed something more robust. Not great, but I had other
things to do.  &lt;/p&gt;

&lt;p&gt;
I finally got around to completing and releasing a proper native
Erlang API for the GTH. No (visible) XML. It&#39;s a gen_server, so it&#39;s
well-behaved and simple enough so that you can do almost anything from
the Erlang shell, e.g. to turn on an E1:
&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; {ok, A} &lt;span class=&quot;synStatement&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;synIdentifier&quot;&gt;gth:start_link&lt;/span&gt;(&lt;span class=&quot;synConstant&quot;&gt;&amp;quot;172.16.2.7&amp;quot;&lt;/span&gt;)&lt;span class=&quot;synSpecial&quot;&gt;.&lt;/span&gt;
{ok, &lt;span class=&quot;synStatement&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;synConstant&quot;&gt;0.44&lt;/span&gt;&lt;span class=&quot;synSpecial&quot;&gt;.&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;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;gth:set&lt;/span&gt;(A, &lt;span class=&quot;synConstant&quot;&gt;&amp;quot;pcm1B&amp;quot;&lt;/span&gt;, [{&lt;span class=&quot;synConstant&quot;&gt;&amp;quot;status&amp;quot;&lt;/span&gt;, &lt;span class=&quot;synConstant&quot;&gt;&amp;quot;enabled&amp;quot;&lt;/span&gt;}])&lt;span class=&quot;synSpecial&quot;&gt;.&lt;/span&gt;
ok
&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;
and put an audio file on a timeslot:
&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;
&lt;span class=&quot;synConstant&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;synStatement&quot;&gt;&amp;gt;&lt;/span&gt; {ok, Bin} &lt;span class=&quot;synStatement&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;synIdentifier&quot;&gt;file:read_file&lt;/span&gt;(&lt;span class=&quot;synConstant&quot;&gt;&amp;quot;/tmp/resample_q_alaw.raw&amp;quot;&lt;/span&gt;)&lt;span class=&quot;synSpecial&quot;&gt;.&lt;/span&gt;
{ok,&lt;span class=&quot;synStatement&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;synSpecial&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;synStatement&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;}
&lt;span class=&quot;synConstant&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;synStatement&quot;&gt;&amp;gt;&lt;/span&gt; {ok, _ID, P_socket} &lt;span class=&quot;synStatement&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;synIdentifier&quot;&gt;gth:new_tcp_player&lt;/span&gt;(A, &lt;span class=&quot;synConstant&quot;&gt;&amp;quot;1B&amp;quot;&lt;/span&gt;, &lt;span class=&quot;synConstant&quot;&gt;2&lt;/span&gt;)&lt;span class=&quot;synSpecial&quot;&gt;.&lt;/span&gt;
{ok,&lt;span class=&quot;synConstant&quot;&gt;&amp;quot;strp1&amp;quot;&lt;/span&gt;,#Port&lt;span class=&quot;synStatement&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;synConstant&quot;&gt;0.1097&lt;/span&gt;&lt;span class=&quot;synStatement&quot;&gt;&amp;gt;&lt;/span&gt;}
&lt;span class=&quot;synConstant&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;synStatement&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;synIdentifier&quot;&gt;gen_tcp:send&lt;/span&gt;(P_socket, Bin)&lt;span class=&quot;synSpecial&quot;&gt;.&lt;/span&gt;
ok
&lt;span class=&quot;synConstant&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;synStatement&quot;&gt;&amp;gt;&lt;/span&gt; flush()&lt;span class=&quot;synSpecial&quot;&gt;.&lt;/span&gt;
&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;
There&#39;s a direct mapping between GTH commands and function names in
the gth.erl module, e.g. the XML &amp;lt;set&amp;gt; command becomes
gth:set(). While writing the gth.erl module, I also rewrote our entire
API test suite (60 modules, 30kloc) to use the gth.erl interface. It
ended up under 20kloc. I&#39;d guess half of that reduction comes from
gth.erl being nicer to use and the other half comes from cleaning up
&quot;while I was at it&quot;.
&lt;/p&gt;

&lt;p&gt;
The code, with examples: &lt;a
href=&quot;http://www.corelatus.com/gth/api/gth_erlang_api.zip&quot;&gt;gth_erlang_api.zip&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
While writing gth.erl, I had a go at doing something similar in
Python. But that&#39;s another story.
&lt;/p&gt;
</description>
	</item>
	
	<item>
		<title>SOX parameters for downsampling to 8kHz Alaw</title>
		<link>../../SOX_parameters_for_downsampling_to_8kHz_Alaw.html</link>        
		<guid isPermaLink="true">../../SOX_parameters_for_downsampling_to_8kHz_Alaw.html</guid>
                <pubDate>Thu, 19 Feb 2009 16:50:16 GMT</pubDate>
		<description>&lt;p&gt; A technician working for an operator mailed me a few days ago
wondering why the recorded voice clips they use for their IVR sound so
bad, &quot;like they&#39;re coming from the bottom of a deep well&quot;. It turned
out that the clips actually sounded OK on a telephone, just not
through his laptop&#39;s speaker. He asked if I recommend any specific
filter parameters when converting audio from 44.1kHz wav to 8kHz Alaw
voice clips.
&lt;/p&gt;

&lt;h4&gt;An example&lt;/h4&gt;

&lt;p&gt;
I took this audio snippet from the introduction to an audio book. It
was originally a .ogg file. I converted it to a .wav file with a
44.1kHz sampling rate and 16 bits per sample. For my purposes any
artefacts from ogg vorbis are negligible.
&lt;/p&gt;

&lt;a href=&quot;http://www.corelatus.com/%7Ematthias/1_mono.wav&quot;&gt;1_mono.wav&lt;/a&gt; (44.1kHz, 16 bit linear samples)

&lt;p&gt;
Next, I converted it to 8kHz Alaw using &lt;a
href=&quot;http://sox.sourceforge.net/&quot;&gt;sox&lt;/a&gt;. 8kHz Alaw is what runs on
the fixed telephone network in most of the world.  (The US uses a
minor variant, &amp;#956;law):
&lt;/p&gt;

&lt;pre&gt;sox 1_mono.wav -A -r 8000 2_8kHz_alaw.wav&lt;/pre&gt;

&lt;a href=&quot;http://www.corelatus.com/%7Ematthias/2_8kHz_alaw.wav&quot;&gt;2_8kHz_alaw.wav&lt;/a&gt; (8kHz, 8 bit Alaw samples)

&lt;p&gt; That sounds a bit less clear than the original, but it&#39;s OK. It&#39;s
what you&#39;d expect coming out of a telephone. There&#39;s some weirdness
though. The audible difference between the two files varies from one
PC to another and even one playback program to another. Why? Because
laptop speakers vary in quality and because playback programs usually
quietly convert everything back to 48kHz or 44.1kHz sampling rates,
and they do it with different approaches. For fun, I resampled to
44.1kHz:
&lt;/p&gt;

&lt;pre&gt;sox 2_8kHz_alaw.wav -r 44100 -s 3_resampled.wav&lt;/pre&gt;

&lt;a href=&quot;http://www.corelatus.com/%7Ematthias/3_resampled.wav&quot;&gt;3_resampled.wav&lt;/a&gt; (44.1kHz, 16 bit linear samples)

&lt;p&gt; 2_8kHz_alaw.wav and 3_resampled.wav should sound almost the
same. But on some PCs they sound markedly different.  
&lt;/p&gt;

&lt;h5&gt;The GTH just plays octets (bytes)&lt;/h5&gt; 

&lt;p&gt;
The GTH has a simple approach to playing
back audio. It just copies the bytes you give it to the destination
timeslot. No format or rate conversion happens, though the GTH does
make sure the data is played out at the E1&#39;s frame rate (8000Hz). The
downside of that is that you have to convert all the files for your
IVR system before giving them to a GTH, e.g. using sox. The upside is
that it&#39;s simple. Nothing happens behind your back.
&lt;/p&gt;

&lt;h4&gt;What are the best SOX options to use?&lt;/h4&gt; 

&lt;p&gt;
I don&#39;t know. I used to suggest the following as a reasonable starting
point:
&lt;/p&gt;

&lt;pre&gt;sox original.wav -r 8000 -c 1 -A -t raw gth.raw resample -q&lt;/pre&gt;

&lt;p&gt;
As of a few years ago, sox improved and the &#39;resample&#39; effect got
deprecated. So now I suggest just letting sox do what it thinks is
best:
&lt;/p&gt;

&lt;pre&gt;sox original.wav -r 8000 -c 1 -A -t raw gth.raw&lt;/pre&gt;

&lt;p&gt; At the time of writing, it uses its &#39;rate&#39; effect with reasonable
default parameters for the bandwidth and filter characteristics. I
experimented a bit with the -m, -h, -v and -s switches for the &#39;rate&#39;
effect. I could not reliably hear a difference, let alone decide that
one sounded better.
&lt;/p&gt;

&lt;h4&gt;Why does the phone system use 8kHz anyway?&lt;/h4&gt;

&lt;p&gt;
There&#39;s a certain sound quality level expected in telephone networks,
and part of that is that the network carries everything up to about
3500Hz. Analog local loop specifications mention that, and pretty much
all digital telephone systems use an 8kHz sampling rate, which is what
you need to be able to carry audio up to 3.5kHz. Even the GSM and AMR
codecs start off with the assumption that the incoming audio is
limited to 3500Hz.
&lt;/p&gt;

&lt;p&gt;
So the bar is set pretty low. I haven&#39;t come across any systems which
set out to provide higher quality, e.g. even skype compresses the hell
out of the audio to save bandwidth. Even when both parties in a
conversation have huge amounts of it. Surprising, why not aim for VOIP
to sound much better than a regular telephone?
&lt;/p&gt;
</description>
	</item>
	
	<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>
	
	<item>
		<title>Perl example code for GTH: SS7 ISUP decoding and playback/record</title>
		<link>../../Perl_example_code_for_GTH__SS7_ISUP_decoding_and_playback_record.html</link>        
		<guid isPermaLink="true">../../Perl_example_code_for_GTH__SS7_ISUP_decoding_and_playback_record.html</guid>
                <pubDate>Thu, 28 May 2009 23:25:45 +0200</pubDate>
		<description>&lt;p&gt;
To help people get started, www.corelatus.com has some example code
for doing useful things with GTH units.
&lt;/p&gt;

&lt;p&gt;
Now it also has Perl example code. It does the same thing as the
python examples:
&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Enable an E1/T1 port
  &lt;/li&gt;&lt;li&gt;Start MTP-2 monitoring on a timeslot and decode SS7 ISUP (to print out when calls start and stop). I wrote a post a while back about &lt;a href=&quot;http://blog.corelatus.com/2009/03/25/decoding-mtp-3-and-isup/&quot;&gt;how to decode ISUP&lt;/a&gt;.
  &lt;/li&gt;&lt;li&gt;Dump the contents of a timeslot to a file (for later analysis)
  &lt;/li&gt;&lt;li&gt;Feed a file into a timeslot (for playback of previously captured files)
&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt; It&#39;s built on top of a Perl module which provides a Perl API for a
subset of the &lt;a href=&quot;http://www.corelatus.com/gth/api/&quot;&gt;GTH API&lt;/a&gt;.
&lt;/p&gt;

&lt;h3&gt;A quick example&lt;/h3&gt;

&lt;p&gt; Here&#39;s a quick example of how it&#39;s used. We want to enable (turn
on) the first E1/T1 interface on a GTH module: &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
&lt;span class=&quot;synStatement&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;synIdentifier&quot;&gt;$api&lt;/span&gt; = gth_control-&amp;gt;&lt;span class=&quot;synStatement&quot;&gt;new&lt;/span&gt;(&lt;span class=&quot;synIdentifier&quot;&gt;$host&lt;/span&gt;);
&lt;span class=&quot;synIdentifier&quot;&gt;$api&lt;/span&gt;-&amp;gt;&lt;span class=&quot;synStatement&quot;&gt;send&lt;/span&gt;(&lt;span class=&quot;synConstant&quot;&gt;&amp;quot;&amp;lt;set name=&#39;pcm&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;$span&lt;/span&gt;&lt;span class=&quot;synConstant&quot;&gt;&#39;&amp;gt;&amp;lt;attribute name=&#39;mode&#39; value=&#39;E1&#39;/&amp;gt;&amp;lt;/set&amp;gt;&amp;quot;&lt;/span&gt;);
&lt;span class=&quot;synStatement&quot;&gt;defined&lt;/span&gt; &lt;span class=&quot;synIdentifier&quot;&gt;$api&lt;/span&gt;-&amp;gt;next_non_event()-&amp;gt;{ok} || &lt;span class=&quot;synStatement&quot;&gt;die&lt;/span&gt;(&lt;span class=&quot;synConstant&quot;&gt;&amp;quot;error from GTH (bogus PCM?)&amp;quot;&lt;/span&gt;);
&lt;span class=&quot;synIdentifier&quot;&gt;$api&lt;/span&gt;-&amp;gt;bye();
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;It&#39;s good for experimenting.&lt;/h3&gt;

&lt;p&gt; The Perl module the examples are based on, gth_control.pm, is at
a level which makes it useful for experiments and prototypes. To build
a full-fledged product on top of it, more work is needed.
&lt;/p&gt;

&lt;p&gt; For a start, you&#39;d probably want to move the XML generation (like
the &#39;&amp;lt;set name=...&#39; code above) out of the application code and
into the gth_control.pm module, thus making it a pure Perl interface.
&lt;/p&gt;

&lt;p&gt;
Next, you need to come up with a strategy to deal with concurrency, because being limited to recording one timeslot at a time is fine for lab work, but not fine for (say) a voicemail system.
&lt;/p&gt;

&lt;h3&gt;Download&lt;/h3&gt;

&lt;p&gt;
The zipfile of the code is linked from 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>Generating DTMF using a &amp;#039;player&amp;#039; on GTH</title>
		<link>../../Generating_DTMF_using_a___039_player__039__on_GTH.html</link>        
		<guid isPermaLink="true">../../Generating_DTMF_using_a___039_player__039__on_GTH.html</guid>
                <pubDate>Tue, 9 Jun 2009 12:31:17 +0200</pubDate>
		<description>&lt;p&gt;
The GTH can &lt;em&gt;transmit&lt;/em&gt; in-band signalling tones on a
timeslot. That&#39;s useful for testing and for building active in-band
signalling systems.
&lt;/p&gt;

&lt;h3&gt;DTMF&lt;/h3&gt;

&lt;p&gt;
The tones transmitted when the subscriber presses a number key on
fixed or mobile handset are called DTMF. Wikipedia has an &lt;a
href=&quot;http://en.wikipedia.org/wiki/DTMF&quot;&gt;article&lt;/a&gt; about it. To
generate DTMF, all we really need to know is that there are 16
possible DTMF signals, that each signal is made up of two sine waves
of particular frequencies and that sending the signal for 100ms is a
reasonable thing to do.
&lt;/p&gt;

&lt;p&gt;
Here&#39;s a .zip file with &lt;a
href=&quot;http://www.corelatus.com/~matthias/blog/dtmf_tones.zip&quot;&gt;DTMF
tones&lt;/a&gt; in it. Each file is raw ALAW data, i.e. it&#39;s ready for the
GTH to play (transmit) on a timeslot.
&lt;/p&gt;

&lt;p&gt;
The GTH has two ways of playing tones. One way is to stream the audio
data in over a TCP socket each time we want to play it. I wrote a &lt;a
href=&quot;http://blog.corelatus.com/2009/03/06/gth-audio-streaming-why-stream-over-tcp/&quot;&gt;post
about that&lt;/a&gt; earlier. The other way is to store the sample data on
the GTH and command its playback whenever it&#39;s needed. Since there&#39;s a
small number of different tones (12, or 16 if you want to use the
A/B/C/D tones as well) and the tones are short, storing them on the
GTH makes sense. To store the tone:
&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;
&lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;new&amp;gt;&amp;lt;clip &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;dtmf5&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;&amp;gt;&amp;lt;/new&amp;gt;&lt;/span&gt;
(and now send the 800 byte file)
&lt;/code&gt;
&lt;/pre&gt;

to play the tone later on:

&lt;pre&gt;
&lt;code&gt;
&lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;new&amp;gt;&amp;lt;player&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;clip &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;clip dtmf5&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;pcm_sink &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;span&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;3A&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt; &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;timeslot&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;19&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;/player&amp;gt;&amp;lt;/new&amp;gt;&lt;/span&gt; 
&lt;/code&gt;
&lt;/pre&gt;

&lt;h3&gt;Sequences of tones&lt;/h3&gt;

&lt;p&gt;
Sometimes you want to transmit a sequence of DTMF tones, for instance to simulate a subscriber dialling a number. The GTH lets you start a player with a sequence of tones like this:
&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;
&lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;new&amp;gt;&amp;lt;player&amp;gt;&lt;/span&gt;
   &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;clip &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;clip dtmf5&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;/&amp;gt;&amp;lt;clip &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;clip dtmf6&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;/&amp;gt;&amp;lt;clip &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;clip dtmf8&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;/&amp;gt;&lt;/span&gt;
   &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;pcm_sink &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;span&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;3A&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt; &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;timeslot&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;19&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;/player&amp;gt;&amp;lt;/new&amp;gt;&lt;/span&gt;
&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;
But that isn&#39;t a valid sequence of DTMF tones. Why not? Because DTMF
expects a gap between tones. The cleanest way to handle that is to
define another clip consisting of just silence and putting it between
each tone. A good &#39;silence&#39; value on E1 lines is 0x54. 60ms (480
samples) is a reasonable length.
&lt;/p&gt;

&lt;h3&gt;Other in-band tones&lt;/h3&gt;

&lt;p&gt;
DTMF in-band signalling is used in pretty much all handsets
(telephones), mostly for dialling, but also to navigate menus in IVR
systems. But before SS7 became popular, in-band signalling in the form
of CAS and SS5 was even used to communicate call setup information
between exchanges. GTH can also generate those tones, but that can be
the subject of another post.
&lt;/p&gt;
</description>
	</item>
	
	<item>
		<title>How does TCP behave on an interrupted network?</title>
		<link>../../How_does_TCP_behave_on_an_interrupted_network_.html</link>        
		<guid isPermaLink="true">../../How_does_TCP_behave_on_an_interrupted_network_.html</guid>
                <pubDate>Thu, 27 Aug 2009 23:24:22 GMT</pubDate>
		<description>&lt;p&gt;
GTH E1/T1 modules are always controlled by a general-purpose server,
usually some sort of unix machine. The server and GTH are connected by
ethernet and communicate using TCP sockets. Normally, that ethernet
connection is chosen to be simple and reliable, for instance by
putting the server and the GTH in the same rack, connected to the same
ethernet switch.
&lt;/p&gt;

&lt;p&gt;
I experimented a bit to see what happens when that network gets
interrupted. I interrupted the network in a reproduceable way by
disabling and re-enabling the server&#39;s ethernet port for a known
length of time while running a &amp;lt;recorder&amp;gt;. (A &amp;lt;recorder&amp;gt;
sends all the data, typically someone talking, from an E1 timeslot to
the server over a TCP socket, 8000 octets per second.)
&lt;/p&gt;

&lt;h3&gt;Capturing the ethernet packets&lt;/h3&gt;

&lt;p&gt;
Here&#39;s what I did to capture traffic and interrupt the ethernet:
&lt;/p&gt;

  &lt;pre&gt;
  tcpdump -w /tmp/capture.pcap -s 0 not port 22
  sudo ifconfig eth0 down; sleep 5; sudo ifconfig eth0 up
  &lt;/pre&gt;

&lt;h3&gt;A trace where traffic recovers in time to prevent an overrun&lt;/h3&gt;

&lt;p&gt;
The GTH buffers about two seconds of timeslot traffic. So a &#39;sleep&#39; of
about a second won&#39;t result in an overrun. Here&#39;s what it looks like
in wireshark:
&lt;/p&gt;

&lt;table&gt;
&lt;tr&gt;&lt;td&gt;Packet&lt;/td&gt;&lt;td&gt;Time&lt;/td&gt;&lt;td&gt;Direction&lt;/td&gt;&lt;td&gt;Flags&lt;/td&gt;&lt;td&gt;Seq. #&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;5&quot;&gt;&lt;hr /&gt;&lt;/td&gt;

&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;133 &lt;/td&gt;&lt;td&gt;  7.596 &lt;/td&gt;&lt;td&gt;  GTH -&amp;gt; server&lt;/td&gt;&lt;td&gt; [PSH, ACK] &lt;/td&gt;&lt;td&gt;59393&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;134 &lt;/td&gt;&lt;td&gt;  7.633 &lt;/td&gt;&lt;td&gt;  server -&amp;gt; GTH&lt;/td&gt;&lt;td&gt; [ACK]      &lt;/td&gt;&lt;td&gt;1    &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;135 &lt;/td&gt;&lt;td&gt;  7.724 &lt;/td&gt;&lt;td&gt;  GTH -&amp;gt; server&lt;/td&gt;&lt;td&gt; [PSH, ACK] &lt;/td&gt;&lt;td&gt;60417&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;136 &lt;/td&gt;&lt;td&gt;  7.761 &lt;/td&gt;&lt;td&gt;  server -&amp;gt; GTH&lt;/td&gt;&lt;td&gt; [ACK]      &lt;/td&gt;&lt;td&gt;1	       &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;137 &lt;/td&gt;&lt;td&gt;  7.852 &lt;/td&gt;&lt;td&gt;  GTH -&amp;gt; server&lt;/td&gt;&lt;td&gt; [PSH, ACK] &lt;/td&gt;&lt;td&gt;61441&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;138 &lt;/td&gt;&lt;td&gt;  7.889 &lt;/td&gt;&lt;td&gt;  server -&amp;gt; GTH&lt;/td&gt;&lt;td&gt; [ACK] &lt;/td&gt;&lt;td&gt;1	       &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;139 &lt;/td&gt;&lt;td&gt;  7.980 &lt;/td&gt;&lt;td&gt;  GTH -&amp;gt; server&lt;/td&gt;&lt;td&gt; [PSH, ACK] &lt;/td&gt;&lt;td&gt;62465&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;140 &lt;/td&gt;&lt;td&gt;  8.017 &lt;/td&gt;&lt;td&gt;  server -&amp;gt; GTH&lt;/td&gt;&lt;td&gt; [ACK] &lt;/td&gt;&lt;td&gt;1	       &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;141 &lt;/td&gt;&lt;td&gt;  8.108 &lt;/td&gt;&lt;td&gt;  GTH -&amp;gt; server&lt;/td&gt;&lt;td&gt; [PSH, ACK] &lt;/td&gt;&lt;td&gt;63489&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;142 &lt;/td&gt;&lt;td&gt;  8.145 &lt;/td&gt;&lt;td&gt;  server -&amp;gt; GTH&lt;/td&gt;&lt;td&gt; [ACK] &lt;/td&gt;&lt;td&gt;1	       &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;143 &lt;/td&gt;&lt;td&gt;  8.236 &lt;/td&gt;&lt;td&gt;  GTH -&amp;gt; server&lt;/td&gt;&lt;td&gt; [PSH, ACK] &lt;/td&gt;&lt;td&gt;64513&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;144 &lt;/td&gt;&lt;td&gt;  8.273 &lt;/td&gt;&lt;td&gt;  server -&amp;gt; GTH&lt;/td&gt;&lt;td&gt; [ACK] &lt;/td&gt;&lt;td&gt;1	       &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;145 &lt;/td&gt;&lt;td&gt;  8.364 &lt;/td&gt;&lt;td&gt;  GTH -&amp;gt; server&lt;/td&gt;&lt;td&gt; [PSH, ACK] &lt;/td&gt;&lt;td&gt;65537&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;146 &lt;/td&gt;&lt;td&gt;  8.401 &lt;/td&gt;&lt;td&gt;  server -&amp;gt; GTH&lt;/td&gt;&lt;td&gt; [ACK] &lt;/td&gt;&lt;td&gt;1	       &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;147 &lt;/td&gt;&lt;td&gt; 10.151 &lt;/td&gt;&lt;td&gt;  GTH -&amp;gt; server&lt;/td&gt;&lt;td&gt; [PSH, ACK] &lt;/td&gt;&lt;td&gt;66561&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;148 &lt;/td&gt;&lt;td&gt; 10.151 &lt;/td&gt;&lt;td&gt;  server -&amp;gt; GTH&lt;/td&gt;&lt;td&gt; [ACK] &lt;/td&gt;&lt;td&gt;1	       &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;149 &lt;/td&gt;&lt;td&gt; 10.151 &lt;/td&gt;&lt;td&gt;  GTH -&amp;gt; server&lt;/td&gt;&lt;td&gt; [ACK] &lt;/td&gt;&lt;td&gt;67585     &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;150 &lt;/td&gt;&lt;td&gt; 10.151 &lt;/td&gt;&lt;td&gt;  server -&amp;gt; GTH&lt;/td&gt;&lt;td&gt; [ACK] &lt;/td&gt;&lt;td&gt;1         &lt;/td&gt;&lt;/tr&gt;

&lt;/table&gt;

&lt;p&gt;
Everything up to packet 146 is normal: the GTH (172.16.2.5) sends 8000
octets every second and the server (172.16.2.1) acks them. It happens
to be in chunks of 1024 octets about eight times per second. After
packet 146, about 8.4 seconds after the capture started, the ethernet
interface went down and stayed down for 1s. The TCP stream started up
again after about 1.5s and then &#39;caught up&#39; by sending many packets in
quick succession.
&lt;/p&gt;

&lt;h3&gt;A trace where traffic didn&#39;t recover&lt;/h3&gt;

&lt;p&gt;
I took a second trace similar to the first one, except this time, I
disabled ethernet for about five seconds:
&lt;/p&gt;

&lt;pre&gt;
Packet Time     Source IP     Dest IP    SPort   DPort
----------------------------------------------------------------------
 28   1.040083  172.16.2.5 -&amp;gt; 172.16.2.1 54271 &amp;gt; 45195 [PSH, ACK] Seq=7169
 29   1.040095  172.16.2.1 -&amp;gt; 172.16.2.5 45195 &amp;gt; 54271 [ACK] Seq=1
 30   1.168065  172.16.2.5 -&amp;gt; 172.16.2.1 54271 &amp;gt; 45195 [PSH, ACK] Seq=8193
 31   1.168078  172.16.2.1 -&amp;gt; 172.16.2.5 45195 &amp;gt; 54271 [ACK] Seq=1 
 32   1.296067  172.16.2.5 -&amp;gt; 172.16.2.1 54271 &amp;gt; 45195 [PSH, ACK] Seq=9217
 33   1.296079  172.16.2.1 -&amp;gt; 172.16.2.5 45195 &amp;gt; 54271 [ACK] Seq=1 
 34   1.424068  172.16.2.5 -&amp;gt; 172.16.2.1 54271 &amp;gt; 45195 [PSH, ACK] Seq=10241
 35   1.424081  172.16.2.1 -&amp;gt; 172.16.2.5 45195 &amp;gt; 54271 [ACK] Seq=1
 36   7.782851  172.16.2.5 -&amp;gt; 172.16.2.1 54271 &amp;gt; 45195 [PSH, ACK] Seq=11265
 37   7.782863  172.16.2.1 -&amp;gt; 172.16.2.5 45195 &amp;gt; 54271 [ACK] Seq=1
 38   7.783406  172.16.2.5 -&amp;gt; 172.16.2.1 54271 &amp;gt; 45195 [ACK] Seq=12289
 39   7.783413  172.16.2.1 -&amp;gt; 172.16.2.5 45195 &amp;gt; 54271 [ACK] Seq=1
 40   7.783569  172.16.2.5 -&amp;gt; 172.16.2.1 54271 &amp;gt; 45195 [ACK] Seq=13737
...
 50   7.784962  172.16.2.5 -&amp;gt; 172.16.2.1 54271 &amp;gt; 45195 [FIN, PSH, ACK] Seq=23873
 51   7.784972  172.16.2.1 -&amp;gt; 172.16.2.5 45195 &amp;gt; 54271 [ACK] Seq=1
 52   7.785026  172.16.2.1 -&amp;gt; 172.16.2.5 45195 &amp;gt; 54271 [FIN, ACK] Seq=1
 53   7.785348  172.16.2.5 -&amp;gt; 172.16.2.1 54271 &amp;gt; 45195 [ACK] Seq=25322
&lt;/pre&gt;

&lt;p&gt; Everything is normal up to packet 35. Then, ethernet is suspended
for five seconds and TCP takes a further second to recover, which
causes a buffer overrun on the GTH (172.16.2.5). The GTH closes the
socket at packet 50 and also sends an overrun event to the application
so that it knows why the socket was closed.
&lt;/p&gt;

&lt;h3&gt;Bottom line&lt;/h3&gt;

&lt;p&gt;
GTH uses IP for control and traffic. It is important that the IP link
between the GTH and the server is simple and reliable. Ideally the GTH
and server should be in the same rack and be connected by an ethernet
switch.
&lt;/p&gt;

&lt;p&gt; It&#39;s possible for a system to survive a short interruption (less
than a second) to the ethernet traffic without pre-recorded calls
getting interrupted. For longer interruptions, all bets are off.  &lt;/p&gt;

&lt;p&gt; (Interruptions aren&#39;t the only type of network problem, e.g. radio
networks such as 802.11 can suffer significant packet loss, which can
trigger TCP congestion avoidance. But that&#39;s another
topic.) &lt;/p&gt;
</description>
	</item>
	
	<item>
		<title>Audio power levels on E1/T1 timeslots: the digital milliwatt</title>
		<link>../../Audio_power_levels_on_E1_T1_timeslots__the_digital_milliwatt.html</link>        
		<guid isPermaLink="true">../../Audio_power_levels_on_E1_T1_timeslots__the_digital_milliwatt.html</guid>
                <pubDate>Sat, 10 Oct 2009 21:33:52 +0200</pubDate>
		<description>&lt;p&gt;
Sometimes, you want to know when the audio on an E1/T1 timeslot has
gotten louder than some limit. In a voice mail application, that&#39;s
useful for catching mistakes such as a subscriber leaving a message
but then not hanging up the phone properly---you don&#39;t want to record
hours and hours of silence. In an IVR application, you might want to
keep an eye on the audio level so that a frustrated (shouting!)
subscriber can be forwarded to a human operator.
&lt;/p&gt;

&lt;p&gt;
GTH provides a &quot;level detector&quot; to do that sort of thing. You start a
level detector on a timeslot, give it a loudness threshold, and it&#39;ll
notify you whenever the audio on the timeslot goes over that
threshold. Here&#39;s an example command which notifies you if the power
on timeslot 13 of an E1/T1 is louder than -20dBm0:
&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;
  &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;new&amp;gt;&amp;lt;level_detector &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;threshold&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;-20&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;&amp;gt;&lt;/span&gt;
     &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;pcm_source &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;span&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;2A&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt; &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;timeslot&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;13&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;/level_detector&amp;gt;&amp;lt;/new&amp;gt;&lt;/span&gt;
&lt;/code&gt;
&lt;/pre&gt;

The algorithm is:

&lt;ol&gt;
  &lt;li&gt;Take a 100ms block of audio (800 samples)&lt;/li&gt;
  &lt;li&gt;Square all the samples&lt;/li&gt;
  &lt;li&gt;Sum the squares&lt;/li&gt;
  &lt;li&gt;If the sum exceeds the loudness threshold, send an XML event&lt;/li&gt;
&lt;/ol&gt;

There are some details to worry about.

&lt;h3&gt;The digital milliwatt&lt;/h3&gt;

&lt;p&gt; The threshold, e.g. -20 in the example above, has to be relative
to something. The standard reference power level in telecommunications
is the milliwatt.  ITU-T G.711, table 5 and 6 defines the sequences
which represent a milliwatt:
&lt;/p&gt;

&lt;p&gt;
A-law: 34 21 21 34 b4 a1 a1 b4&lt;br/&gt;
&amp;#956;-law: 1e 0b 0b 1e 9e 8b 8b 9e&lt;br/&gt;
&lt;/p&gt;

&lt;p&gt;
Here&#39;s what a few periods of the digital milliwatt look like:
&lt;/p&gt;

&lt;img
src=&quot;static/small_linear_milliwatt.png&quot;
alt=&quot;small_linear_milliwatt&quot; title=&quot;small_linear_milliwatt&quot;/&gt;

&lt;p&gt;
In this post, the unit &#39;dBm0&#39; means power, in dB relative to the digital milliwatt, as defined by the sequences above. If you have no idea what dB means, wikipedia has a &lt;a href=&quot;http://en.wikipedia.org/wiki/Decibel&quot;&gt;decent article&lt;/a&gt;.
&lt;/p&gt;

&lt;h3&gt;What&#39;s the loudest possible sound on a timeslot?&lt;/h3&gt;

&lt;p&gt; 170 is the highest value possible in A-law encoding. It
corresponds to linear 4032. That&#39;s about 6dB louder than the digital
milliwatt.
&lt;/p&gt;

&lt;p&gt; 85 is the smallest value possible in A-law encoding. It
corresponds to linear -1. That&#39;s about 66dB softer than the digital
milliwatt.
&lt;/p&gt;

&lt;p&gt; The range -66dBm0...+6dBm0 sets an upper bound on the range of
power on a timeslot. Then there are other things which further limit
the practical range, so you&#39;re unlikely to actually use a +6dBm0
threshold in practice, but it&#39;s there if you want it.
&lt;/p&gt;

&lt;h3&gt;Is the G.711 definition the best one?&lt;/h3&gt;

&lt;p&gt;
The sequence given in G.711 is a 1kHz sine wave. The sampling rate on
E1/T1 is 8kHz, so the reference sequence can be expressed in just
eight values. That&#39;s nice, but that also leads to small errors, about
0.13dB, because of quantisation.
&lt;/p&gt;

&lt;p&gt;
ITU-T O.133 discusses that problem in detail and proposes a test
signal which specfically is &lt;b&gt;not&lt;/b&gt; 1kHz (i.e. not a submultiple of
the sampling rate). For most practical purposes, 0.13dB doesn&#39;t matter
and so the simple and robust thing to do is to use the well-defined
and well-known G.711 sequence as a reference.
&lt;/p&gt;

&lt;p&gt;
Here&#39;s what a few periods of a 1020Hz signal look like. Notice that
the samples, i.e. the red crosses, don&#39;t appear in the same spot one
period later---that way we don&#39;t get the same errors over and over
again.
&lt;/p&gt;

&lt;div class=&quot;image&quot;&gt;
&lt;img src=&quot;static/small_1020hz1.png&quot;
alt=&quot;1020Hz signal sampled at 125us intervals&quot;/&gt;
&lt;div&gt;1020Hz signal sampled at 125us intervals&lt;/div&gt;
&lt;/div&gt;

&lt;h3&gt;Testing pitfall: the .wav header&lt;/h3&gt;

&lt;p&gt; GTH &lt;em&gt;player&lt;/em&gt;s plays raw A-law or &amp;#956;-law data. If you feed
a player a .wav file in 8kHz A-law, or &amp;#956;-law if your network uses
&amp;#956;-law, there will be a very short bit of noise at the start of the
playback because the .wav header gets treated as though it were audio.
&lt;/p&gt;

&lt;p&gt; When testing level detection, especially at quiet levels, that
header noise is enough to trigger a detector. Here&#39;s a .wav of a
1000Hz sine wave at about -30dBm0: &lt;/p&gt;

&lt;pre&gt;
00000000  52 49 46 46 42 27 00 00  57 41 56 45 66 6d 74 20  |RIFFB&#39;..WAVEfmt |
00000010  12 00 00 00 06 00 01 00  40 1f 00 00 40 1f 00 00  |........@...@...|
00000020  01 00 08 00 00 00 66 61  63 74 04 00 00 00 10 27  |......fact.....&#39;|
00000030  00 00 64 61 74 61 10 27  00 00 d5 c4 f5 f1 f3 f1  |..data.&#39;........|
00000040  f5 c4 d5 44 75 71 73 71  75 44 d5 c4 f5 f1 f3 f1  |...DuqsquD......|
*
00002740  f5 c4 d5 44 75 71 73 71  75 44                    |...DuqsquD|
&lt;/pre&gt;

&lt;p&gt; The first 58 octets (bytes) are the header. If we turn that header
into a periodic signal, it&#39;s at about -8dBm0, which is fairly
loud. With the default &lt;em&gt;period&lt;/em&gt; parameter of 100ms in the level
detector, that&#39;ll cause a false level of about -11dBm0.
&lt;/p&gt;

&lt;h3&gt;The period parameter&lt;/h3&gt;

&lt;p&gt; The &lt;em&gt;level_detector&lt;/em&gt; has an optional parameter, the
period. The period sets the size of the audio block the GTH considers
when measuring the power. A short &lt;em&gt;period&lt;/em&gt; makes the GTH
responsive to sudden changes in power on the timeslot, which would be
useful in an application such as figuring out which of the people in a
conference call are currently talking. A long &lt;em&gt;period&lt;/em&gt; averages
out the power over a longer time, which is useful in deciding whether
a voicemail recording has finished.  &lt;/p&gt;

&lt;p&gt;
The default is 100ms.
&lt;/p&gt;

&lt;h3&gt;Sample files&lt;/h3&gt;

&lt;p&gt;
&lt;a href=&quot;http://blog.corelatus.com/static/milliwatt_reference_audio.zip&quot;&gt;This
.zip file&lt;/a&gt; contains sample recordings with 1kHz sine waves at 0,
-10, -20, -30, -40 and -50 dBm0. The .wav versions are useful for
listening to or importing into an audio editing program to calibrate
the level meter. The .raw versions are just plain A-law samples---you
can use them with a GTH player.
&lt;/p&gt;
</description>
	</item>
	
	<item>
		<title>GTH &#39;C&#39; API</title>
		<link>../../GTH__C__API.html</link>        
		<guid isPermaLink="true">../../GTH__C__API.html</guid>
                <pubDate>Wed, 20 Jan 2010 10:47:37 GMT</pubDate>
		<description>&lt;p&gt; 
This post is for people who want to use C to control a GTH. Other
languages (e.g. Erlang, Java, Python and Perl) are easier to work
with, but in some applications you want the complete control that C
gives you. 
&lt;/p&gt;

&lt;p&gt;
Corelatus provides a &lt;a href=&quot;http://www.corelatus.com/gth/api/gth_c_examples.zip&quot;&gt;
C API for GTH&lt;/a&gt;. The C API lets you control a GTH using plain C function
calls---all of the XML wire format is taken care of.
&lt;/p&gt;

&lt;p&gt;Here&#39;s an example of how to use it to record speech
on an E1/T1 timeslot, something you&#39;d typically do in a voicemail system:
&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;quot;gth_apilib.h&amp;quot;&lt;/span&gt;
...

  GTH_api api;                     &lt;span class=&quot;synComment&quot;&gt;// GTH_api represents one GTH API connection&lt;/span&gt;
  &lt;span class=&quot;synType&quot;&gt;int&lt;/span&gt; result;
  &lt;span class=&quot;synType&quot;&gt;int&lt;/span&gt; data_socket;
  &lt;span class=&quot;synType&quot;&gt;char&lt;/span&gt; buffer[&lt;span class=&quot;synConstant&quot;&gt;2000&lt;/span&gt;];
  &lt;span class=&quot;synType&quot;&gt;char&lt;/span&gt; job_id[MAX_JOB_ID];
  &lt;span class=&quot;synType&quot;&gt;int&lt;/span&gt; octet_count;

  result = gth_connect(&amp;amp;api, &lt;span class=&quot;synConstant&quot;&gt;&amp;quot;172.16.1.10&amp;quot;&lt;/span&gt;);    &lt;span class=&quot;synComment&quot;&gt;// Assuming the default GTH IP &lt;/span&gt;
  assert(result == &lt;span class=&quot;synConstant&quot;&gt;0&lt;/span&gt;);

  &lt;span class=&quot;synComment&quot;&gt;// We want to record audio on the E1/T1 called &amp;quot;1A&amp;quot;, on timeslot 3.&lt;/span&gt;
  data_socket = gth_new_recorder(api, &lt;span class=&quot;synConstant&quot;&gt;&amp;quot;1A&amp;quot;&lt;/span&gt;, &lt;span class=&quot;synConstant&quot;&gt;3&lt;/span&gt;, job_id);

  &lt;span class=&quot;synStatement&quot;&gt;while&lt;/span&gt; ( (octet_count = recv(data_socket, buffer, &lt;span class=&quot;synStatement&quot;&gt;sizeof&lt;/span&gt; buffer, &lt;span class=&quot;synConstant&quot;&gt;0&lt;/span&gt;)) ) {
    &lt;span class=&quot;synComment&quot;&gt;// do whatever you want with the received data&lt;/span&gt;
  }

...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
The recording above happens in the &#39;while&#39; loop. It continues forever
(i.e. until you abort it). The audio data is bit-for-bit identical to
what was on the E1/T1 timeslot, so this can be used for recording both
voice and signalling.
&lt;/p&gt;

&lt;h3&gt;Further examples&lt;/h3&gt;

&lt;p&gt;The C API code includes further examples to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Record audio or signalling from a timeslot to a .wav file&lt;/li&gt;
  &lt;li&gt;Play back previously recorded files&lt;/li&gt;
  &lt;li&gt;Install (upgrade) the firmware on a GTH&lt;/li&gt;
  &lt;li&gt;Monitor (sniff) SS7 MTP-2 and save the signalling to a wireshark
    (PCAP) compatible file.&lt;/li&gt;
  &lt;li&gt;Monitor CAS R2 signalling.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Standalone Parser&lt;/h3&gt;

&lt;p&gt;Aside: the C API code includes a standalone parser for the XML
responses the GTH emits. You can use the parser without using the
rest of the API library, if you want to.
&lt;/p&gt;
</description>
	</item>
	
	<item>
		<title>Decoding the Gb Interface with Wireshark</title>
		<link>../../Decoding_the_Gb_Interface_with_Wireshark.html</link>        
		<guid isPermaLink="true">../../Decoding_the_Gb_Interface_with_Wireshark.html</guid>
                <pubDate>Wed, 31 Mar 2010 22:26:29 GMT</pubDate>
		<description>&lt;p&gt; 
The Gb interface is part of the packet radio data network (GPRS) in GSM,
it sits between the BSC and the SGSN and carries subscriber data headed
to and from the internet.&lt;/p&gt;

&lt;p&gt;
Wireshark understands how to decode the Gb interface, so you can use
wireshark to look through data sniffed from a Gb interface by a
Corelatus GTH.  Here&#39;s what it looks like:
&lt;/p&gt;

&lt;img alt=&#39;wireshark screenshot&#39; style=&#39;margin-left:-170px&#39; src=&#39;static/gsm_gb_interface_screenshot.png&#39;/&gt;

&lt;h3&gt;How to tell the GTH to capture Gb&lt;/h3&gt;

&lt;p&gt;To look at a GPRS network like this, you need to do a few things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Connect one of the GTH&#39;s E1 interfaces to the E1 (or T1) interface
carrying the Gb interfaces. You typically do that at a cross connect
panel, using a G.772 monitor point.&lt;/li&gt;

&lt;li&gt;Enable the E1 interface you connected.&lt;/li&gt;

&lt;li&gt;Tell the GTH to start decoding frame relay on that interface&lt;/li&gt;

&lt;li&gt;Convert the captured data to the file format which wireshark understands,
  libpcap.&lt;/li&gt;

&lt;li&gt;Open the captured file in wireshark. (On unix-like operating systems,
  including OSX, you can also pipe into wireshark to get a live view of
  the capture.)&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;Taking those steps one at a time, starting with #2:&lt;/p&gt;

&lt;h4&gt;Enable the E1 interface&lt;/h4&gt;

&lt;pre&gt;
&lt;code&gt;
  &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;set &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;pcm3A&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;&amp;gt;&amp;lt;attribute &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;monitoring&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt; &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;value&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;true&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;/&amp;gt;&amp;lt;/set&amp;gt;&lt;/span&gt;
&lt;/code&gt;
&lt;/pre&gt;

&lt;h4&gt;Tell GTH start decoding frame relay&lt;/h4&gt;

&lt;p&gt;The Gb interface uses frame relay on E1. Different sites use
different configurations of timeslots. One common setup is to use
timeslots 1--15. Another common setup is to 1--15 + 17--31. The
GTH can handle any setup.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;
  &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;new&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;fr_monitor &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;ip_addr&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;172.16.2.1&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt; &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;ip_port&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;1234&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;pcm_source &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;span&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;3A&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt; &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;timeslot&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;1&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;pcm_source &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;span&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;3A&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt; &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;timeslot&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;2&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;pcm_source &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;span&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;3A&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt; &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;timeslot&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;3&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;/&amp;gt;&lt;/span&gt;
      ..
      &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;pcm_source &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;span&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;3A&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt; &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;timeslot&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;15&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;/fr_monitor&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;/new&amp;gt;&lt;/span&gt;
&lt;/code&gt;
&lt;/pre&gt;

&lt;h4&gt;Convert the captured data&lt;/h4&gt;

&lt;p&gt;GTH sends out data in a format described in
the &lt;a href=&#39;www.corelatus.com/gth/api/gth_api.pdf&#39;&gt;API manual&lt;/a&gt;.
Wireshark wants the data to be in libpcap format. save_to_pcap.erl, in
the &lt;a href=&#39;http://www.corelatus.com/gth/api/gth_erlang_api.zip&#39;&gt;sample
Erlang code for GTH&lt;/a&gt; can do the conversion, like this:
&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;
  &lt;span class=&quot;synIdentifier&quot;&gt;save_to_pcap:from_file&lt;/span&gt;(&lt;span class=&quot;synConstant&quot;&gt;&amp;quot;/tmp/captured.raw&amp;quot;&lt;/span&gt;, &lt;span class=&quot;synConstant&quot;&gt;&amp;quot;/tmp/captured.pcap&amp;quot;&lt;/span&gt;)&lt;span class=&quot;synSpecial&quot;&gt;.&lt;/span&gt;
&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;
  A lazier approach is to let save_to_pcap.erl configure the GTH and
start the capture:
&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;
  &lt;span class=&quot;synIdentifier&quot;&gt;save_to_pcap:frame_relay&lt;/span&gt;(&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;&amp;quot;3A&amp;quot;&lt;/span&gt;, &lt;span class=&quot;synIdentifier&quot;&gt;lists:seq&lt;/span&gt;(&lt;span class=&quot;synConstant&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;synConstant&quot;&gt;15&lt;/span&gt;), &lt;span class=&quot;synConstant&quot;&gt;&amp;quot;gprs.pcap&amp;quot;&lt;/span&gt;)&lt;span class=&quot;synSpecial&quot;&gt;.&lt;/span&gt;
&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;  
  The &lt;a href=&#39;http://www.corelatus.com/gth/api/gth_c_examples.zip&#39;&gt;C version
    &lt;/a&gt;of save_to_pcap can currently only convert MTP-2, not frame
    relay. If you want it extended, send mail.
&lt;/p&gt;


&lt;h4&gt;Start up wireshark&lt;/h4&gt;

&lt;p&gt;
By default, wireshark decodes frame relay as &#39;FRF 3.2/CISCO HDLC&#39;.
That&#39;s not quite what we want. Go to Edit/Preferences/Protocols/FR
and change the encapsulation to &#39;GPRS Network Service&#39;. Now you
get full decoding.
&lt;/p&gt;

</description>
	</item>
	
	<item>
		<title>Decoding UMTS (3G) Interfaces with Wireshark</title>
		<link>../../Decoding_UMTS__3G__Interfaces_with_Wireshark.html</link>        
		<guid isPermaLink="true">../../Decoding_UMTS__3G__Interfaces_with_Wireshark.html</guid>
                <pubDate>Mon, 24 May 2010 16:46:18 GMT</pubDate>
		<description>&lt;p&gt; 
Many 3G networks use ATM on their internal interfaces, e.g. on the Iub and
Iu-PS interfaces. Those interfaces carry both control information (radio
environment information, attach/detach messages, location updates) and also
subscriber data, for instance IP traffic.
&lt;/p&gt;

&lt;p&gt;
Wireshark understands how to decode those ATM interfaces. Here&#39;s an
example of an interface sniffed by a GTH.  The interface was carrying
IP traffic over ATM on an E1 line.
&lt;/p&gt;

&lt;img alt=&#39;wireshark screenshot&#39; style=&#39;margin-left:-170px&#39; src=&#39;static/atm_llc_interface_screenshot.png&#39;/&gt;

&lt;h3&gt;How to tell the GTH to capture an ATM link&lt;/h3&gt;

&lt;p&gt;To look at a 3G network like this, you need to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Connect one of the GTH&#39;s E1 interfaces to the E1 (or T1) interface
carrying the ATM interface. You typically do that at a cross connect
panel, using a G.772 monitor point.&lt;/li&gt;

&lt;li&gt;Enable the E1 interface you connected.&lt;/li&gt;

&lt;li&gt;Tell the GTH to start decoding ATM AAL5 (and/or AAL2) on that interface&lt;/li&gt;

&lt;li&gt;Convert the captured data to the file format which wireshark understands,
  libpcap.&lt;/li&gt;

&lt;li&gt;Open the captured file in wireshark. (On unix-like operating systems,
  including OSX, you can also pipe into wireshark to get a live view of
  the capture.)&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;Taking those steps one at a time, starting with #2:&lt;/p&gt;

&lt;h4&gt;Enable the E1 interface&lt;/h4&gt;

&lt;pre&gt;
&lt;code&gt;
  &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;set &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;pcm3A&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;&amp;gt;&amp;lt;attribute &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;monitoring&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt; &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;value&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;true&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;/&amp;gt;&amp;lt;/set&amp;gt;&lt;/span&gt;
&lt;/code&gt;
&lt;/pre&gt;

&lt;h4&gt;Tell GTH start decoding ATM AAL5&lt;/h4&gt;

&lt;p&gt;IP traffic on ATM is always carried in AAL5. The timeslot
arrangement is usually 1--15 + 17--31. A few sites share the E1 with
other protocols, this is called fractional ATM. The GTH can handle
either scheme.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;
  &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;new&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;atm_aal5_monitor &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;ip_addr&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;172.16.2.1&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt; &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;ip_port&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;1234&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt; &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;vpi&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;0&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt; &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;vci&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;5&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;pcm_source &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;span&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;3A&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt; &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;timeslot&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;1&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;pcm_source &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;span&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;3A&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt; &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;timeslot&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;2&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;pcm_source &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;span&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;3A&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt; &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;timeslot&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;3&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;/&amp;gt;&lt;/span&gt;
      ..
      &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;pcm_source &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;span&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;3A&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt; &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;timeslot&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;15&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;pcm_source &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;span&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;3A&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt; &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;timeslot&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;17&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;/&amp;gt;&lt;/span&gt;
      ..
      &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;pcm_source &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;span&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;3A&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt; &lt;/span&gt;&lt;span class=&quot;synType&quot;&gt;timeslot&lt;/span&gt;=&lt;span class=&quot;synConstant&quot;&gt;&#39;31&#39;&lt;/span&gt;&lt;span class=&quot;synIdentifier&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;/fr_monitor&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;synIdentifier&quot;&gt;&amp;lt;/new&amp;gt;&lt;/span&gt;
&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;
In this example, the VPI/VCI is 0/5. If you know the VPI/VCI in advance,
great. If you don&#39;t, the GTH can sniff traffic at the AAL0 interface and
show you which VPI/VCI are active on the link.
&lt;/p&gt;

&lt;h4&gt;Convert the captured data&lt;/h4&gt;

&lt;p&gt;GTH sends out data in a format described in
the &lt;a href=&#39;www.corelatus.com/gth/api/gth_api.pdf&#39;&gt;API manual&lt;/a&gt;.
Wireshark wants the data to be in libpcap format. save_to_pcap.erl, in
the &lt;a href=&#39;http://www.corelatus.com/gth/api/gth_erlang_api.zip&#39;&gt;sample
Erlang code for GTH&lt;/a&gt; can do the conversion, like this:
&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;
  &lt;span class=&quot;synIdentifier&quot;&gt;save_to_pcap:from_file&lt;/span&gt;(&lt;span class=&quot;synConstant&quot;&gt;&amp;quot;/tmp/captured.raw&amp;quot;&lt;/span&gt;, &lt;span class=&quot;synConstant&quot;&gt;&amp;quot;/tmp/captured.pcap&amp;quot;&lt;/span&gt;)&lt;span class=&quot;synSpecial&quot;&gt;.&lt;/span&gt;
&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;
  A lazier approach is to let save_to_pcap.erl configure the GTH and
start the capture:
&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;
  &lt;span class=&quot;synIdentifier&quot;&gt;save_to_pcap:aal5&lt;/span&gt;(&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;&amp;quot;3A&amp;quot;&lt;/span&gt;, &lt;span class=&quot;synIdentifier&quot;&gt;lists:seq&lt;/span&gt;(&lt;span class=&quot;synConstant&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;synConstant&quot;&gt;15&lt;/span&gt;) &lt;span class=&quot;synStatement&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;synIdentifier&quot;&gt;lists:seq&lt;/span&gt;(&lt;span class=&quot;synConstant&quot;&gt;17&lt;/span&gt;,&lt;span class=&quot;synConstant&quot;&gt;31&lt;/span&gt;),
  {&lt;span class=&quot;synConstant&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;synConstant&quot;&gt;5&lt;/span&gt;}, &lt;span class=&quot;synConstant&quot;&gt;&amp;quot;aal5.pcap&amp;quot;&lt;/span&gt;)&lt;span class=&quot;synSpecial&quot;&gt;.&lt;/span&gt;
&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;  
  The &lt;a href=&#39;http://www.corelatus.com/gth/api/gth_c_examples.zip&#39;&gt;C version
    &lt;/a&gt;of save_to_pcap can currently only convert MTP-2, not AAL5. If
    you want it extended, send mail (address at top right).
&lt;/p&gt;


&lt;h4&gt;Start up wireshark&lt;/h4&gt;

&lt;p&gt;
Recent versions of Wireshark, e.g. 1.2.7, can decode such capture files
out of the box, without any configuration. Finished.
&lt;/p&gt;

</description>
	</item>
	
	<item>
		<title>Porting C Socket Code to Windows</title>
		<link>../../Porting_C_Socket_Code_to_Windows.html</link>        
		<guid isPermaLink="true">../../Porting_C_Socket_Code_to_Windows.html</guid>
                <pubDate>Wed, 16 Jun 2010 13:48:38 GMT</pubDate>
		<description>&lt;p&gt;
  I just ported
  the &lt;a href=&#39;http://www.corelatus.com/gth/api/gth_c_examples.zip&#39;&gt;C
  example code&lt;/a&gt; for controlling Corelatus E1/T1 hardware to Visual
  Studio 2010. Doing that was easier than expected. This first part
  of this post is about how to use that code. The second part is 
  a bit of history about what I had to do to port the code.
&lt;/p&gt;

&lt;h4&gt;Obtaining Visual Studio&lt;/h4&gt;

&lt;p&gt;Microsoft have their C/C++ compiler available for free download
  on &lt;a href=&#39;http://www.microsoft.com/express/Windows/&#39;&gt;microsoft.com&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;The install process is pretty standard for windows, if you&#39;re
  accustomed to Microsoft products, there are no surprises here.
&lt;/p&gt;


&lt;h4&gt;Compiling the code&lt;/h4&gt;

&lt;p&gt;
  &lt;ol&gt;
    &lt;li&gt;Start the &quot;Visual Studio Command Prompt&quot;. By default, that&#39;s
      in &quot;Start/Programs/Microsoft Visual Studio 2010 Express&quot;.&lt;/li&gt;

    &lt;li&gt;Navigate to the directory you unpacked
      the &lt;a href=&#39;http://www.corelatus.com/gth/api/gth_c_examples.zip&#39;&gt;sample
      code&lt;/a&gt; in. Remove any old .exe files with &#39;del *.exe&#39;.&lt;/li&gt;

    &lt;li&gt;Run &#39;nmake /f NMakefile&#39;. After a couple of seconds, you have 
        six brand-new .exe files. Here&#39;s what this step looks like:&lt;/li&gt;
  &lt;/ol&gt;

  &lt;img style=&#39;margin-left:-70px&#39; 
       src=&#39;static/visual_studio_compile.png&#39; 
       alt=&#39;screenshot of a VC compile&#39;/&gt;

  If you just wanted to see how to compile the code, &lt;b&gt;you can stop reading
  now&lt;/b&gt;. The rest of the post is just about what I had to do to make this
  work with Microsoft&#39;s compiler.
&lt;/p&gt;


&lt;h4&gt;Hurdle #1: MS nmake vs gnumake vs Visual Studio projects&lt;/h4&gt;

&lt;p&gt;
  Conclusion: I ended up using Microsoft&#39;s nmake and wrote a separate
  NMakefile for it.
&lt;/p&gt;

&lt;p&gt;
  My code gets built by &#39;make&#39;, through a Makefile. Visual Studio doesn&#39;t
  include a make program which can understand normal Makefiles, leaving
  me a choice of either using the Visual Studio IDE or using Microsoft&#39;s
  &lt;code&gt;nmake&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
  I spent half an hour trying the IDE route. When you make a new
  project, you have to choose what sort it is. &quot;CLR Console
  Application&quot; seemed closest to what I wanted to do, so I chose
  that. Maybe &quot;Makefile Project&quot; would have worked better.
  Things got increasingly confusing from there. What&#39;s a &quot;solution?&quot;
  Why are &quot;precompiled headers&quot; enabled? I just want to compile a few
  hundred lines of C. At that point, I gave up, the IDE is clearly not
  the easiest way for me to get started.
&lt;/p&gt;

&lt;p&gt;
  Next, I tried Microsoft&#39;s replacement for &lt;code&gt;make&lt;/code&gt;, called
  &lt;code&gt;nmake&lt;/code&gt;. That didn&#39;t start flawlessly either, nmake uses
  its own syntax. Initially, I thought I might be able to write one
  Makefile which both gnumake and nmake understand. But Microsoft&#39;s
  syntax seems to be too different to allow that. Oh well. The NMakefile
  is just a dozen lines or so.
&lt;/p&gt;


&lt;h4&gt;Hurdle #2: Missing header files&lt;/h4&gt;

&lt;p&gt;
  Conclusion: I used #ifdefs to include different header files when
  compiling in a win32 environment.&lt;/p&gt;

&lt;p&gt;
  Visual Studio doesn&#39;t provide some of the header files the code
  uses, e.g. there&#39;s no &#39;unistd.h&#39; and no &#39;sys/socket.h&#39;. Odd.
  Providing most of unistd.h shouldn&#39;t be too hard.
&lt;/p&gt;

&lt;p&gt;
  The point of this exercise is to get the code to compile using
  a Microsoft toolchain, so I didn&#39;t investigate using cygwin or
  mingw.
&lt;/p&gt;

&lt;p&gt;
  In the end, it turns out that I wasn&#39;t using anything from &#39;unistd.h&#39;
  which didn&#39;t get provided by something else in win32. &#39;socket.h&#39; (and
  friends) was a bit harder, but it turns out that&#39;s provided by 
  &#39;winsock2.h&#39;.
&lt;/p&gt;


&lt;h4&gt;Hurdle #3: &#39;Mostly compatible&#39; socket API&lt;/h4&gt;

&lt;p&gt;
  Conclusion: winsock2 is different to the BSD socket API, but the
  differences can be worked around with just a few changes.
&lt;/p&gt;

&lt;p&gt;
  Sockets were invented on unix, so I assumed that other OSes would
  just copy the interface. But no, not on win32. There seem to be at
  least two attempts to make a socket API for windows, called
  &#39;winsock&#39; and &#39;winsock2&#39;. The first seems to be deprecated.  The
  main problems I hit were:

  &lt;ul&gt;
    &lt;li&gt;You can&#39;t use close() on a socket, you have to use closesocket()&lt;/li&gt;
    &lt;li&gt;You can&#39;t use read() on a socket, you have to use recv()&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;errno&lt;/code&gt; doesn&#39;t report socket errors, you have to
      call a special Windows Socket error reporting function.&lt;/li&gt;
  &lt;/ul&gt;

  None of those problems are hard to get around.
&lt;/p&gt;
  

&lt;h4&gt;Hurdle #4: GNU and Microsoft can&#39;t agree on function names&lt;/h4&gt;

&lt;p&gt;
  Both GNU and Microsoft have replacements for some functions which
  are prone to security problems. If you use plain &lt;code&gt;strcat()&lt;/code&gt;
  or &lt;code&gt;strcpy&lt;/code&gt;, visual studio warns about security problems.
&lt;/p&gt;

&lt;p&gt;
  Disabling the warnings would be quick but feels like cheating. So
  I looked at the &#39;less insecure&#39; alternatives. GNU call them
  &lt;code&gt;strncat&lt;/code&gt; and &lt;code&gt;strncpy&lt;/code&gt; whereas Microsoft call
  them &lt;code&gt;strcat_s&lt;/code&gt; and &lt;code&gt;strcpy_s&lt;/code&gt;. And the
  arguments are the same way around. It would have been nice if GNU
  and MS had solved this the same way, but no. Minor annoyance.
&lt;/p&gt;


&lt;h4&gt;Hurdle #5: Structure packing pragmas&lt;/h4&gt;

&lt;p&gt;
  Conclusion: Both MS and GNU understand the #pragma pack(N) syntax,
  but only GNU understands the __attribute__((__packed__)) syntax.
&lt;/p&gt;

&lt;p&gt;
  A couple of the examples (save_to_pcap.c and record.c) use
  structures to encode or decode data defined by an external
  format. For instance, here&#39;s what the wire format of a
  &#39;pcap&#39; protocol capture file looks like:

  &lt;pre&gt;
    &lt;code&gt;
      &lt;span class=&quot;synType&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;synType&quot;&gt;struct&lt;/span&gt; {
        &lt;span class=&quot;synType&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;synType&quot;&gt;int&lt;/span&gt; magic;
        &lt;span class=&quot;synType&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;synType&quot;&gt;short&lt;/span&gt; major_version;
        &lt;span class=&quot;synType&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;synType&quot;&gt;short&lt;/span&gt; minor_version;
        &lt;span class=&quot;synType&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;synType&quot;&gt;int&lt;/span&gt; GMT_to_localtime;
        &lt;span class=&quot;synType&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;synType&quot;&gt;int&lt;/span&gt; sigfigs;
        &lt;span class=&quot;synType&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;synType&quot;&gt;int&lt;/span&gt; snaplen;
        &lt;span class=&quot;synType&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;synType&quot;&gt;int&lt;/span&gt; network;
      } PCAP_global_header;
    
&lt;/code&gt;
  &lt;/pre&gt;

  We have to tell the compiler that spacing out the fields to get
  a certain alignment isn&#39;t allowed. The recommended GNU way to
  do that is to add &lt;code&gt;__attribute__((__packed__))&lt;/code&gt; after
  the structure. The recommended Microsoft way is to add
  &lt;code&gt;#pragma pack(1)&lt;/code&gt; somewhere before the structure, and
  then remember to change the packing back again before hitting
  any code which is sensitive to performance.
&lt;/p&gt;

&lt;p&gt;
  Since this is just example code, we don&#39;t care about that last
  bit of performance, so we can just leave the packing at 1.
&lt;/p&gt;

&lt;p&gt;
  Aside: the structure above is a bit sloppy because just quietly
  assumes that an int is 32 bits and a short 16.
&lt;/p&gt;

&lt;h4&gt;Hurdle #6: Windows firewall&lt;/h4&gt;

&lt;p&gt;
  Some of the example code opens TCP sockets for listening. By default,
  the windows firewall doesn&#39;t allow that. Just click &quot;fine, ok, let
  me do this&quot;.
&lt;/p&gt;

&lt;p&gt;
  Unfortunately, that looks ugly for the user---the program will fail
  the first time you run it, and the pop-up box says &quot;publisher
  unknown&quot;.  Does anyone know how to improve on this? It&#39;d be nice if
  the user could approve the publisher, i.e. me, once, and then every
  program works.
&lt;/p&gt;

&lt;h4&gt;How long did the porting take?&lt;/h4&gt;

&lt;p&gt;
  A couple of days, including getting Visual Studio installed.
  That&#39;s for a few thousand lines of code with a bit of socket IO
  and file IO.
&lt;/p&gt;

&lt;p&gt;
  If I had to do it again, it&#39;d take an afternoon or so.
&lt;/p&gt;
</description>
	</item>
	
        </channel>
</rss>
