Asterisk: forward if peer unreachable

1

2

I would like to respond to incoming calls by checking if a specific peer is reachable, and dial the appropriate number accordingly.

Presently I did this:

exten => 1200,1,Answer()
same => n,Set(reachable=${SHELL(asterisk -rx "sip show peers" | grep ^cedrich-phone.*OK)})
same => n,GotoIf($["${LEN(${reachable})}" = "0"]?extoffline)
same => n,Dial(SIP/cedrich-phone,20)
same => n(extoffline),Dial(SIP/another-phone,20,tr)
same => n,Hangup()

Could you tell me if this is acceptable and if it can be improved by using the best practices?

Cedric H.

Posted 2013-10-13T16:48:02.320

Reputation: 121

Answers

5

Executing a shell of asterisk on an incoming call just doesn't feel right to me. It probably works ok but shouldn't the status of a peer be already known to asterisk?

I use the function SIPPEER() with which you can request the status of a peer. If the first 3 characters (of OK (44 ms)) is OK then you can call the peer. All other situations you can forward to another peer.

I do something like this:

exten => _202,1,Log(NOTICE,Dial Status of ${EXTEN}: ${SIPPEER(${EXTEN},status)})
exten => _202,n,GotoIf($["${SIPPEER(${EXTEN},status):0:3}"="OK "]?ok1:forward)
exten => _202,n(ok1),Log(NOTICE,Calling number is available)
exten => _202,n,Dial(SIP/${EXTEN},50,wW)
exten => _202,n,Hangup()
exten => _202,n(forward),Log(NOTICE,Calling forward number)
exten => _202,n,Dial(SIP/201,50,wW)
exten => _202,n,Hangup()

This checks the status before we're going to Dial() and goes to n(forward) if the peer is unavailable, busy or otherwise not OK.

There is however a small problem with this. When the peer denies the call (or is for another reason unavailable, e.g. he went online before our next online-check) the call doesn't get through.

There is a function DIALSTATUS we can use after the Dial() to check if the call was answered succefully. So use this after the Dial() and if it's not answered also do the forward. (It worked in a test i did. Denying the call gave BUSY in the log and went to the next peer)

You get something like this:

exten => _202,1,Log(NOTICE,Dial Status of ${EXTEN}: ${SIPPEER(${EXTEN},status)})
exten => _202,n,GotoIf($["${SIPPEER(${EXTEN},status):0:3}"="OK "]?ok1:forward)
exten => _202,n(ok1),Log(NOTICE,Calling number is available)
exten => _202,n,Dial(SIP/${EXTEN},50,wW)
exten => _202,n,Log(NOTICE,Dial status: ${DIALSTATUS})
exten => _202,n,GotoIf($["${DIALSTATUS)}"="ANSWER"]?ok2:forward)
exten => _202,n(ok2),Log(NOTICE,Successfull call)
exten => _202,n,Hangup()
exten => _202,n(forward),Log(NOTICE,Calling forward number)
exten => _202,n,Dial(SIP/201,50,wW)
exten => _202,n,Hangup()

I didn't test this last bit (with DIALSTATUS) extensively so you should do some test but here it seems to work.

Rik

Posted 2013-10-13T16:48:02.320

Reputation: 11 800

1

As @arheops mentioned, you can use DEVICE_STATE() to get the status of a specific device, if it's 1:1 mapping (1 account on 1 device). You can use the following:

${DEVICE_STATE(${CHANNEL(channeltype)}/${CHANNEL(peername)})}

Another possibility is EXTENSION_STATE() function in case you have 1:many mapping (one extension with more than one device).

Both can have hints as described here if you need to have one user to use multiple devices. Here you can see how to make dynamic hints

Stoinov

Posted 2013-10-13T16:48:02.320

Reputation: 264

-1

Use of system in dialplan will open shell and spawn 2 proccess for each call.

Sure asterisk have function for your task. It described in all books.

-= Info about function 'DEVICE_STATE' =- 

[Synopsis]
Get or Set a device state. 

[Description]
The DEVICE_STATE function can be used to retrieve the device state from any
device state provider. For example:
NoOp(SIP/mypeer has state ${DEVICE_STATE(SIP/mypeer)})
NoOp(Conference number 1234 has state ${DEVICE_STATE(MeetMe:1234)})
The DEVICE_STATE function can also be used to set custom device state from
the dialplan.  The 'Custom:' prefix must be used. For example:
Set(DEVICE_STATE(Custom:lamp1)=BUSY)
Set(DEVICE_STATE(Custom:lamp2)=NOT_INUSE)
You can subscribe to the status of a custom device state using a hint in
the dialplan:
exten => 1234,hint,Custom:lamp1
The possible values for both uses of this function are:
UNKNOWN | NOT_INUSE | INUSE | BUSY | INVALID | UNAVAILABLE | RINGING |
RINGINUSE | ONHOLD

arheops

Posted 2013-10-13T16:48:02.320

Reputation: 977

I'd be happy to upvote your answer or even accept it if you could remove your useless first sentence and if you could expend your answer, not just copy pasting... – Cedric H. – 2013-10-20T09:56:42.993

I am ok if you not upvote it. I am sorry, it is not clear what exactly i have expand. IF you need more info, you always can search by info provided, for example read this page http://www.voip-info.org/wiki/view/Asterisk+func+device_State. Or install freepbx and check it dialplan.

– arheops – 2013-10-20T13:48:18.797