[FreeBSD] Network configure

시스템 부팅시 자동으로 NIC 에 IP 를 할당하고 싶다면 /etc/rc.conf 파일을 이용한다.

rc.conf 설정 예제.

root@FBSD10:/etc # vi rc.conf 

hostname="FBSD10"
#ifconfig_em0="DHCP"
ifconfig_em0="10.0.2.16/24"
ifconfig_em0_ipv6="inet6 accept_rtadv"
sshd_enable="YES"
ntpd_enable="YES"
# Set dumpdev to "AUTO" to enable crash dumps, "NO" to disable
dumpdev="AUTO"

# Set for em1
ifconfig_em1="192.168.200.12/24"

# Set for em2
ifconfig_em2="192.168.201.12/24"

# Default route gateway
defaultrouter="10.0.2.2"

 

rc.conf 파일은 NIC 설정외에도 다양한 기능들을 지원한다. 리눅스의 /etc/rc.local 파일을 생각하면 되겠다.
이보다 더 자세한 옵션들을 보고 싶다면..

$ man rc.conf

 

/etc/rc.conf 파일 설정 이후, 재부팅없이 네트워크를 Up/Down/Restart 를 해야 한다면 다음을 활용하자.

Netowrk Restart

$ /etc/rc.d/netif restart

Network Down

$ /etc/rc.d/netif stop

Network Up

$ /etc/rc.d/netif start

 

Routing Table 도 마찬가지로 조작이 가능하다.

Network routing table Restart

$ /etc/rc.d/routing restart

 

출처 : http://www.cyberciti.biz/tips/freebsd-how-to-start-restart-stop-network-service.html

[Freeswitch] modules.conf.xml

Freeswitch 에서 사용하는 Module On/Off 를 설정하는 파일.

fs_cli 로 접속하여 load 명령어로도 On/Off 가 가능하지만, Freeswitch 재 시작 후, 매번 load 명령어를 날려줘야만 하는 불편함이 있다.

이럴 경우, modules.conf.xml 파일에 Freeswitch 시작시 자동 load module을 설정해 놓으면 편리하다.

