Category Archives: Asterisk

Groundwire push notifications with private SIP server

Acrobits’ Groundwire is a SIP soft-phone app for iOS. To receive incoming calls while the app is inactive, it either runs in the background (which drains the battery pretty quickly) or uses push notifications. The latter requires you to entrust Acrobits’ servers with your login credentials and only works for SIP servers reachable from the internet, so it is is not an option for private/internal SIP servers.

However, Acrobits offers a push notification HTTP API. This article tells you how to use it for this purpose.

First, you need the app to report its push token to your server. A PHP script like this one can accept this information and store it into your Asterisk server’s database:

$key = $_POST['username'];
$key = filter_var($key, FILTER_SANITIZE_NUMBER_INT);
$value = $_POST['token'];
if ($value == '')
 header('HTTP/1.0 422 Unprocessable Entity', TRUE, 422);
 die('No token provided');
shell_exec("sudo asterisk -rx 'database put GroundwireToken " . escapeshellarg($key) . " " . escapeshellarg($value) . "'");

$value = $_POST['selector'];
shell_exec("sudo asterisk -rx 'database put GroundwireSelector " . escapeshellarg($key) . " " . escapeshellarg($value) . "'");

$value = $_POST['appid'];
shell_exec("sudo asterisk -rx 'database put GroundwireApp " . escapeshellarg($key) . " " . escapeshellarg($value) . "'");

In Groundwire, go to Settings, Accounts, edit your account, Advanced Settings, Web Services, Push Token Reporter. For URL, enter the full URL of the above script. For POST, enter

Second, you need to modify your dialplan to send a push notification that wakes up the app. I created a subroutine for that purpose:

exten => _XX,1,GotoIf(${DB_EXISTS(GroundwireToken/${EXTEN})}]?groundwire)
same => n,Return()
same => n(groundwire),Set(push_data=verb=NotifyTextMessage&Selector=${URIENCODE(${DB(GroundwireSelector/${EXTEN})})}&DeviceToken=${URIENCODE(${DB(GroundwireToken/${EXTEN})})}&AppId=${URIENCODE(${DB(GroundwireApp/${EXTEN})})})
same => n,Noop(Groundwire: ${CURL("",${push_data})})
same => n,Ringing()
same => n,Wait(3) ; give app some time to activate
same => n(done),Return()
exten => i,1,Return()
exten => s,1,Return()

Then, in your dialplan, call that subroutine, like so:

exten => _XX,Noop(Incoming call for ${EXTEN})
same => n,Gosub(sub-push,${EXTEN},1)
same => n,Dial(SIP/${EXTEN})

Because there is no (documented) way to tell the app to dial a number (e.g. one that does PickupChan(SIP/${CALLERID(num)})) when it receives the push notification, we are simply waiting for three seconds for the app to launch and register and then proceed signalling the call.

Asterisk 11 und Sipgate Basic

Für ältere Asterisk-Versionen hat Sipgate in seinen FAQs passende Einträge für die sip.conf aufgeführt. Unter Asterisk 11 hat sich leider die NAT-Behandlung etwas verändert (nat=yes gibt es nicht mehr), deswegen hier meine funktionierende Konfiguration (SIPID durch die Kundennummer und SIPPWD durch das SIP-Passwort ersetzen):


In der [global]-Section habe ich außerdem


