Example extension dialplan configuration sections in extensions.conf. Phone features such as call-forwarding, pickup and parking require x-cisco-serviceuri extensions to be configured.
Context to call a SIP phone extension. Call-forwarding and Alert-Info as well as an optional voice mailbox is supported.
[call-extension]
exten => _X.,1,Set(PEERNAME=${EXTEN})
; By manually checking for call-forwarding, the call can be forwarded even if the phone is unregistered
same => next,Set(CALLFORWARD=${SIPPEER(${PEERNAME},callforward)})
same => next,GotoIf($[${LEN(${CALLFORWARD})} != 0]?callforward,1)
same => next,Set(MAILBOX=${SIPPEER(${PEERNAME},mailbox)})
; Phones can be made to play a different ring using the Alert-Info header, see Ring Tones for examples
same => next,ExecIf($[${LEN(${ALERT_INFO})} != 0]?SIPAddHeader(Alert-Info: <${ALERT_INFO}>))
same => next,Dial(SIP/${PEERNAME},30)
same => next,Goto(${TOLOWER(${DIALSTATUS})},1)
; Check if forwarded to the phone's voicemail extension
exten => callforward,1,GotoIf($[${CALLFORWARD} = ${SIPPEER(${PEERNAME},vmexten)}]?busy,1)
; Cisco SIP phones support displaying diversion information
same => next,Set(REDIRECTING(from-all,i)="${SIPPEER(${PEERNAME},callerid_name)}" <${SIPPEER(${PEERNAME},callerid_num)}>)
same => next,Set(REDIRECTING(reason,i)=cfu)
same => next,Goto(extensions,${CALLFORWARD},1)
; If ${MAILBOX} is empty send congestion, otherwise go to voicemail extension below
exten => congestion,1,ExecIf($[${LEN(${MAILBOX})} = 0]?Congestion(10))
same => next,Set(GREETING=u)
same => next,Goto(voicemail,1)
; If ${MAILBOX} is empty send busy, otherwise go to voicemail extension below
exten => busy,1,ExecIf($[${LEN(${MAILBOX})} = 0]?Busy(10))
same => next,Set(GREETING=b)
same => next,Goto(voicemail,1)
exten => noanswer,1,Goto(congestion,1)
exten => chanunavail,1,Goto(congestion,1)
exten => voicemail,1,Answer()
same => next,Wait(0.5)
same => next,VoiceMail(${MAILBOX},${GREETING})
same => next,Hangup(normal_clearing)
Incoming context for local phone extensions. Note: when defining a hint the peer name needs to be specified twice as there are two independant states, the device state and the presence state.
[extensions]
exten => 301,1,Goto(call-extension,${EXTEN},1)
; Note the duplication of the hint peername
same => hint,SIP/301,SIP/301
exten => 302,1,Goto(call-extension,${EXTEN},1)
same => hint,SIP/302,SIP/302
exten => 303,1,Goto(call-extension,${EXTEN},1)
same => hint,SIP/303,SIP/303
...
Hunt-group login. Ring only those peers that are logged into the hunt-group.
; Clear dial group first
exten => 370,1,Set(DIALGROUP(huntgroup)=)
same => next,Set(PEERNAMES=301&302&303)
same => next,While($[${LEN(${PEERNAMES})} != 0])
same => next,Set(PEERNAME=${SHIFT(PEERNAMES,&)})
; Check if peer is logged-in to the hunt group and add them to the dial group if they are
same => next,ExecIf($[${SIPPEER(${PEERNAME},huntgroup)} = yes]?Set(DIALGROUP(huntgroup,add)=SIP/${PEERNAME}))
same => next,EndWhile()
; Send congestion if the dial group is empty
same => next,ExecIf($[${LEN(${DIALGROUP(huntgroup)})} = 0]?Congestion(10))
; Phones support 'Answered Elsewhere' so the 'c' flag is included
; Later series need to be logged into the hunt-group and have CISCO_HUNTPILOT set to not record answered calls as missed
same => next,Set(_CISCO_HUNTPILOT="Ring All" <${EXTEN}>)
same => next,Dial(${DIALGROUP(huntgroup)},30,ic)
same => next,Hangup(${HANGUPCAUSE})
; Only allow one page at a time
exten => 380,1,Set(GROUP()=paging)
same => next,ExecIf($[${GROUP_COUNT(paging)} != 1]?Busy(10))
; Multicast audio mode is enabled using the m() option
same => next,SIPCiscoPage(301&302&303,om(224.0.1.1)d(From ${CALLERID(number)}))
same => next,Hangup(normal_clearing)
Call the intercom line on multiple phones. Intercom is specified as a line key. See paging for how to page phones without requiring an intercom line.
; Clear dial group first
exten => 390,1,Set(DIALGROUP(intercom)=)
; The list of SIP peers and their associated intercom line peer. List could be dynamically specified using EVAL() or DB() allowing for multiple intercom groups.
same => next,Set(PEERNAMES=301/391&302/392&303/393)
same => next,While($[${LEN(${PEERNAMES})} != 0])
same => next,Set(PEERNAME=${SHIFT(PEERNAMES,/)})
same => next,Set(INTERCOM_PEERNAME=${SHIFT(PEERNAMES,&)})
same => next,ExecIf($[${DEVICE_STATE(SIP/${PEERNAME})} = NOT_INUSE]?Set(DIALGROUP(intercom,add)=SIP/${INTERCOM_PEERNAME}))
same => next,EndWhile()
same => next,ExecIf($[${LEN(${DIALGROUP(intercom)})} = 0]?Busy(10))
same => next,Page(${DIALGROUP(intercom)},is,3)
same => next,Hangup(normal_clearing)
Extension for the messages (voicemail) button, set by <messagesNumber> as part of the line key definition.
exten => 399,1,Set(CONNECTEDLINE(all)="Voice Mail" <${EXTEN}>)
same => next,Answer()
same => next,Wait(0.5)
same => next,Set(MAILBOX=${SIPPEER(${CHANNEL(peername)},mailbox)})
same => next,VoiceMailMain(${MAILBOX},s)
same => next,Hangup(normal_clearing)
Dialplan features used by the Cisco phones are prefixed with x-cisco-serviceuri-, start by stripping it off. Note: x needs to be surrounded by [] otherwise it will be interpreted as to match any digit. Available feature extensions are listed below.
Busy Lamp Field Directed Call Pickup, ${EXTEN:10} is the number specified as the <speedDialNumber> in a BLF speed-dial line key definition, also needs to have a matching subscribe entry in sip.conf.
exten => _blfpickup-.,1,PickupChan(SIP/${EXTEN:10})
same => next,Hangup(normal_circuit_congestion)
Group Call Pickup, manually sets the pickup extension or group.
; Try pickup on channel first
exten => _gpickup-.,1,PickupChan(SIP/${EXTEN:8})
; Otherwise, treat exten as pickup group
same => next,Set(CHANNEL(pickupgroup)=${EXTEN:8})
same => next,Pickup()
same => next,Hangup(normal_circut_congestion)
Park Call. You can omit the park exten if you have parkexten set to park in res_parking.conf. Note: the extension priority of the Park application must be 1.
; If the parked call isn't retrieved in 60 seconds it will be sent to extension 370
exten => park,1,Park(default,st(60)T(50)c(extensions,370,1))
; Remember to include the parked calls context
include => parked-calls
Directed BLF Call Park, blind-transfers the current call to this extension. ${EXTEN:6} is the number specified as the <speedDialNumber> in a BLF Directed Call Park line key definition, also needs to have a matching subscribe entry in sip.conf. The dpark prefix is only used when that parking extension is not in use, otherwise it uses the optional <retrievalPrefix>.
exten => _dpark-.,1,Set(PARKINGEXTEN=${EXTEN:6})
same => next,Goto(park,1)
Record call, inbound and outbound legs are recorded separately so ConfBridge is used to merge them together.
exten => record,1,Answer()
same => next,Wait(0.5)
same => next,Set(CONFBRIDGE(bridge,record_conference)=yes)
same => next,Set(CONFBRIDGE(bridge,record_file)=${RECORD_PEERNAME})
same => next,Set(CONFBRIDGE(user,quiet)=yes)
; Other channel variables available are ${RECORD_CHANNEL} and ${RECORD_DIRECTION}.
same => next,ConfBridge(${RECORD_UNIQUEID})
same => next,Hangup(normal_clearing)
Abbrievated (or speed) dials, soft key is available from the dial number screen. Example uses ${SPEEDDIAL_XXX} which is set in the phone's sip.conf entry.
exten => _abbrdial-.,1,Set(SPEEDDIAL=${EVAL(SPEEDDIAL_${EXTEN:9})})
same => next,GotoIf($[${LEN(${SPEEDDIAL})} != 0]?extensions,${SPEEDDIAL},1)
same => next,Hangup(unallocated)
Meetme Conferencing, used to detect creation of a conference bridge as opposed to just joining one.
; Only allow creation of conference bridge if no one else has first
exten => _meetme-36X,1,ExecIf($[${CONFBRIDGE_INFO(${EXTEN:7},parties)} != 0]?Hangup(normal_circuit_congestion))
same => next,Set(CONFBRIDGE(bridge,template)=default_bridge)
same => next,Set(CONFBRIDGE(user,template)=default_user)
same => next,Set(CONFBRIDGE(user,admin)=yes)
same => next,ConfBridge(${EXTEN:7})
same => next,Hangup(normal_clearing)
; Reject calls to conference bridges that haven't been created
exten => _36X,1,ExecIf($[${CONFBRIDGE_INFO(${EXTEN},parties)} = 0]?Hangup(unallocated))
same => next,Set(CONFBRIDGE(bridge,template)=default_bridge)
same => next,Set(CONFBRIDGE(user,template)=default_user)
same => next,Set(CONFBRIDGE(user,admin)=no)
same => next,ConfBridge(${EXTEN})
same => next,Hangup(normal_clearing)
Divert (Connected), allow call to be diverted to voicemail after being answered.
exten => idivert,1,Answer()
same => next,Wait(0.5)
same => next,Set(MAILBOX=${SIPPEER(${IDIVERT_PEERNAME},mailbox)})
same => next,VoiceMail(${MAILBOX},b)
same => next,Hangup(normal_clearing)
Specifies the number the phone stores in the call history without modifying the caller-ID number. Example use is to include a prefix required for an outside line so it can be dialed unedited from the call history entry.
; If dialing outside numbers requires that they be prefixed with a '1'
exten => _X.,1,Set(_CISCO_CALLBACK_NUMBER=1${CALLERID(number)})
same => next,Dial(SIP/${EXTEN},,30)
...
Specifies the caller-ID for the hunt-group which will be shown on the phone and stored in the call history. For later models this needs to be set to avoid logging calls answered on other phones as missed calls. Note: The phone must be logged-in to the hunt-group for the information to be shown.
; Specify a name and number for the hunt-group.
exten => _X.,1,Set(_CISCO_HUNTGROUP="Ring All" <${EXTEN}>))
same => next,Dial(SIP/301&SIP/302&SIP/303,,30)
...