Asterisk call forwarding

Asterisk call forwarding

If you use this setup a phone can dial *21*<number> for immediate redirect or
*61*<number> for delayed redirect, and #21# or #61# to cancel the setting.

If you need help understanding how the variables used in these examples work, have a look at Asterisk variables. (Macro arguments can be referenced along with an offset, like so: exten => s,1,Set(CFIM=${DB(CFIM/${ARG1:-4})})).

Abbreviations used

Example 1

  ; Standard extension macro (with call forwarding):
  ; ${ARG1} - Extension(we could have used ${MACRO_EXTEN} here as well
  ; ${ARG2} - Device(s) to ring
  exten => s,1,((Asterisk cmd DBget|DBget))(temp=CFIM/${ARG1}) ; Get CFIM key, if not existing, goto 102
  exten => s,2,((Asterisk cmd Dial|Dial))(Local/${temp}@pbx/n)   ; Unconditional forward
  exten => s,3,Dial(${ARG2},20) ; 20sec timeout
  exten => s,4,DBget(temp=CFBS/${ARG1})  ; Get CFBS key, if not existing, goto 105
  exten => s,5,Dial(Local/${temp}@pbx/n) ; Forward on busy or unavailable

  ; No CFIM key
  exten => s,102,Goto(s,3)

  ; No CFBS key - voicemail ?
  exten => s,105,Busy

Asterisk 1.2

  ; Standard extension macro (with call forwarding): 
  ; ${ARG1} - Extension(we could have used ${MACRO_EXTEN} here as well 
  ; ${ARG2} - Device(s) to ring 

  exten => s,1,Set(temp=${DB(CFIM/${ARG1})})
  exten => s,n,GotoIf(${temp}?cfim:nocfim)
  exten => s,n(cfim),Dial(Local/${temp}@default/n)   ; Unconditional forward 
  exten => s,n(nocfim),NoOp

  exten => s,n,Dial(${ARG2},15) ; 15sec timeout 

  exten => s,n,Set(temp=${DB(CFBS/${ARG1})})
  exten => s,n,GotoIf(${temp}?cfbs:nocfbs)
  exten => s,n(cfbs),Dial(Local/${temp}@default/n) ; Forward on busy or unavailable 
  exten => s,n(nocfbs),Busy

  • This macro reads variables stored in the Asterisk database
  • The macro executes 'Dial(Local/<number>@pbx)' if a redirection number is found. This implies the number that was selected is dialable from the [pbx] context. You should probably modify this. (If you only want outbound redirect this could be Dial(Zap/1/<number>) for instance)
  • If the DBget does not find a key, it exits with the result code 101, making the next step in the dial plan the current priority+101

Example 2

  ; Unconditional Call Forward
  exten => _*21*X.,1,DBput(CFIM/${CALLERIDNUM}=${EXTEN:4})
  exten => _*21*X.,2,Hangup
  exten => #21#,1,DBdel(CFIM/${CALLERIDNUM})
  exten => #21#,2,Hangup

  ; Call Forward on Busy or Unavailable
  exten => _*61*X.,1,DBput(CFBS/${CALLERIDNUM}=${EXTEN:4})
  exten => _*61*X.,2,Hangup
  exten => #61#,1,DBdel(CFBS/${CALLERIDNUM})
  exten => #61#,2,Hangup

  • You can't use use "#" for SIP adapters like Grandstream Handytone, because they will not be send. These phones and adaptors use # as the character to end the phoneno., so that you don't have to wait for the timeout. Use something like this for call forward instead:

Example 3

  ; Unconditional Call Forward
  ; create call forward
  exten => _*21*X.,1,GotoIf($[${EXTEN:-1} = #]?2:3)
  exten => _*21*X.,2,StripLSD(1)
  exten => _*21*X.,3,DBput(CFIM/${CALLERIDNUM}=${EXTEN:4})
  exten => _*21*X.,4,Hangup
  ; delete call forward
  exten => **21,1,DBdel(CFIM/${CALLERIDNUM})
  exten => **21,2,Hangup
  ; delete call forward (with #)
  exten => **21#,1,Goto(**21,1)

If you do it this way, both regular phones and SIP adaptors without dialplan will work the same way (ending the string with #)

  • This context implements the functionality to set or cancel call forwarding. It needs to be included in the context used for outbound calls
  • The ${EXTEN:4} variable construct takes the current extension and strips the first four characters.
  • This programming does not confirm the setting with an audio prompt. Add this if you want the user to get a confirmation of the new status.

Example 4

  exten => 7000,1,Macro(stdexten,7000,MGCP/aaln/1@<myphone>)   ; IP10S
  exten => 7001,1,Macro(stdexten,7001,SIP/oej)   ; SIP connection

Please note
Don't forget to include the apps extension in your context.

Example 5

This is for V1.2.x and handles the forwarded call in the expected manner. IE the caller is dropped into the called mailbox rather than the extension that the called exten was forwarded to. IE 20 calls 21 which is forwaded to 22 but 22 doesnt answer then the mailbox it drops into is 21 not as many examples 22.

The CFIM database entry is set as in the above examples.

== extensions.conf ==

 ; Standard extension macro:
 ;   ${ARG1} - Extension  (we could have used ${MACRO_EXTEN} here as well
 ;   ${ARG2} - Device(s) to ring
 ; Retrieve the Call Forward number if available.
 exten => s,1,Set(CFIM=${DB(CFIM/${ARG1:-4})})
 ; Dial the appropriate number depending on whether the Call Forward
 exten => s,n,GotoIf($["${vmbox}"!=""]?s-NoCFIM,1)
 exten => s,n,Set(_vmbox=${MACRO_EXTEN:-4})
 exten => s,n,GotoIf($["${CFIM}"!=""]?s-CFIM,1:s-NoCFIM,1)
 ; Pass call to Voicemail with the appropriate greeting.
 ;exten => s,n,GosubIf($[${DIALSTATUS}=NOANSWER]?s-NOANSWER,1:s-BUSY,1)
 ; Hangup.
 exten => s,n,Hangup
 ; Dial Call Forward number & return.
 exten => s-CFIM,1,Dial(Local/${CFIM},30,Ttr)
 exten => s-CFIM,n,GosubIf($[${DIALSTATUS}=NOANSWER]?s-NOANSWER,1:s-BUSY,1)
 exten => s-CFIM,n,Hangup
 ; Dial actual extension & return.
 exten => s-NoCFIM,1,Dial(${ARG1},30,Ttr)
 exten =>  s-NoCFIM,n,GosubIf($[${DIALSTATUS}=NOANSWER]?s-NOANSWER,1:s-BUSY,1)
 exten => s-NoCFIM,n,Hangup
 ; Unavailable voicemail message if there is no answer.
 exten => s-NOANSWER,1,Voicemail(u${vmbox})
 exten => s-NOANSWER,n,Return
 ; Busy voicemail message for any DIALSTATUS other than NOANSWER (or ANSWER).
 exten => s-BUSY,1,Voicemail(b${vmbox})
 exten => s-BUSY,n,Return

Example 6

For version 1.8

exten = _ZX,1,GotoIf(${DB_EXISTS(CFIM/${EXTEN})}?cfim)
exten = _ZX,n,GotoIf(${DB_EXISTS(CFBS/${EXTEN})}?cfbs)
exten = _ZX,n,Dial(SIP/${EXTEN},,${DIALOPTIONS})
exten = _ZX,n,Hangup

exten = _ZX,n(cfbs),Set(temp=${DB(CFBS/${EXTEN})}) ; Get CFBS key
exten = _ZX,n,Dial(SIP/${EXTEN},20,${DIALOPTIONS}) ; 20sec timeout
exten = _ZX,n,Dial(SIP/operator/${temp},,${DIALOPTIONS}) ; Forward on busy or unavailable
exten = _ZX,n,Hangup

exten = _ZX,n(cfim),Set(temp=${DB(CFIM/${EXTEN})}) ; Get CFIM key
exten = _ZX,n,Dial(SIP/operator/${temp},,${DIALOPTIONS}) ; Unconditional forward
exten = _ZX,n,Hangup

exten = _*21*X.,1,Set(DB(CFIM/${CALLERID(num)})=${REPLACE(EXTEN:4,*#-)})
exten = _*21*X.,n,Hangup
exten = **21,1,DBdel(CFIM/${CALLERID(num)})
exten = **21,n,Hangup

exten = _*61*X.,1,Set(DB(CFBS/${CALLERID(num)})=${REPLACE(EXTEN:4,*#-)})
exten = _*61*X.,n,Hangup
exten = **61,1,DBdel(CFBS/${CALLERID(num)})
exten = **61,n,Hangup

Any problems email me.
I also have a web gui for setting the callfwd as well as from the set. This allows the attendant to cancel or set forwards.

  • Because of limitations of this wiki, the above script is not displayed correct, plz go to the homepage above, for copy and paste

Created by: oej, Last modification: Tue 12 of Jun, 2012 (02:46 UTC) by admin
Please update this page with new information, just login and click on the "Edit" or "Discussion" tab. Get a free login here: Register Thanks! - Find us on Google+