login | register
20 Aug 2008 [10:15 UTC]

AussieVoIP

FreePBX, Trixbox and Australian Voice over IP Information

Similar PagesHistoryPrint

How to get the DID of a SIP trunk

Created by: wiseoldowl,Last modification on 18 Mar 2007 [09:02 UTC]

How to get the DID of a SIP trunk when the provider doesn't send it (and why some incoming SIP calls fail)


The symptom: On a SIP trunk, you can't get an inbound route to work - it just doesn't seem to recognize the number. You can get the call to go to your any DID/any CID route, or maybe the call doesn't get answered at all. When you type sip debug from the CLI, you can see (when you scroll back to the point where the call came in) that a sip INVITE packet arrived, and it contained the DID number in the sip To: header (in the form To: <sip:NUMBER@IP ADDRESS>), but you also see that the FROM_DID was set to s. In other words, you see a line that looks like this:
  -- Executing Set("SIP/9995552368-09876543", "FROM_DID=s") in new stack
So there the DID number is, in the sip INVITE packet's To: header, but the CLI reveals that Asterisk isn't picking it up, and therefore it goes to your default inbound route.

(Oh, and for anyone who's still trying to figure out how to turn off sip debugging, the CLI command is sip no debug)

Fortunately this isn't a hard thing to work around, as long as the DID number really is in the sip To: header. First, create a context in extensions_custom.conf that looks like this:
[custom-get-did-from-sip]
exten => _.,1,Noop(Fixing DID using information from SIP TO header)
exten => _.,n,Set(pseudodid=${SIP_HEADER(To)})
exten => _.,n,Set(pseudodid=${CUT(pseudodid,@,1)})
exten => _.,n,Set(pseudodid=${CUT(pseudodid,:,2)})
exten => _.,n,Goto(from-trunk,${pseudodid},1)
Or, thanks to naftali5, you can cut the above down to one line of code that does the same thing, but is a bit less obvious to the casual reader:
[custom-get-did-from-sip]
exten => _.,1,Goto(from-trunk,${CUT(CUT(SIP_HEADER(To),@,1),:,2)},1)
(And speaking of naftali5, if you are using his Dialplan Injections module, and want to put the above line in the Destination section, then you will need to use a slightly different syntax (changing the commas to bar characters), so it looks like this:
* Custom App: from-trunk,${CUT(CUT(SIP_HEADER(To)|@|1)|:|2)},1
The part after Custom App: is what you paste into the text box. This ONLY applies to Dialplan Injection users)

Then, in the trunk associated with the provider, change the trunk context statement (which should read context=from-trunk) to:
context=custom-get-did-from-sip
(Or for Dialplan Injection users, just use
context=injection-n
but replace n with the actual injection number, which will appear next to the injection name in the right-hand column menu of injections.)

And note that with such providers, you may have to move that context statement from the USER details to the PEER details section. This is why calls from some SIP providers sometimes fail to come in at all - they effectively never "see" the User context and details, therefore they don't see the context statement there and have nowhere to go. It's also why you sometimes see instructions for sip providers that leave the User context and User details sections totally blank, but include a context statement in the peer details - in most such cases it's because the provider is treating the customer as an end user (like someone using a softphone or a VoiP adapter) rather than as a peer, and they aren't sending DID information.

The above instructions may also solve the problem where you have two (or more) trunks from the same provider, but Asterisk always treats it as if all calls are coming in on one of the two trunks, therefore again not allowing you to set up separate inbound routes for each trunk. As long as the provider sends the number in the sip To header, the above code should set the DID properly.

If the first part of the To: statement is something other than a DID number (a user name, for example), then you may have to add a line just before the final Goto statement. For example, let's say the provider is sending To: <sip:Fred@IP ADDRESS> and your DID number (or at least, the number you want to use to denote your inbound route) is really 5551212. You'd then use code similar to this:
[custom-get-did-from-sip]
exten => _.,1,Noop(Fixing DID using information from SIP TO header)
exten => _.,n,Set(pseudodid=${CUT(CUT(SIP_HEADER(To),@,1),:,2)})
exten => _.,n,Set(pseudodid=${IF($["${pseudodid}"="Fred"]?5551212:${pseudodid})})
exten => _.,n,Goto(from-trunk,${pseudodid},1)
Or, as long as you only have ONE trunk from that provider, you could always just cheat a little and hardcode the desired DID in a separate custom context, like this:
[custom-stupid-provider]
exten => _.,1,Noop(Fixing DID to 5551212)
exten => _.,n,Goto(from-trunk,5551212,1)
And use the name of this context in the trunk settings. I hear you asking, why not just do it this way on all trunks with this issue? Well, because if you add a second trunk from the same provider, this won't work correctly for both trunks, and if you ever change your number and then forget what you've done and just try to set your inbound route to the new number, it won't work. And besides all that, if you have more than one SIP provider that doesn't send proper DID, you'd have to create a separate custom context for each of them, instead of having one custom context that works for all of them.

One final note for Free World Dialup users, you may find that sip calls will still not come in until you put the following statement in sip.conf:
insecure=invite
I have no idea why that works, but it seems to make a difference.

What if the provider doesn't send the number in the sip To: header?


There is at least one provider that actually sends a s character instead of a number in the sip To: header. What can you do with a provider like that? Well, all may not be lost. If you only have a single trunk from that provider, you can just use the "cheat" shown above, since it doesn't rely on the contents of the sip headers. If, however, you have TWO or more trunks from the same provider, you can do a sip debug from the CLI and watch as calls come in on each trunk and note whether there are any consistent differences.

For example, if you have two lines on the same account, the provider will often assume that you are using a VoIP adapter (such as a Sipura or Linksys) and will use port 5060 for line 1, and port 5061 for line 2. That difference might show up in the headers of the sip INVITE packet, for example:
Via: SIP/2.0/UDP 111.222.333.444:5060;branch=z9hQ4bK67sc0a8e;rport
In this case, you see that there is a colon (:) before the port number and a semicolon following, and that there are actually TWO colons on the line before the port number, so maybe this would work:
[custom-really-stupid-provider]
exten => _.,1,Noop(Fixing DID using port from SIP VIA header)
exten => _.,n,Set(pseudodid=${CUT(CUT(SIP_HEADER(Via),;,1),:,3)})
exten => _.,n,Set(pseudodid=${IF($["${pseudodid}"="5060"]?5551111:${pseudodid})})
exten => _.,n,Set(pseudodid=${IF($["${pseudodid}"="5061"]?5552222:${pseudodid})})
exten => _.,n,Goto(from-trunk,${pseudodid},1)
Or, if you only have two trunks from this provider, you probably could just condense the two test lines into one, by testing for one port number and assuming the other if the conditional test fails, like this:
exten => _.,n,Set(pseudodid=${IF($["${pseudodid}"="5060"]?5551111:5552222)})
Note that the code in this section is untested, it's just to give you some ideas about how to possibly handle the really oddball situation were you have two (or more) lines from the same provider, and cannot find any other way to differentiate them. And, don't automatically assume you have a bigger problem than you actually have - for example, it may well be that having different port numbers on the different trunks would allow Asterisk to distinguish them enough that the simple "cheat" method would work (you'd have to make one for each trunk, of course).

Additional Reference:

Asterisk SIP channels

back to content

bitweaver

Powered by

  • Powered by bitweaver
  • Powered by Smarty
  • Powered by Adodb
  • Powered by MySQL
back to content

Site Navigation

back to content
Powered by bitweaver