Skip to main content

DID routing based on SIP Headers

Posted by Denis Campq on Fri, 02/27/2009

Just ran into an issue with DIDs being sent from different SIP providers using different parts of the SIP Header. One provider users the Contact Header to send DIDs and the other uses the TO: header.

I was able to clone the script that uses the TO: header for DID and get the Broadvox trunk working or use the script to use the CONTACT header field but can't figure out how to get them both to work.

I think I need to extract the header information based on the Trunk but I can't figure out a way to make both work on our MT. The scrip I modified gets kicked off in extensions.conf from-outside context.

Any help would be very much appreaciated.


Submitted by eeman on Fri, 02/27/2009 Permalink

so you want a script that matches against 's' that will route either for the TO or the CONTACT?

do you have examples of how they present and what the other header looks like when its empty?

personally i think writing a script is the wrong approach. I think from-outside should be pure and you should drop the call into another context that re-routes back to from-outside once you fix the header issue. Its apparent that this problem isnt going to limit itself to just these 2 providers. Soon provider Z is going to use TO headers but format them differently etc. Its looking very unlikely you will find a one-shoe-fits all script.

take trunk X and send it to a custom context in user_extensions.include

user_extensions.include:

[trunk-x]

exten => s,1,Goto(from-outside,${CUT(${CUT(${SIP_HEADER(TO)},\:,2)},\@,1)},1)

[trunk-y]

exten => s,1,Goto(from-outside,${CUT(${CUT(${SIP_HEADER(CONTACT)},\:,2)},\@,1)},1)

the above is pseudo code as I havent seen the actual header to know how to parse it.

Submitted by Denis Campq on Sat, 02/28/2009 Permalink

Thanks Erik,

I was able to accomplish what I needed last night in >10 lines of script code . Your example accomplishes what I did in one line. The mark of a true programmer.

The flexibility of Thirdlane's open design really shines when it comes to accomplishing a desired result like this.

Your input is very much appreciated.

Denis Camp

ABP Technology

Submitted by Denis Campq on Sat, 02/28/2009 Permalink

How can I add to the drop down Context List on the Trunk configuration page?

I would like to select from the drop down Context list a custom context to do the header extract for the specific trunk and then point it back to from-outside keeping it pure as you suggested. My thought is to create a SIP trunk and select from the drop down list the context you want to use to get the DID from where ever the provider puts the DID in the SIP Header.

I am a little unclear as to the first place the call is sent when the Invite is received from the SIP Trunk. I always thought the call went to extensions.conf from-outside context first. Can you clarify how the incoming call is first processed for MT.

Submitted by eeman on Sat, 02/28/2009 Permalink

well if alex were to add a 'custom' option for trunks that lets you name the context that would be great. Until then I'd say create your trunk then edit sip.conf manually to change the context. With regards to what context a call goes to first, its the context= statement in the channel driver config (zapata.conf, sip.conf, iax.conf etc).

For example in my STE at my house I have sip trunks and a FXO trunk from my phone company. I have a lot of marketing calls that call me with predictive dialers, so I blacklist them. I have the zap channel going to a from-windstream context which looks like:

[from-windstream]

exten => s,1,Wait(.5)

exten => s,n,NoOp(${CALLERID(num)})

exten => s,n,GotoIf(${DB_EXISTS(wsblacklist/${CALLERID(num)})}?from-specialring,s,1)

exten => s,n,Goto(from-outside,s,1)

and for the blacklisted numbers

[from-specialring]

exten => s,1,Answer

exten => s,n,Wait(.5)

exten => s,n,Zapateller

exten => s,n,Playback(cannot-complete-as-dialed)

exten => s,n,Playback(hangup-try-again)

exten => s,n,Playback(cause-code)

exten => s,n,Playback(alaska)

exten => s,n,Wait(1)

exten => s,n,Hangup

Submitted by Denis Campq on Sat, 02/28/2009 Permalink

I tried to change the Context in sip.conf for the trunk but the changes are rewritten back to from-outside when the trunk is modified and saved with the GUI.

I also tried to add the trunks to user-extensions.include as you suggested but the call doesn't go there initially since the call is first sent to sip.conf to get the Trunk and context of the Trunk. Would like to find a flexible and safe solution because more and more SIP trunks will be coming and the current SIP standard leaves to much room for the developers to put DIDs where they want.

Submitted by eeman on Sat, 02/28/2009 Permalink

well yea the setting will get re-written if you edit the trunk, but how often are you editing a trunk once you set it up? its a good stop-gap until the gui gets modified.

Submitted by gb_delti on Thu, 09/17/2009 Permalink

I have the same problem (DID is placed in a custom "X-Number" header) but so far didn't get it to work.

I have placed the following script in user_extensions.include:

[from-efon]

exten => s,n,Set(INCOMINGNUMBER=${SIP_HEADER(X-Number)})

exten => s,n,NoOp(Incoming e-fon number: ${INCOMINGNUMBER})

exten => s,n,Goto(from-outside-redir,${INCOMINGNUMBER},1)

exten => i,1,Nop(Invalid extension ${EXTEN})

exten => i,n,Hangup()

I've put the line

context=e-fon

in the appropriate trunk entry in sip.conf (and paid attention that no other context line exists for this entry)

I rave reloaded the diaplan and the SIP config, but when a call comes in, I get the error message

Call from '0615004480' to extension 's' rejected because extension not found.

What am I doing wrong?

Submitted by gb_delti on Fri, 09/18/2009 Permalink

At first I facepalmed, but then looked again in my sip.conf. I really have "context=from-efon" in my sip.conf, not the one I posted here. And it still doesn't work. I already have set the log output to "very verbose" but still don't get more error information than the one I posted.