Documenting Problems That Were Difficult To Find The Answer To

Monthly Archives: September 2014

Capturing Incoming SIP Address With Asterisk

When a call comes into your Asterisk server via a SIP trunk or just over SIP it will usually have ${CALLERID(num)} set to the incoming number if that call originated from the plain old telephony system (POTS).

However how do you capture caller ID from a SIP address such as

Well, in this case ${CALLERID(num)} will contain the text john.smith – but getting the domain name is trickier.

In actual fact the domain will be found in the ${CHANNEL} variable looking something like SIP/ Now you can use the ${CUT(CHANNEL,-,2)} in a vain hope to trim off that hexadecimal number at the end – but this will fail miserably if there is a dash in the domain name (a perfectly legal thing to do).

Instead we need to define a macro that will trim off everything up to the right-most dash. The following will do this and store the result in ${trimresult}:

exten => s,1,NoOp()
  same => n,Verbose(parameter is <${ARG1}>)
  same => n(loop),NoOp()
  same => n,GotoIf($["${ARG1}" = ""]?end)
  same => n,GotoIf($[${LEN(${ARG1})} < 2]?end)
  same => n,GotoIf($["${ARG1:-1}" = "-"]?founddash)
  same => n,Set(ARG1=${ARG1:0:$[${LEN(${ARG1})}-1]})
  same => n,Goto(loop)
  same => n(founddash),Set(ARG1=${ARG1:0:$[${LEN(${ARG1})}-1]})
  same => n(end),Set(trimresult=${ARG1})

Now we can define a macro that filters our incoming caller ID to prevent any nasty characters from having side effects when creating files or calling system binaries (result is in ${FILTERED_ID}):

exten => s,1,NoOp()
  same => n,GotoIf($["${CUT(CHANNEL,/,1)}" != "SIP"]?notsip)
  same => n,Macro(trim-to-dash,${CHANNEL})
  same => n,Set(sipdomainin=${CUT(trimresult,/,2)})
  same => n,Set(FILTERED_ID=${FILTER(0-9a-zA-Z@._ +,${CALLERID(num)}@${sipdomainin})})
  same => n,Goto(end)
  same => n(notsip),NoOp()
  same => n,GotoIf($["${CALLERID(num)}" = "s"]?nonum)
  same => n,GotoIf($["${CALLERID(num)}" = ""]?nonum)
  same => n,GotoIf($["${FILTER(0-9a-zA-Z@._ +,${CALLERID(num)})}" = ""]?nonum)
  same => n,Set(FILTERED_ID=${FILTER(0-9a-zA-Z@._ +,${CALLERID(num)})})
  same => n,Goto(end)
  same => n(nonum),Set(FILTERED_ID=${FILTER(0-9a-zA-Z@._ +,${CALLERID(name)})})
  same => n(end),NoOp()

Be aware that when you have an incoming call you may want to capture the incoming caller ID into the ${FILTERED_ID} variable – but this will not be inherited when you issue the Dial() command.

So if you’re planning to use the incoming caller ID by a dialled extension you need to subsequently create another variable with a leading underscore – such variables are inherited by sub-channels with the prefixed underscore removed. E.g.:

  same => n,Set(_FILTERED_ID=${FILTERED_ID})
  same => Dial(SIP/101&SIP/102, 15, M(write-debug-file))

What is the Price of Closing a Motorway for an Accident?


Having personally been parked on a motorway for 3 hours without any choice in the matter I have a keen sense of sympathy for the many who have also experienced an unexpected and unwanted imprisonment in their lives.

The argument, of course, is that a fatality is a tragic thing and that such an event should be dealt with and the incident area investigated without contamination.

But at what point is the cost to the public as a whole greater than the value of an uncontaminated accident scene? To some that may not have a price – but to others there is a level of reasonableness to consider.

The question is: what is the price to the public of a tailback?

What Price a Tailback?

Let’s consider an event that occurred on 1 November 2011 where the M25 was closed for 3 hours causing a 19-mile tailback.

How many vehicles would have been caught up in this queue? Assuming that each car consists of at least one working adult (the driver) how much is their time worth? This should give as a very basic cost basis of such an incident to the general public (not including lorries and business impact).

How Many Cars?

  • length of a BMW 3 Series: 4.5 metres
  • number of car lengths between cars in a queue: 2.0 (conservative guess)
  • distance taken by a single car: (2.0 + 1.0) x 4.5 = 13.5 metres
  • cars per kilometre: 74
  • cars per mile: 119