pchero@MyDebian:/usr/local/freeswitch/conf/autoload_configs$ cat modules.conf.xml 
<configuration name="modules.conf" description="Modules">
  <modules>
    
    <!-- Loggers (I'd load these first) -->
    <load module="mod_console"/>
    <load module="mod_logfile"/>
    <!-- <load module="mod_syslog"/> -->

    <!--<load module="mod_yaml"/>-->

    <!-- Multi-Faceted -->
    <!-- mod_enum is a dialplan interface, an application interface and an api command interface -->
    <load module="mod_enum"/>

    <!-- XML Interfaces -->
    <!-- <load module="mod_xml_rpc"/> -->
    <!-- <load module="mod_xml_curl"/> -->
    <!-- <load module="mod_xml_cdr"/> -->
    <!-- <load module="mod_xml_scgi"/> -->

    <!-- Event Handlers -->
    <load module="mod_cdr_csv"/>
    <!-- <load module="mod_cdr_sqlite"/> -->
    <!-- <load module="mod_event_multicast"/> -->
    <load module="mod_event_socket"/>
    <!-- <load module="mod_event_zmq"/> -->
    <!-- <load module="mod_zeroconf"/> -->
    <!-- <load module="mod_erlang_event"/> -->
    <!-- <load module="mod_snmp"/> -->

    <!-- Directory Interfaces -->
    <!-- <load module="mod_ldap"/> -->

    <!-- Endpoints -->
    <!-- <load module="mod_dingaling"/> -->
    <!-- <load module="mod_portaudio"/> -->
    <!-- <load module="mod_alsa"/> -->
    <load module="mod_sofia"/>
    <load module="mod_loopback"/>
    <!-- <load module="mod_woomera"/> -->
    <!-- <load module="mod_freetdm"/> -->
    <!-- <load module="mod_openzap"/> -->
    <!-- <load module="mod_unicall"/> -->
    <!-- <load module="mod_skinny"/> -->
    <!-- <load module="mod_khomp"/>   -->
    <!-- <load module="mod_rtmp"/>   -->

    <!-- Applications -->
    <load module="mod_commands"/>
    <load module="mod_conference"/>
    <!-- <load module="mod_curl"/> -->
    <load module="mod_db"/>
    <load module="mod_dptools"/>
    <load module="mod_expr"/>
    <load module="mod_fifo"/>
    <load module="mod_hash"/>
    <load module="mod_voicemail"/>
    <!--<load module="mod_directory"/>-->
    <!--<load module="mod_distributor"/>-->
    <!--<load module="mod_lcr"/>-->
    <load module="mod_esf"/>
    <load module="mod_fsv"/>
    <load module="mod_cluechoo"/>
    <load module="mod_valet_parking"/>
    <!--<load module="mod_fsk"/>-->
    <!--<load module="mod_spy"/>-->
    <!--<load module="mod_random"/>-->
    <load module="mod_httapi"/>
    <!--<load module="mod_translate"/>-->

    <!-- SNOM Module -->
    <!--<load module="mod_snom"/>-->

    <!-- This one only works on Linux for now -->
    <!--<load module="mod_ladspa"/>-->

    <!-- Dialplan Interfaces -->
    <!-- <load module="mod_dialplan_directory"/> -->
    <load module="mod_dialplan_xml"/>
    <load module="mod_dialplan_asterisk"/>

    <!-- Codec Interfaces -->
    <load module="mod_spandsp"/>
    <load module="mod_g723_1"/>
    <load module="mod_g729"/>
    <load module="mod_amr"/>
    <!--<load module="mod_ilbc"/>-->
    <load module="mod_h26x"/>
    <load module="mod_vp8"/>
    <load module="mod_b64"/>
    <!--<load module="mod_siren"/>-->
    <!--<load module="mod_isac"/>-->
    <!--<load module="mod_celt"/>-->
    <!--<load module="mod_opus"/>-->

    <!-- File Format Interfaces -->
    <load module="mod_sndfile"/>
    <load module="mod_native_file"/>
    <!-- <load module="mod_shell_stream"/> -->
    <!--For icecast/mp3 streams/files-->
    <!--<load module="mod_shout"/>-->
    <!--For local streams (play all the files in a directory)-->
    <load module="mod_local_stream"/>
    <load module="mod_tone_stream"/>

    <!-- Timers -->
    <!-- <load module="mod_timerfd"/> -->
    <!-- <load module="mod_posix_timer"/> -->

    <!-- Languages -->
    <!-- <load module="mod_spidermonkey"/> -->
    <load module="mod_v8"/>
    <!-- <load module="mod_perl"/> -->
    <load module="mod_python"/>
    <!-- <load module="mod_java"/> -->
    <load module="mod_lua"/>

    <!-- ASR /TTS -->
    <!-- <load module="mod_flite"/> -->
    <!-- <load module="mod_pocketsphinx"/> -->
    <!-- <load module="mod_cepstral"/> -->
    <!-- <load module="mod_tts_commandline"/> -->
    <!-- <load module="mod_rss"/> -->
    
    <!-- Say -->
    <load module="mod_say_en"/>
    <!-- <load module="mod_say_ru"/> -->
    <!-- <load module="mod_say_zh"/> -->
    <!-- <load module="mod_say_sv"/> -->

    <!-- Third party modules -->
    <!--<load module="mod_nibblebill"/>-->
    <!--<load module="mod_callcenter"/>-->

  </modules>
</configuration>

 

[Freeswitch] fs_cli/event_socket.conf.xml

Freeswitch에서 asterisk -r 과 같은 Command line interpreter 역할을 하는 것이 fs_cli  이다.

기본적으로 Freeswitch 를 설치하게 되면 fs_cli 도 같이 사용할 수 있도록 설정되어 있다. 그러나, 보안상의 이유로 이 기능을 On/Off 해야 하는 경우가 생긴다.

이 경우, Freeswitch Server 에서 fs_cli 지원 모듈을 On/Off 해주면 된다.

modules.conf.xml 파일에서 mod_event_socket 모듈을 load/unload 하게 되면 fs_cli 기능을 On/Off 할 수 있다.

<configuration name="modules.conf" description="Modules">
  <modules>

    <!-- Loggers (I'd load these first) -->
    <load module="mod_console"/>
    <load module="mod_logfile"/>
    <!-- <load module="mod_syslog"/> -->

    <!--<load module="mod_yaml"/>-->

    <!-- Multi-Faceted -->
    <!-- mod_enum is a dialplan interface, an application interface and an api command interface -->
    <load module="mod_enum"/>

    <!-- XML Interfaces -->
    <!-- <load module="mod_xml_rpc"/> -->
    <!-- <load module="mod_xml_curl"/> -->
    <!-- <load module="mod_xml_cdr"/> -->
    <!-- <load module="mod_xml_scgi"/> -->

    <!-- Event Handlers -->
    <load module="mod_cdr_csv"/>
    <!-- <load module="mod_cdr_sqlite"/> -->
    <!-- <load module="mod_event_multicast"/> -->
    <load module="mod_event_socket"/>
    <!-- <load module="mod_event_zmq"/> -->

기본적으로 Freeswitch 를 설치하게 되면 fs_cli 도 같이 사용할 수 있도록 설정되어 있다. 그러나, 보안상의 이유로 이 기능을 On/Off 해야 하는 경우가 생긴다.
이 경우, Freeswitch Server 에서 fs_cli 지원 모듈을 On/Off 해주면 된다.

그리고, fs_cli 의 접속 권한과 같은 부분들을 관리 하고자 한다면 event_socket.conf.xml 파일을 수정하면 된다.

pchero@MyDebian:/usr/local/freeswitch/conf/autoload_configs$ cat event_socket.conf.xml

<configuration name="event_socket.conf" description="Socket Client">
  <settings>
    <param name="nat-map" value="false"/>
    <!--<param name="listen-ip" value="127.0.0.1"/>-->
    <param name="listen-ip" value="0.0.0.0"/>
    <param name="listen-port" value="8021"/>
    <param name="password" value="ClueCon"/>
    <param name="apply-inbound-acl" value="local_net"/>
    <!--<param name="apply-inbound-acl" value="lan"/>-->
    <!--<param name="stop-on-bind-error" value="true"/>-->
  </settings>
</configuration>

[Asterisk] Checking available SIP port.

Asterisk Test Server 를 구축해 놓고, 정상적으로 포트가 열렸는지(방화벽..)를 확인하는 작업을 진행하고 있었다.

이상하게.. 어디에 문제가 있는 정확히는 알 수는 없었지만 정상적인 작동이 되지 않았다.

방화벽 문제로 판단을 하고 하나씩 하나씩 iptables 옵션을 확인해가며 방화벽들을 내리고 있었다.

 

하나씩 방화벽을 내릴 때마다 정상적으로 작동이 되는지(즉, 해당 포트로 Ping 이 나가는지)를 확인하기 위해 한번씩 telnet 을 이용하여 해당 포트(5060-sip)로 접속을 시도하였다.

 

한참을 그렇게 작업을 진행하던 중, 방화벽을 잠시 전부 꺼두었다는 이야기가 들려와 다시한번 telnet 으로 해당포트에 접속을 시도하였다.

결과는 실패였다.

 

아직 방화벽이 안내려간거 같다고 하니, 다른쪽에서는 Test Server가 정상적으로 작동을 한다고 한다.

헛?? 설마??

 

동작 테스트를 해보니 정상적으로 작동을 한다..

무슨 일일까?

 

문제는 내 Test 방법에 있었다.

나는 줄곧 telnet 으로 해당 포트를 두드렸던것..

 

하지만 Telnet 은 기본적으로 TCP 를 이용하여 접속을 시도한다…..

UDP 로 확인해야 하는데.. 계속해서 TCP 로 확인을 시도했던것…

 

기억하자. Asterisk 에서 SIP 통신 연결을 확인하기 위해서는 Telnet 으로는 불가능하다는 것을..

MyDebian*CLI> sip show peers
Name/username             Host                                    Dyn Forcerport Comedia    ACL Port     Status      Description                      
test01/test01             192.168.200.1                            D  Yes        Yes            5060     OK (32 ms)                                   
test02/test02             192.168.200.1                            D  Yes        Yes            5060     OK (31 ms)                                   
test03/test03             192.168.200.1                            D  Yes        Yes            5060     OK (32 ms)                                   
voicemail_trunk-01        192.168.200.10                              Auto (No)  No          A  5080     OK (1 ms)                                    
4 sip peers [Monitored: 4 online, 0 offline Unmonitored: 0 online, 0 offline]

 

 

 

[Asterisk] Variables in Asterisk

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...

출처 : http://www.voip-info.org/wiki/view/Asterisk+variables