How to make internal calls ring differently from external ones

wiseoldowl's picture

Every so often I see someone ask whether it's possible to make internal calls have a distinctive ring from external ones. I thought it would not be that difficult, but I was wrong. Let's say that you have three-digit extensions, and whenever someone calls extension 234 you want it to ring with the normal pattern if it's an external call, but with a different pattern if it's an internal call (and we assume here that the endpoint supports this). This is as far as I got - in extensions_custom.conf, I added the following at the bottom of the [from-internal-custom] context:

exten => 234,1,Goto(checkiflocal,${EXTEN},1)

[checkiflocal]
exten => _XXX,1,GotoIf($["${CALLERID(num)}" > "999"]?notfromext)
exten => _XXX,n,GotoIf($["${CALLERID(num)}" < "100"]?notfromext)
exten => _XXX,n,Set(__ALERT_INFO=Bellcore-r4)
exten => _XXX,n(notfromext),Goto(from-internal,${EXTEN},2)

The above actually works in testing, but it's not right. The problem here is returning to the from-internal context. What I want it to do is return to from-internal and continue processing without skipping anything that should execute, but an include apparently isn't designed that way. The first statement that matches extension 234 apparently means that the next statement must be number 2, or something like that (I'm REALLY confused at the moment). Anyway, the difference is that when I make a call without the above added lines, the first two lines of CLI output are these:

-- Executing [234@from-internal:1] GotoIf("SIP/230-b7d17a30", "0?ext-local|234|1") in new stack
-- Executing [234@from-internal:2] Macro("SIP/230-b7d17a30", "user-callerid|") in new stack

BUT, if I use the above added code, the conditional call to ext-local is completely skipped, and after executing my added lines it picks up with the second line. You might say "but of course, because you are specifying line 2 in the Goto" - but if I specify Line 1, it just goes into an endless loop until I hang up.

Is there some way I can accomplish the above without skipping the conditional call to ext-local? So far that doesn't seem to make a difference, but then I have no idea where that Gosub is in the actual code so I have no idea under what circumstances the call to ext-local is supposed to be invoked. And there may be other includes that are being skipped as well.

Any thoughts?


__________________


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

We have done this by setting

mickecarlsson's picture

We have done this by setting all indound DID's with alert info and have our endpoints configured so that it will trigger the second ring signal if alert info is received. Internal calls will ring whatever the signal is set to on the endpoint as default.


__________________

Mikael Carlsson, FreePBX Development Team
Get Official Paid Support - Click Here


I knew there was some

wiseoldowl's picture

Thanks… I knew there was some obvious solution I was overlooking … although it would be nice to be able to explicitly specify an alert-info for internal calls, and another for external calls, as requested here: http://www.freepbx.org/trac/ticket/3937 (although the more I think about it, the more I think this functionality really ought to be on a per-extension basis, not a per-followme basis, since different endpoints may use different alert info strings, and not all of those may be configurable).


Finally figured out a way to do it, that is very configurable!

wiseoldowl's picture

I was actually on the right track, but not doing it in the right place. The trick is to put the following code in /etc/asterisk/extensions_override_freepbx.conf :

[from-internal]
include => set-alert-if-local

[from-internal-original]
include => from-internal-xfer
include => bad-number

[set-alert-if-local]
exten => 234,1,GotoIf($["${CALLERID(num)}" > "999"]?notfromlocal)
exten => 234,n,GotoIf($["${CALLERID(num)}" < "100"]?notfromlocal)
exten => 234,n,Set(__ALERT_INFO=Bellcore-r3)
exten => 234,n(notfromlocal),Goto(from-internal-original,${EXTEN},1)
;The following three lines must not be changed!
exten => _.,1,Goto(from-internal-original,${EXTEN},1)
exten => s,1,Goto(from-internal-original,s,1)
exten => h,1,Macro(hangupcall)

The real action is in the four lines following the [set-alert-if-local] context tag, which can be duplicated as often as necessary for the number of extensions you have and the different ring patterns. Specifically:

All four lines must begin with either exten => extension, or exten => _pattern, — this defines which extension or group of extensions the rule is to apply to. Don't forget the leading underscore if using a pattern.

The first two lines define the upper and lower boundaries of what is considered a local extension - in this case, anything above 999 or below 100 would not be considered local. Therefore, you can set the distinctive ring to occur only if the call is from a particular group of extensions (a subset of your local extensions) or even compress this down to a single line and do an exact match on a particular calling extension (e.g. the boss!).

The third line sets the Alert Info string, and must be the correct string for the endpoint. You could have multiple rules to have different distinctive rings for different individual calling extensions, or groups of extensions.

The fourth line after the [set-alert-if-local] context tag should be included verbatim, except of course that if you have multiple rule sets then each one must have a unique label here (and that label must also be changed to match in the first two lines after the [set-alert-if-local] tag). So, if I had multiple rules here, instead of using notfromlocal I might use notfromlocal234, so I could keep my labels straight when reading down the list (also that would be easier to auto-generate if anyone ever writes a module to do this).

All the other lines should probably be left unchanged, although I have a feeling that someone will say I should not use the _. pattern in the catch-all line that follows the comment. I was basically following the lead of whoever wrote the [from-sip-external] context in extensions.conf (see the comment in that section of code).

One caveat, I haven't upgraded to 2.6 yet so if you have, be sure to check /etc/asterisk/extensions.conf and make sure that the [from-internal] context hasn't changed - that's what I copied verbatim to the [from-internal-original] context here, so if that changes in extensions.conf then it must be changed here in extensions_override_freepbx.conf as well.

I'll probably copy this information to a How-To in a day or two, but wanted to post it here first so that you guys could critique it and tell me if I'm doing anything I shouldn't here. And no, I an not real crazy about putting the [from-internal] context in extensions_override_freepbx.conf, but everything I tried in extensions_custom.conf had unwanted side effects. When I get around to doing the How-To I'll definitely mention mickecarlsson's technique first, since that will be easier in many situations (especially where are your endpoints use the same Alert Info strings).


alert-Info in inbound works only if destination is extension

mappletree's picture

I've actually used the technique referred to by mickecarlsson and it works as long as the destination object of the inbound route is an extension.

As soon as the destination of the call is a different object (queue, ring group, etc.) it looses the Alert-Info information along the way and by the time the call goes to an extension.

This is my experience with FreePBX 2.5