In a 3-lane tailback for 19 miles there would be approximately 19 x 3 x 119 = 6,783 cars involved all parked for 3 hours.

What Price Delay?

Let’s conservatively assume that each car contains one adult of working age and that over the span of vehicles those adults earn the average UK wage. Let’s bill their time delayed by their income for those hours delayed.

So, for 6,783 cars delayed for 3 hours at an average earning rate of £12.48 per hour per car we have a total cost of £253,853. Over a quarter of a million pounds and that’s a conservative estimate!

Should a Motorway be Completely Blocked if it Costs the Public a Quarter Million Pounds?

I cannot answer that. But it should make you think the next time the police completely shut off a motorway.

Fatal accidents are complicated things. But if a few cars get written off in an accident it would be cheaper just to tow those things off the road and buy the people involved brand new cars rather than hold up the (uninvolved and innocent) public.

Insurer’s Responsibilities?

I would argue that insurers must bear the cost of compensating directly affected drivers for the cost of their delay. It would be, arguably, infeasible to process separate personalised claims by every driver caught in the tailback. But given a record of vehicles on the motorway section at the time (from camera logs) and a calculated average loss to the public – each motorist should at least get £36 compensation mailed to them from the insurer of the responsible vehicle.

Think about it: the person responsible will likely get a brand new car from the insurance company – even though they caused the accident. But thousands of innocent motorists have time stolen from them with no compensation at present – and this cannot be right.

It would be entirely appropriate for insurance companies to levy different fees for insurance depending on whether motorists use the motorways or not. If you crash on a backroad and affect nobody it is right that nobody else gets compensated. But if you block a motorway and directly prevent motorists from escaping or getting around the incident then you should bear full liability to those people you are directly affecting. You might not have crashed into their car but you could be causing them great pain – missing a wedding, a flight, or getting to a hospital to deliver a baby!


All numbers here are estimates only – very basic – and a number of assumptions may have been missed. However the number derived should be viewed as an absolute minimum of the impact to the public – the true cost is likely to be far higher when taking into consideration missed appointments, spoiled items in vehicles, lorries and commercial vehicles also trapped, and consequential incidents occurring in the tailback.

How To Disable Newline Translation Over FTP In Beyond Compare

I am a big fan of Beyond Compare (have purchased a Pro edition license) – and I use it mostly to backup between hard drives or remote sites and home.

I made a SFTP connection to a remote site to copy a text file using the Folder Compare view. However upon making the copy the local file (on Windows) was bigger than the remote file (on Linux). Yet the files compared the same. Clearly newline translation was occurring (as Linux uses a single byte to represent a line ending while Windows uses two bytes to represent a line ending).

So, how to do a binary download rather than a text-conversion download?

Go to the menu, select Tools -> FTP Profiles…

Select Tools > FTP Profiles...

Select Tools > FTP Profiles…

Next choose the Transfer tab, select the default FTP profile, and change the transfer type to be always Binary (not Auto).

Set the default transfer type to be Binary

Set the default transfer type to be Binary

Now you can retry your copy action and the file on your local system should be byte-identical to the one on your remote system.

Linksys SIP Call Terminates After 32 Seconds Because of Invalid Asterisk Contact Header

I had a friend call me from their Linksys VoIP phone to my Asterisk server using SIP (over the Internet).

The call would come in – ring my internal extension just fine. I would pick up the phone – and we could both hear each other.

However approximately 30 seconds later the call would terminate suddenly. It turned out the call was terminated precisely 32 seconds later.

Using debugging (sip set debug on) I captured the SIP packets for debugging.

The incoming INVITE from my friend looked like this (anonymised):

Via: SIP/2.0/UDP;branch=z9hG4bK-fe593a22;rport
From: "Test Client" <>;tag=a824af307af335a1o0
To: <>
Call-ID: 1c5d63e3-6ade2eca@
CSeq: 101 INVITE
Max-Forwards: 70
Contact: "Test Client" <sip:1234567890@>
Expires: 240
User-Agent: Linksys/SPA942-6.1.5(a)
Content-Length: 399
Supported: replaces
Content-Type: application/sdp

All good. Well, things would go well until I picked up the call and I would see the SIP OK from my Asterisk server being retransmitted without acknowledgement from my friend’s Linksys phone:

Retransmitting #10 (NAT) to
SIP/2.0 200 OK
Via: SIP/2.0/UDP;branch=z9hG4bK-fe593a22;received=;rport=5060
From: "Test Client" <>;tag=a824af307af335a1o0
To: <>
Call-ID: f8227f59-90d685a6@
CSeq: 101 INVITE