Erläuterungen zu den Einstellungen, die potentiell problematisch sind:

  • nat: wenn hier was anderes steht, werden eingehende Anrufe nicht immer signalisiert. Unter Asterisk 1.8 und früher ging nat=yes.
  • qualify: sendet regelmäßig SIP-Pakete, um in der NAT-Tabelle des Routers zu bleiben. Wenn das nicht aktiviert ist,w erden eingehende Anrufe nicht immer signalisiert.
  • canreinvite: muss deaktiviert sein, weil sonst der UDP-Port für RTP nach der Anrufannahme noch geändert werden kann. Der Router hat den Port dann nicht in seiner NAT-Tabelle und verwirft die Pakete, dementsprechend wird kein Ton übertragen.
  • callbackextension: hiermit spart man sich eine Zeile wie register => in der [global]-Sektion. Wichtig: die lokale Extension (das ist der Wert von callbackextension bzw. der nach dem Schrägstrich in der register-Zeile) muss unbedingt gleich der SIPID sein. Wenn er das nicht ist, wird der erste eingehende Anruf nach einer Wartezeit von ca. 30 Minuten oder mehr zwar signalisiert, aber der Anrufer bekommt auch nach dem Annehmen weiterhin das Freizeichen (ein iPhone im Vodafone-Netz zeigte bei mir nach einige Sekunden nach dem Annehmen dann “Anruf fehlgeschlagen” an) und der Angerufene bekommt keinen Ton. Ich hatte ursprünglich nur register => (entspricht callbackextension=s), was auch ging — nur andere Zahlen, z.B. die eigene Telefonnummer, verursachen das Problem.
  • trustrpid: Bei Sipgate-internen Anrufen steht bei eingehenden Anrufen im From-Feld des SIP-Headers nicht immer die Nummer des Anrufers, sondern z.B. dessen Kundennummer. In dem Fall wird die korrekte Nummer im Feld P-Asserted-Identity mitgesendet und mit dieser Option wird sie später ins From-Feld kopiert.
  • sendrpid: Falls man im Dialplan die CONNECTEDLINE-Funktion benutzt, um bei ausgehenden Anrufen Text im Display des Telefons anzuzeigen (und dafür in [global] den Wert sendrpid=pai gesetzt hat), sollte man es für Sipgate hier deaktivieren.

Mit der obigen Konfiguration landen eingehende Sipgate-Anrufe im Dialplan unter SIPID@sipgate-in. Ausgehende Anrufe bekommt man im Dialplan mit

exten => _0049X.,1,Goto(0${EXTEN:4},1)
exten => _+49X.,1,Goto(0${EXTEN:3},1)
exten => _+XXX.,1,Goto(00${EXTEN:1},1)
exten => _XXX.,1,Set(CALLERID(number)=SIPID)
same => n,Set(CALLERID(name)=49123456789)
same => n,Dial(SIP/${EXTEN}@sipgate-SIPID,,rWT)

wobei 49123456789 die gewünschte Absenderrufnummer ist, wenn im Sipgate-Account bei Absenderrufnummer “setzt das Endgerät” ausgewählt ist. Für die Standardnummer kann man diese Zeile auch weglassen.

Eingehende Anrufe gehen so (angenommen, man hat ein internes SIP-Endgerät mit der Nummer 20 angelegt):

exten => SIPID,1,Dial(SIP/20)

Asterisk: Change number in To header

A long time ago, I wrote about changing the callee ID as seen by the caller using CONNECTEDLINE.
Changing the caller ID as seen by the callee is also pretty obvious using CALLERID.
That leaves two more constellations: changing the caller ID as seen by the caller (which doesn’t make sense because a phone typically doesn’t display its own number on outgoing calls)., and changing the callee ID as seen by the callee, which I’ll talk about here now.

The reason you might want to do this is because you have multiple PSTN phone numbers that ring the same SIP phone. The obvious way to solve this would be to use

exten => _X.,n,SipAddHeader(To: "123456" <sip:123456@server>)
exten => _X.,n,Dial(SIP/${EXTEN})

, but that doesn’t work because SipAddHeader doesn’t overwrite existing headers, it only adds new ones. The Snom forum mentions a hack using the Diversion header, assuming your phone does indeed display that. A much nicer way is the following:

exten => _X.,n,Dial(SIP/${EXTEN}!123456)

. The number after the exclamation mark is simply what Asterisk uses as the local part when it composes the To URI. This features is not well-documented, but from the code I guess it was introduced in Asterisk 1.6. Asterisk 1.8’s (and higher) chan_sip.c gives a short explanation:

 *  SIP Dial string syntax:
 *       SIP/devicename
 *  or   SIP/username@domain (SIP uri)
 * or   SIP/username[:password[:md5secret[:authname[:transport]]]]@host[:port]
 * or   SIP/devicename/extension
 *  or   SIP/devicename/extension/IPorHost
 * or   SIP/username@domain//IPorHost
 * and there is an optional [!dnid] argument you can append to alter the
 *  To: header.

