Read extension from first diversion header

We have a SIP trunk connection cisco callmanager 6.1.5 to FreePBX. All phones register with callmanager and FreePBX is used for voicemail only. Everything except the following is working fine. If a manager forwards their phone to their secretary and a call comes in and the secretary does not pick up the incoming call is sent to the secretary’s voicemail instead of the manager. Callmanager is sending all the correct diversion headers as you see a diversion header for each extension the call touched on its way to voicemail.

How do I read the extension out of the first diversion header so I can send the call to that extension’s voicemail on FreePBX? I’ve tried the SIP_HEADER() function in the extensions_custom.conf file, but not having any success so far. Bellow are the diversion headers associated with a forwaded call ending up in voicemail.

Diversion: “Brian” sip:[email protected];reason=user-busy;privacy=off;screen=yes
Diversion: “Guest” sip:[email protected];reason=unconditional;privacy=off;screen=yes


Diversion: "Brian" <sip:[email protected]>;reason=user-busy;privacy=off;screen=yes
Diversion: "Guest" <sip:[email protected]>;reason=unconditional;privacy=off;screen=yes

is SIP_HEADER() pulling anything out?

Or is it pulling the wrong header? (the Secretarie’s in stead of the bosses)?

If it’s not pulling anything, I’d have a closer look, ti should be able to get any header. If it is pulling out the wrong one, then see the help (per my 1.4 system):


Gets the specified SIP header

Since there are several headers (such as Via) which can occur multiple
times, SIP_HEADER takes an optional second argument to specify which header with
that name to retrieve. Headers start at offset 1.

Note the offset, try 2.


Above is what I am trying with no success. I don’t see anything in the asterisk real time console. It seems to be ignored.

No doubt I’m misunderstanding the use of the SIP_HEADER function.

The function works, try pulling some other headers to make sure that you can get something.

Try also turning on SIP debug in Asterisk for that trunk so you can see the SIP messages and exactly what is being transmitted (if you are not already doing that).

I can’t say I’ve tried to pull Diversion headers with SIP_HEADER() but I know it works as I’ve used it for other fields. (I have never tried it for multiple repeated fields though).

Thank you; turning on SIP debugging helped and I should have thought of that myself.

The diversion headers are coming over from callmanager, but it looks like they get stripped out before being sent to the voicemail extension processing in extensions_custom.conf. I need to somehow find the last diversion header before the call gets sent to the processing for the voicemail extension and set the rdnis variable to the extension in that diversion header.

I’m not sure where and how to do this. Any help to get me started would be very appreciated.

I would configure the trunk to go somewhere like:


in place of the default from-pstn or equivalent.

Then, define that context in extension_custom.conf where you can do what ever logic you need to in processing it and changing what ever you need to change, after which you can either send it on its way to from-pstn modified or otherwise directly to where ever you need to send it.

Thanks Philippe for all the help.

Below is the dial-plan programming that will cycle through all of the diversion headers sent from callmanager. The highest indexed diversion header is the one you want in order to get the extension of the original extension dialed by the caller. The below has to be included into the from-pstn-custom context in the extensions_custom.conf file.

exten => 232,1,Set(x=1)
exten => 232,n,While($["${SIP_HEADER(Diversion,${x})}" != ""])
exten => 232,n,Set(mb="${SIP_HEADER(Diversion,${x})}")
exten => 232,n,Set(mb=${CUT(mb,@,1):-4})
exten => 232,n,Set(x=$[${x}+1])
exten => 232,n,EndWhile()

If anyone knows of a more elegant way of doing this please post.

the basic loop looks reasonable (if you really wanted you could combine the first two Set() commands into 1 :slight_smile:

You cold probably generalize it and then I wouldn’t put it in from-pstn-custom, I would put it in its own context and direct the callmanager sip trunk to that context.

Then you would end up with something like this:

exten => _X.,1,Set(mb=${EXTEN})
exten => _X.,n,Set(x=1)
exten => _X.,n,While($["${SIP_HEADER(Diversion,${x})}" != ""])
exten => _X.,n,Set(mb="${SIP_HEADER(Diversion,${x})}")
exten => _X.,n,Set(mb=${CUT(mb,@,1):-4})
exten => _X.,n,Set(x=$[${x}+1])
exten => _X.,n,EndWhile()
exten=>  _X.,n,Goto(from-pstn,${mb},1)

Of course if this is purely dedicated to voicemail, you may want to have a closer look at the dialplan and direct it directly to the appropriate dialplan that deals with voicemail. Furthermore, you may want to have a closer look at the sip packets coming in during different scenarios. (The user was busy, the user was unavailable, etc.) and see if there is anything in the signaling that would indicated which situation occurred. (Note the reason=user_busy and various other reason codes). You could use this to route to either the busy or unavailable voicemail modes which would be an added bonus!