[Sep 8 13:48:08] WARNING[15643]: chan_sip.c:3641 retrans_pkt: Retransmission timeout reached on transmission f8337f49-91d68a12@ for seqno 101 (Critical Response) -- See
Packet timed out after 32000ms with no response

I used tcpdump to confirm that no SIP packets were being transmitted to me after I picked up the call.

So I looked up a little further to see what Asterisk was telling the Linksys phone after it attempted to INVITE me to a call.

SIP/2.0 200 OK
Via: SIP/2.0/UDP;branch=z9hG4bK-fe593a22;received=;rport=5060
From: "Test Client" <>;tag=a824af307af335a1o0
To: <>;tag=as7cf44a28
Call-ID: 91d68a12-f8337f49@
CSeq: 101 INVITE
Server: Asterisk PBX
Supported: replaces, timer
Contact: <sip:222@>
Content-Type: application/sdp
Content-Length: 277

My Asterisk server was sending a Contact: header with an internal IP address! And the Linksys phone was using this Contact-header (Contact-URI) to send all future SIP packets. Thus I stopped receiving SIP packets from the Linksys phone once I answered the call. Now my friend and I could talk – RTP was working – but the call would be terminated by Asterisk after 32 seconds.

How To Fix The Contact Header In Asterisk

There were two steps. Firstly I needed to specify what my external IP address was. There are two ways. If you know your external IP address and it doesn’t change then specify it directly:


However if you’re running an Asterisk server at home you probably have a dynamic address. I personally use a free Dynamic DNS account and have my SIP domain name as a CNAME to my Dynamic DNS domain name. In this case specify:

externrefresh=180           ; update address from domain name every 3 minutes

The next step is to ensure your Asterisk server knows what a local address is – so that it can present this externip or externhost in the Contact header when INVITEd from outside your local network:


Now you should see outgoing Contact: URLs using your external IP address – and the Linksys phone should now be able to correctly contact your Asterisk server once you’ve picked up your extension to answer.

Alternative Method

What if your Asterisk server is NATted behind another NAT? For example – in my configuration I had a router (running NAT) connected to the Internet and my home network. On my home network I had a Linux server (also running NAT) – and hosted on that Linux server I had a LXC container running my Asterisk server.

Linux has the nf_nat_sip module which should re-write the appropriate Contact: header.

Try loading the module on your NAT server by typing modprobe nf_nat_sip, confirm it is loaded with lsmod |grep nf_nat_sip, and re-try your call.

Creating A Basic IVR With Asterisk

So you want to start your home business using Asterisk. And you’d like incoming callers to be treated to the customary interactive voice response (IVR) that many modern businesses have.

Some Useful Links

When playing with dialplans keep these Asterisk links handy: application commands, variables, functions, and standard extensions.

The Audio

Start by recording a few voice prompts, such as “Welcome to Widgets Incorporated”. Save this as a .wav file.

Note that, for Asterisk to handle the voice files appropriately, they should be in 16-bit 8000Hz format. You can use ffmpeg to convert your audio files into the appropriate output format:

user@host:~> ffmpeg -i welcome-to-widgets-orig.wav \
  -ac 1 -ab 128000 -ar 8000 welcome-to-widgets-8000.wav
Input #0, wav, from 'welcome-to-widgets-orig.wav':
  Duration: 00:00:01.96, bitrate: 705 kb/s
    Stream #0.0: Audio: pcm_s16le, 44100 Hz, 1 channels, s16, 705 kb/s
Output #0, wav, to 'welcome-to-widgets-8000.wav':
    encoder         : Lavf53.21.1
    Stream #0.0: Audio: pcm_s16le, 8000 Hz, 1 channels, s16, 128 kb/s
Stream mapping:
  Stream #0.0 -> #0.0
Press ctrl-c to stop encoding
size=      31kB time=1.96 bitrate= 128.2kbits/s
video:0kB audio:31kB global headers:0kB muxing overhead 0.146721%

Next – where do you put your audio files? You have to look it up from /etc/asterisk/asterisk.conf:

user@host:~> grep astdatadir /etc/asterisk/asterisk.conf
astdatadir => /usr/share/asterisk

So on my system sounds are, by default, at /usr/share/asterisk/sounds/. You can create subfolders but always be sure to prefix the subfolder name in the extensions.conf dialplan if you do.

The Dialplan

Now we have to create our dialplan. For the sake of testing let’s define an extension that will hook straight into our IVR.