Asterisk: Remotely retrieving voicemail by pressing *

Many howtos around the internet on how to remotely access your voicemail box involve a dedicated extension reachable from the outside or an IVR menu entry. But wouldn’t it be much nicer if you could just press the * DTMF key during the announcement? Turns out, this is quite simple:

exten => s,1,Dial(SIP/1234,20)
exten => s,n,Voicemail(1234,us)
exten => a,1,VoiceMailMain(1234)
exten => a,n,Hangup()

And it even works when you’re using macros (like I am):

exten => 5551234,1,Macro(incoming-plus-voicemail,SIP/1234,20,1234)
exten => 5551337,1,Macro(incoming-plus-voicemail,SIP/1337,20,1337)

[macro-incoming-plus-voicemail] ; SIP/xxx, wait time, voicemail
exten => s,1,Dial(${ARG1},${ARG2}
exten => s,n,Voicemail(${ARG3},us)
push * during the announcement to access your mailbox
exten => a,1,VoiceMailMain(${ARG3})
exten => a,n,Hangup()

Asterisk: Compile SRTP Module without recompiling Asterisk

I recently installed Asterisk 1.8.3 (the Asterisk team now provides pre-built Debian packages at
Unfortunately, that package came without the res_srtp SRTP module. (UPDATE: Starting in 1.8.4, it does come with it.) Because I didn’t feel like re-compiling the entire package, I just took the corresponding version of res_srtp.c from the SVN, added the following lines to the beginning of it:

#ifndef AST_MODULE
#define AST_MODULE "res_srtp"

and compiled and installed it using

gcc -shared res_srtp.c -o -lsrtp
sudo cp /usr/lib/asterisk/modules/

You’ll need to have libsrtp0-dev and asterisk-dev installed, otherwise the compile will fail.
Then, you can do sudo asterisk -r and load the module using module load res_srtp (or just restart Asterisk).

I’m still working on getting SRTP working flawlessly both incoming and outgoing and with stuff like transfers. Asterisk Secure Calling Specifics are a good starting point, but I’m also planning to write another post about this in the near future.

Asterisk: Change Callee-ID using CONNECTEDLINE

It’s easy to change your Caller ID (assuming your phone provider doesn’t filter it) in Asterisk using something like Set(CALLERID(name)=blah). This is often used to choose which number to use for an outgoing call if you have multiple on a single SIP or ISDN trunk.

But did you know it’s just as easy to change the Callee ID on an outgoing call, i.e. change what your phone displays during the call? This can be very useful to display on the phone which one of several possible outgoing lines (multiple SIP providers, ISDN, …) was used or at which point in an IVR menu you are at the moment. To do this, use Set(CONNECTEDLINE(name)=blah). Before getting started, set sendrpid = pai in your sip.conf.

To make things easier, I created two macros in my dialplan:

exten => s,1,Set(CONNECTEDLINE(name,i)=${ARG1})
exten => s,n,Set(CONNECTEDLINE(number,i)=${ARG2})
exten => s,n,Set(CONNECTEDLINE(pres)=allowed)

exten => s,1,Macro(connectedline-name-number,${ARG1}, ${MACRO_EXTEN})

Now I can do things like

exten => 101,1,Answer()
exten => 101,n,Macro(connectedline-name,Hello World)
exten => 101,n,Playback(hello-world)
exten => 101,n,Hangup()

in my dialplan (IVR example).

Or how about

exten => 100,1,Macro(connectedline-name,Mailbox)
exten => 100,n,VoiceMailMain(${CALLERID(num)},s)
exten => _XXX.,n,Macro(connectedline-name,VoIP 1)
exten => _XXX.,n,Dial(SIP/${EXTEN}@voipprovider)

(outgoing line example).

The Asterisk Wiki also has an entire page on Manipulating Party ID Information.