Custom Failover Module - Preserving Caller ID

I wrote a little module in extension_custom.conf, which checks to see if a remote SIP extension’s status is OK, and if not, transfers the call to a cell phone. Here is the module:

[failover]
exten => s,1,NoOp(Failover Check)
    same => n,GotoIf($["${SIPPEER(11801,status):0:3}"="OK "]?good)
    same => n,GotoIf($["${SIPPEER(11802,status):0:3}"="OK "]?good)
    same => n(fail),Dial(Local/15555555555@outbound-allroutes)
    same => n(good),Return()

I then create a Custom Destination with " failover,s,1 " and set the Return value to the desired ring group. When both extensions go offline, the call rings the cell phone, but the original caller ID is not preserved. Instead, the cell phone receives the default caller ID of the outbound trunk.

Can anyone offer some tips to improve this module, ideally preserving the original Caller ID? Should I use a transfer or goto function instead of dial? Any thoughts would be appreciated.

You realize this can be done inside FreePBX already. In the extension page you can set a UNREACHABLE destination

I do that for individual extensions, but I needed a way to handle incoming routes that pointed to a ring group.

My example above checks two extensions, and if either of them are Status OK, the call proceeds to the ring group via Return(). Otherwise, the call goes to the alternate destination (but unfortunately, with the wrong Caller ID).

I would try a goto to from-internal

Hi,

Change the fail line to that:

same => n(fail),Dial(Local/15555555555@outbound-allroutes/n)

The /n modifier will help you to preserver all the previous channel variables. Take a look at this link:
https://wiki.asterisk.org/wiki/display/AST/Local+Channel+Modifiers

Thank you,

Daniel Friedman
Trixton LTD.

1 Like

Thanks for the suggestions. I tried these two methods:

Goto(from-internal,15555555555,1)

Dial(Local/15555555555@outbound-allroutes/n)

But the caller ID was not preserved in either case.

If I put this command above the dial command:

NoOp(${CALLERID(num)})

then the correct Caller ID is printed to the log. So I know the information is there. I’m so close…

Hi,

You can always set the caller id before your extensions status checking:

[failover]
exten => s,1,NoOp(Failover Check)
same => n,Set(CALLERID(all)=${CHANNEL(from)}
same => n,GotoIf($["${SIPPEER(11801,status):0:3}"="OK "]?good)
same => n,GotoIf($["${SIPPEER(11802,status):0:3}"="OK "]?good:fail)
same => n(fail),Dial(Local/15555555555@from-internal/n)
same => n(good),Return()

But, I think it might be possible that your provider is blocking any caller id that is not belongs to your trunk.

Thank you,

Daniel Friedman
Trixton LTD.

I’ve been able to determine that my SIP provider is not altering the caller ID in this case. For example, I can set any number as the outbound caller ID of my extension, and the provider allows it to go through.

Looking at the Asterisk logs, I can see where the caller ID is being set. Full logs are here:
http://pastebin.com/HdYTuN4N

The incoming caller ID that should be preserved has been replaced with 13333333333
The DID number I am calling is 14444444444
The default caller ID of the trunk is 15555555555

If you look at lines #66-80, you can see where the system is changing the caller ID to the trunk’s default.

Hi,

You do not allow an override in your trunk settings. Can you send me a screenshot of your sip trunk settings?

Thank you,

Daniel Friedman
Trixton LTD.

Sure. Here is a screenshot of my trunk settings (with sensitive info edited out)

http://ibin.co/2MCMakfr7YsV

Hi,

Let us add a small bypass:

[failover]
exten => s,1,NoOp(Failover Check)
same => n,Set(__USEROUTCID=${CALLERID(num)})
same => n,GotoIf($["${SIPPEER(11801,status):0:3}"="OK "]?good)
same => n,GotoIf($["${SIPPEER(11802,status):0:3}"="OK "]?good:fail)
same => n(fail),Dial(Local/15555555555@from-internal/n)
same => n(good),Return()

Please report back.

Thank you,

Daniel Friedman
Trixton LTD.

Daniel,

I added the line as you suggested, but still got the same result.

To simplify things, I’ve taken the status check out of the module, and stripped it down to the bare essentials:

exten => s,1,NoOp(*TEST* ${CALLERID(num)})
    same => n,Set(__USEROUTCID=${CALLERID(num)})
    same => n,Dial(Local/15555555555@from-internal/n)
    same => n,Hangup()

Hi,

Send the logs please,

Thank you,

Daniel Friedman
Trixton LTD.

Here are the full logs:
http://pastebin.com/SF12H5nk

Hi,

Try to set the dial plan like this:

exten => s,1,NoOp(*TEST* ${CALLERID(num)})
same => n,Set(__KEEPCID=YES)
same => n,Dial(Local/15555555555@from-internal/n)
same => n,Hangup()

Thank you,

Daniel Friedman
Trixton LTD.

I found a solution. I had to add this context to my extensions_custom.conf file:

[macro-dialout-trunk-predial-hook]
exten => s,1,NoOp()
    same => n,ExecIf($["${CALLERID(number)}"="15555555555"]?Set(CALLERID(number)=${REALCALLERIDNUM}))
    same => n,MacroExit()

Where 15555555555 is the trunk’s default Caller ID.

The REALCALLERIDNUM variable contained the Caller ID I wanted, and macro-dialout-trunk-predial-hook is automatically called before a trunk dials out. So I had it check to see if CALLERID was the default, and if so, replace it with REALCALLERIDNUM. Seems to be working perfectly now. Thank you to all who contributed to the discussion.