exten => _755,1,NoOp()
  same => n,Goto(ivr-root,s,1)

This says that if 755 is dialled then we should jump into the ivr-root context with the s extension.

Now, what do we want our IVR to do? Maybe answer the phone and then pause for 500ms before the next step (the Answer() function does this). Next read out a message in the background while listening for an extension (the Background() function does this). Finally wait after the background message has been played for several seconds for an extension to be dialed (the WaitExten()function does this). The following would accomplish this:

exten => s,1,NoOp()
  same => n,Answer(500)
  same => n,Background(welcome-to-widgets-8000&enter-extension)
  same => n,WaitExten(3)
  same => n,HangUp()

You could write the Background statement as two separate statements (might be easier to read):

exten => s,1,NoOp()
  same => n,Answer(500)
  same => n,Background(custom/welcome-to-widgets-8000)
  same => n,Background(custom/enter-extension)
  same => n,WaitExten(3)
  same => n,HangUp()

Now you can give options and jump to other contexts. Imagine if you had a message “Please press 1 for Jim, press 2 for Bob, press 3 to hear this option again” saved as option-readout.wav you could have:

exten => s,1,NoOp()
  same => n,Answer(500)
  same => n,Background(custom/welcome-to-widgets-8000)
  same => n(my_marker),Background(custom/option-readout.wav)
  same => n,WaitExten(3)
  same => n,HangUp()

exten => 1,1,Dial(SIP/101) ; dial Jim

exten => 2,1,Dial(SIP/102) ; dial Bob

exten => 3,1,Goto(s,my_marker) ; repeat options

What if you want to press 2 for a new (e.g. sales) menu? Press 3 for a different (e.g. technical) menu? Create new contexts for the new menus.

exten => s,1,NoOp()
  same => n,Answer(500)
  same => n,Background(custom/welcome-to-widgets-8000)
  same => n(my_marker),Background(custom/option-readout)
  same => n,WaitExten(3)
  same => n,HangUp()

exten => 1,1,Dial(SIP/101) ; dial Jim

exten => 2,1,Goto(ivr-menu-sales,s,1)
exten => 3,1,Goto(ivr-menu-tech,s,1)

exten => 3,1,Goto(s,my_marker) ; repeat options

; ----
; sales group
exten => s,1,NoOp()
  same => n,Background(custom/options-sales)
  same => n,WaitExten(3)
  same => n,HangUp()

exten => 0,1,Goto(ivr-root,s,my_marker) ; go back to main manu

exten => 1,1,Dial(SIP/102) ; dial Bob

; ----
; technical group
exten => s,1,NoOp()
  same => n,Background(custom/options-tech)
  same => n,WaitExten(3)
  same => n,HangUp()

exten => 0,1,Goto(ivr-root,s,my_marker) ; go back to main manu

exten => 1,1,Playback(custom/our-website-location)

exten => 2,1,Playback(custom/frequently-asked-questions)

exten => 3,1,Dial(SIP/103) ; dial Fred


To diagnose your IVR dialplan it is probably best to run Asterisk in verbose mode.

user@host:~> asterisk -rvvvv

To switch off verbose mode run asterisk again:

user@host:~> asterisk -r
host*CLI> core set verbose 1
Verbosity was 4 and is now 1


Frequency Mismatch

[Sep  3 13:22:55] WARNING[23571]: format_wav.c:110 check_header_fmt: Unexpected frequency mismatch 44100 (expecting 8000)

You may have to convert the file into an appropriate format using ffmpeg or similar. See also this blog post.

File Not Found

[Sep  3 13:25:05] WARNING[23726]: file.c:663 ast_openstream_full: File custom/welcome-to-widgets-8000 does not exist in any format
[Sep  3 13:25:05] WARNING[23726]: file.c:958 ast_streamfile: Unable to open custom/welcome-to-widgets-8000 (format 0x4 (ulaw)): No such file or directory

You need to double check the spelling of the file name, that the file actually exists in the directory, that the permissions of the file and directory allow reading, and that the Asterisks thinks sounds are where you think they are.

You can try specifying the full path to the file, e.g.:

  same => n,Background(/usr/local/share/asterisk/sounds/custom/welcome-to-widgets-8000)

If that succeeds then double check your asterisk.conf file.

Adding a Domain To OpenWRT Barrier Breaker

So you’re running OpenWRT version 14.07 (Barrier Breaker). And you’ve got a dynamically updating domain name from

You want to configure your router to update your dynamic domain address to that of your WAN interface.

