Using Variables in Asterisk Dialplans
Asterisk 에서 Dialplan 작성시, 내부 변수를 목적에 따라 Global, Shared, Chanel-specific 변수로 구분해서 사용할 수 있다.
공통적으로 변수를 사용할 때 다음과 같은 방식으로 사용할 수 있다.
${foo:offset:length}
foo 는 변수의 이름이고, offset 은 변수의 내용 중 참조하고자 하는 시작 위치, length 는 offset 으로부터 참조하고자 하는 변수 내용의 길이이다.
변수 이름 작성시, 사용자 지정 변수(User-defined value)는 대/소문자 상관 없이 참조가 가능하나, Asterisk 에서 지정하여 사용하는 변수(ex. ${EXTEN}) 같은 경우는 대/소문자를 구분한다.
크게 4가지 타입의 변수(Global, Shared, Channel, Environment)가 있는데, 각각의 의미는 다음과 같다.
Global : [globals] 섹션에서 설정하거나 SetGlobalVal 명령으로 설정된 변수. 한번 설정하면 언제/어디서 든지 호출하여 참조가 가능하다.
Shared : Variables are new in Asterisk 1.6(however a backport is available for 1.4). Two (or more?) channels can gain full access with the help of Asterisk func SHARED to what otherwise would be a channel variable.
Channel : 특정 Call 에 연동되어 사용가능한 변수. Global 타입과는 달리 Call(Channel)에서만 사용 가능하다. 즉, Call(Channel) 종료시, 해당 변수는 모두 삭제된다.
Environment : Unix 환경 변수. Dialplan 내에서 ENV() 함수로 사용가능하다. ${ENV(var)} var 에는 참조하고자하는 Unix 환경변수 이름을 입력하면 된다.
만약, Channel 변수를 설정할 때, Global 변수에 설정되어 있는 변수와 똑같은 이름으로 설정하게 된다면 Channel 변수를 참조하게 된다.
[FooTest] exten => 100,1,SetGlobalVar(FOO=5) exten => 100,2,NoOp(${FOO}) exten => 100,3,NoOp(${foo}) exten => 100,4,Set(foo=8) exten => 100,5,NoOp(${FOO}) exten => 100,6,NoOp(${foo}) — Executing SetGlobalVar("Zap/1-1", "FOO=5") in new stack — Setting global variable 'FOO' to '5' — Executing NoOp("Zap/1-1", "5") in new stack — Executing NoOp("Zap/1-1", "5") in new stack — Executing Set("Zap/1-1", "foo=8") in new stack — Executing NoOp("Zap/1-1", "8") in new stack — Executing NoOp("Zap/1-1", "8") in new stack
Global 변수 설정 직후 ${FOO} 의 값을 확인해보면 “5” 로 나오는 것을 확인할 수 있다. 하지만 Channel 변수로 설정 후, ${FOO} 값을 확인해보면 모두 “8”로 표시되는 것을 알 수 있다.
Inheritance of Channel Variables
변수 선언시, _(underscore)를 붙이게 되면 이는 Inheritance of Channel Variable 임을 선언하는 것이다. 그런데 이 ‘_'(underscore) 를 하나를 붙이느냐, 두개를 붙이느냐에 따라 변수가 상속되는 범위가 달라진다.
하나를 붙이면 한번만 상속되고, 두개를 붙이게 되면 계속해서 상속된다.
exten => 104,1,Set(FEE=fee) exten => 104,2,Set(_FIE=fie) exten => 104,3,Set(__FUM=fum) exten => 104,4,Dial(Local/105) exten => 105,1,NoOp(${FEE}) exten => 105,2,NoOp(${FIE}) exten => 105,3,NoOp(${FUM}) exten => 105,4,Dial(Local/106) exten => 106,1,NoOp(${FEE}) exten => 106,2,NoOp(${FIE}) exten => 106,2,NoOp(${FUM}) results in — Executing Set("SIP/oberon-365e", "FEE=fee") in new stack — Executing Set("SIP/oberon-365e", "_FIE=fie") in new stack — Executing Set("SIP/oberon-365e", "__FUM=fum") in new stack — Executing Dial("SIP/oberon-365e", "Local/105") in new stack — Called 105 — Executing NoOp("Local/105@default-7263,2", "") in new stack — Executing NoOp("Local/105@default-7263,2", "fie") in new stack — Executing NoOp("Local/105@default-7263,2", "fum") in new stack — Executing Dial("Local/105@default-7263,2", "Local/106") in new stack — Called 106 — Executing NoOp("Local/106@default-49be,2", "") in new stack — Executing NoOp("Local/106@default-49be,2", "") in new stack — Executing NoOp("Local/106@default-49be,2", "fum") in new stack
Using $
If you want to set a global variable containing the another variable name in the [globals] category of extensions.conf you have to do something like this:
[globals] SS=$ MY_VAR=${SS}{EPOCH}-${SS}{EXTEN}.gsm
This way the MY_VAR value is ${EPOCH}-${EXTEN}.gsmUsing it with the EVAL() function is very useful. I.e. If you want to record you can do this:
exten => 104,1,Set(filename=${EVAL(${MYVAR}){) exten => 104,2,MixMonitor(${filename})
Predefined Channel Variables
- ${ACCOUNTCODE}: Account code, if specified – see Asterisk billing (DEPRECATED in 1.2.0 and removed in 1.4. Use ${CDR(accountcode)}
- ${ANSWEREDTIME}: This is the amount of time(in seconds) for actual call.
- ${BLINDTRANSFER}: The active SIP channel that dialed the number. This will return the SIP Channel that dialed the number when doing blind transfers – see BLINDTRANSFER
- ${CALLERID(all)}: The current Caller ID name and number – See Setting Callerid for usage in Asterisk 1.4
- ${CALLERID(name)}: The current Caller ID name – ${CALLERIDNAME} was used in versions of Asterisk prior to 1.2.0, it was DEPRECATED in 1.2.0 and removed in 1.4.
- ${CALLERID(num)}: The current Caller ID number – ${CALLERIDNUM} was used in versions of Asterisk prior to 1.2.0, it was DEPRECATED in 1.2.0 and removed in 1.4.
(Note: this is not necessarily numeric as the name would indicate and can legitimately contain the space character. Commands acting on this variable (such as ‘GotoIf’, for example) should be aware of this).
- ${CALLINGPRES}: PRI Call ID Presentation variable for incoming calls (See callingpres )
- ${CHANNEL}: Current channel name
- ${CONTEXT}: The name of the current context
- ${DATETIME}: Current date time in the format: DDMMYYYY-HH:MM:SS This is deprecated in Asterisk 1.2, instead use :${STRFTIME(${EPOCH},,%d%m%Y-%H:%M:%S)})
- ${DIALEDPEERNAME}: Name of the called party. Broken for now, see DIALEDPEERNAME
- ${DIALEDPEERNUMBER}: Number of the called party. Broken for now, see DIALEDPEERNUMBER
- ${DIALEDTIME}: Time since the number was dialed (only works when dialed party answers the line?!)
- ${DIALSTATUS}: Status of the call. See DIALSTATUS (note: In the current SVN release, DIALSTATUS seems to have been removed. Now you should use the DEVSTATE function. Try in astersisk console “core show function DEVSTATE” for more informations)
- ${DNID}: Dialed Number Identifier. Limitations apply, see DNID
- ${EPOCH}: The current UNIX-style epoch (number of seconds since 1 Jan 1970)
- ${EXTEN}: The current extension – cannot be modified with the set command- just use the GoTo to change the EXTEN variable!
- ${HANGUPCAUSE}: The last hangup return code on a Zap channel connected to a PRI interface
- ${INVALID_EXTEN}: The extension asked for when redirected to the i (invalid) extension
- ${LANGUAGE}: The current language setting. See Asterisk multi-language
- ${MEETMESECS}: Number of seconds a user participated in a MeetMe conference
- ${PRIORITY}: The current priority
- ${RDNIS}: The current redirecting DNIS, Caller ID that redirected the call. Limitations apply, see RDNIS
- ${SIPDOMAIN}: SIP destination domain of an inbound call (if appropriate)
- ${SIP_CODEC}: Set the SIP codec for the inbound (=first) call leg (see channelvariables.txt or README.variables in 1.2); Asterisk 1.6.2 also comes with SIP_CODEC_OUTBOUND for the remote (=second) call leg.
- ${SIPCALLID}: The SIP dialog Call-ID: header
- ${SIPUSERAGENT}: The SIP user agent header
- ${TIMESTAMP}: Current date time in the format: YYYYMMDD-HHMMSS This is deprecated as of Asterisk 1.4, instead use :${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)})
- ${TRANSFERCAPABILITY}: Type of Channel
- ${TXTCIDNAME}: Result of application TXTCIDName (see below)
- ${UNIQUEID}: Current call unique identifier
- ${TOUCH_MONITOR}: used for “one touch record” (see features.conf, and wW dial flags). If is set on either side of the call then that var contains the app_args for app_monitor otherwise the default of WAV||m is used
- ${TOUCH_MONITOR_PREFIX}: used for “one touch record” (see features.conf, and wW dial flags). This set Prefix to ${TOUCH_MONITOR} default: auto “New in 1.8”
Application-specific variables
특정 Function/Application 들은 Input/Output 으로 Channel 변수들을 이용한 결과값들을 제공한다.
- AgentCallbackLogin returns ${AGENTBYCALLERID_${CALLERID}}: The ID of the agent successfully logged on.
- ChanIsAvail returns ${AVAILCHAN}: The first available channel
- Dial takes input from ${VXML_URL}: Send XML Url to Cisco 7960 or to i6net VoiceXML browser
- Dial takes input from ${ALERT_INFO}: Set ring cadence or allow intercom on for various SIP phones
- Dial returns ${CAUSECODE}: If the dial failed, this is the errormessage
- Dial returns ${DIALSTATUS}: Text code returning status of last dial attempt.
- Dial takes input from ${TRANSFER_CONTEXT}: If this variable exists, when a #transfer is executed it goes to the selected extension on this context.
- EnumLookup returns ${ENUM}: The result of the lookup
- Hangup reads the ${PRI_CAUSE} variable for setting PRI return codes
- MeetMe takes input from {MEETME_AGI_BACKGROUND}: An AGI script to run
- MeetMe returns ${MEETMESECS}: The number of seconds the user was in a conference
- Playback returns ${PLAYBACKSTATUS}: The status of the command (FAILED|SUCCESS)
- Queue returns ${QUEUESTATUS}: The reason for popping the call out of the queue
- TXTCIDName returns ${TXTCIDNAME}: The result of the DNS lookup
- VoiceMail returns ${VMSTATUS}: indicates the status of the execution of the VoiceMail application. Possible values are: SUCCESS | USEREXIT | FAILED .
Macro-specific variables
Macro context 에서는 추가적인 Channel 변수들이 사용가능하다.
- ${ARG1}: The first argument passed to the macro
- ${ARG2}: The second argument passed to the macro (and so on)
- ${MACRO_CONTEXT}: The context of the extension that triggered this macro
- ${MACRO_EXTEN}: The extension that triggered this macro
- ${MACRO_OFFSET}: Set by a macro to influence the priority where execution will continue after exiting the macro
- ${MACRO_PRIORITY}: The priority in the extension where this macro was triggered
Call files extension specific variables
- ${REASON}: A number that represents the reason why an outgoing call failed. See Asterisk Reason variable.
Environment Variables
Unix 환경 변수들도 참조가 가능하다.
${ENV(foo)}
- ${ENV(ASTERISK_PROMPT)}: the current Asterisk CLI prompt.
- ${ENV(RECORDED_FILE)}: the filename of the last file saved by the Record command (available in CVS > 2004-03-21)
String Handling Functions
String Length
${LEN(foo)}
foo 변수의 길이를 리턴한다. 해당 변수가 NULL 인지 빈 문자열인지 확인하는데 효과적인 방법이다.
exten => 100,1,Set(Fruit=pear) exten => 100,2,NoOp(${LEN(Fruit)}) exten => 100,3,NoOp(${LEN(${Fruit})})
첫번째 NoOp() 결과는 “5”를 리턴한다(Fruit). 두번째 NoOp() 결과는 “4”를 리턴한다(${Fruit} == pear)
Substrings
${foo:offset:length}
returns a substring of the string foo, beginning at offset offset and returning the next length characters. The first character is at offset 0.
- If offset is negative, it is taken leftwards from the right hand end of the string.
- If length is omitted or is negative, then all the rest of the string beginning at offset is returned.
${123456789:1} - returns the string 23456789 ${123456789:-4} - returns the string 6789 ${123456789:0:3} - returns the string 123 ${123456789:2:3} - returns the string 345 ${123456789:-4:3} - returns the string 678 exten => _NXX.,1,Set(areacode=${EXTEN:0:3}) - get the first 3 digits of ${EXTEN} exten => _516XXXXXXX,1,Dial(${EXTEN:3}) - get all but the first 3 digits of ${EXTEN} exten => 100,1,Set(whichVowel=4) exten => 100,2,Set(foo=AEIOU:${whichVowel}:1) - sets ${foo} to the single letter 'U'
String Concatenation
두 개이상의 문자열들을 합친다면 다음과 같이 하면 된다.
${foo}${bar} 555${theNumber} ${longDistancePrefix}555${theNumber}
Variable math
변수들을 이용하여 더하기, 곱하기, 증가하기들을 하고싶다면..
exten => s,1,Set(SOMEVAR=$[${SOMEVAR} + 1]) ; increment exten => s,2,Set(SOMEVAR=$[2 * ${SOMEVAR}]) ; multiplication etc... In times past, a single space was required between items in the $[...] expressions. This is no longer the case! In late model Asterisks (1.2?), the MATH function is also available... exten => s,1,Set(SOMEVAR=${MATH(${SOMEVAR}+1,i)}) ; increment, get result as integer exten => s,2,Set(SOMEVAR=${MATH(2*${SOMEVAR})}) ; multiplication etc...