First things first, install the luci-app-ddns package on your router. Then reboot your router and log into the LuCI web interface.

Next navigate to the Services -> Dynamic DNS page:

Navigate to the Services > Dynamic DNS page

Navigate to the Services > Dynamic DNS page

Enter the dynamic DNS provider and account details

Enter the dynamic DNS provider and account details

Then enter the details of your dynamic domain name, your username and password.

Set the source of the IP address to interface and the interface to be your WAN interface (in my case my WAN interface is PPPoE).

That’s all there is to it!

If you are using an older version of OpenWRT you may wish to create a script to update the dynamic DNS. If this is the case then please visit this blog article.

Voipfone Peer With Asterisk Reports No Funds

I had set up Voipfone (a VoIP provider) as a peer to my Asterisk server. It registered fine and my extensions could call the Voipfone test numbers without any problems (155 the confirmation test, 152 the echo test).

But whenever I tried to call a real phone number (my mobile or a local store) I got the following message in a British female voice:

Sorry your call can't be connected. Please try again.

I turned on SIP debugging in Asterisk:

myuser@myhost:~# asterisk -r
myhost*CLI> sip set debug on

Note that in this example my Asterisk server is on The Voipfone SIP server is at My extension is 234 that I’m making the call from.

Next I tried making a call (to Pizza Hut at Thorpe Park) to 01932567159. Of interest were the following two entries:

Reliably Transmitting (NAT) to
Via: SIP/2.0/UDP;branch=z9hG4bK3700cafe;rport
From: "234" <>;tag=as36249d34
To: <>
CSeq: 102 INVITE
User-Agent: Asterisk PBX


<--- SIP read from UDP: --->
SIP/2.0 183 Session Progress
Via: SIP/2.0/UDP;branch=z9hG4bK3700cafe;received=;rport=5060
From: "234" <>;tag=as36249d34
To: <>;tag=VFa4bb2530035671ac22635ffaface
CSeq: 102 INVITE
User-Agent: Voipfone Sip Network

At this point I’m hearing the message on the phone to please try again. Now when the phone call ends I get:

<--- SIP read from UDP: --->
SIP/2.0 603 No Funds
Via: SIP/2.0/UDP;branch=z9hG4bK3700cafe;received=;rport=5060
From: "234" <>;tag=as36249d34
To: <>;tag=VFa4bb2530035671ac22635ffaface
CSeq: 102 INVITE
User-Agent: Voipfone Sip Network

Now I know I have funds. I logged into Voipfone and discovered I had plenty of funds in my account. So what was going wrong?

Well turns out Voipfone wasn’t keen on the user (From: e-mail address) being something other than my Voipfone account number.

I needed to add the following line to my sip.conf file under my peer block:


and re-loading the SIP configuration:

myuser@myhost:~# asterisk -r
myhost*CLI> sip reload

So my sip.conf now looks like:

register =>


Now, when I dial, I see the following sent to Voipfone from Asterisk:

Reliably Transmitting (NAT) to
Via: SIP/2.0/UDP;branch=z9hG4bK2a703134;rport
From: "234" <>;tag=as6b9ff512
To: <>;tag=VFa4bb2530035671ac22635ffadefa
CSeq: 102 INVITE

… and I get dialtone.

Accessing Panasonic KT-UX113 Phone Web Interface For The First Time

These notes have been taken from this blog post and trial-and-error.

After connecting the KT-UX113 Panasonic VoIP (SIP) phone to the Ethernet and, assuming your network has dynamically assigned it a DHCP address, do the following.

You’ll see an error displayed:

Connection error (90001)
Check server and set it.

Press Setup. Press Enter to select “Information Display”. Scroll down using the down arrow once to see your IP address:

IP Address

Now press Back. Then press the down arrow to select “Network Settings” and press Enter.

Scroll down to select “Embedded web”. Use the down arrow to change this setting to “On”.

Embedded web

Press Enter. You will hear a long beep.

Now in your web browser navigate to (or whatever the IP address was that you saw your phone displaying under “Information Display” -> “IP Address”.

You will be asked for a username and password. The defaults are user:admin, password:adminpass.

If you do not log in fast enough the embedded web server will switch off and you will have to enable it again on the phone.

You should see the following web page:

Panasonic KX-UT113 Web Page On First Login

Panasonic KX-UT113 Web Page On First Login

One of the first things you may wish to do is upgrade the firmware, the latest for each country can be found here. (It so happened that the phone I purchased off eBay in the UK already had the latest firmware). Firmware can be loaded through the web interface from the “Maintenance” tab.