Konfigurace Asterisku (8) - Proměnné dialplanu

Proměnné dialplanu jsou důležitým nástrojem, bez kterého se prakticky žádná konfigurace Asterisku neobejde. I v našem seriálu jsme se už s proměnnými setkali. Proměnné jsou základ pro použití funkcí. Díky nim se z Asterisku stává velmi silný nástroj.

Druhy proměnných

V Asterisku verze 1.4.x, o kterém je tento seriál, se můžete setkat se třemi druhy proměnných:

proměnné kanálu (channel variables)
Proměnné kanálu jsou platné jen pro zpracování jednoho hovoru. Asterisk při zpracování dialplanu udržuje seznam proměnných kanálu pro každý hovor zvlášť. Proměnné zanikají při skončení hovoru. Tyto proměnné se využívají nejčastěji. Není-li zdůrazněno, o jaký druh proměnné jde, myslí se obvykle proměnná kanálu.
globální proměnné (global variables)
Tyto proměnné jsou společné pro všechny hovory. Jejich živostnost není omezena a zanikají teprve při ukončení běhu Asterisku a někdy také při reloadu dialplanu. Příkladem může být proměnná s počtem přijatých hovorů, která se zvýší o 1 při každém novém hovoru.
proměnné prostředí (environment variables)
Proměnné prostředí, které má k dispozici každý proces, například $PATH, nebo $HOME.

Asterisk nerozlišuje typy. Všechny proměnné jsou typu řetězec.

Proměnné kanálu

Proměnné se vytváří prostým přiřazením hodnoty:

exten => 999,1,Set(promenna=12345) ;vytvoří proměnnou promenna

Na hodnotu proměnné se můžeme odkazovat pomocí zápisu ${promenna}. Neexistující proměnná se chová jako prázdný řetězec. Přitom nezáleží na velikosti písmen:

exten => 999,n,NoOp(${promenna}) ;vypíše 12345
exten => 999,n,NoOp(${PROMENNA}) ;také vypíše 12345

Proměnné je možno vkládat přímo do textu. Můžete je použít v parametrech libovolné funkce. Lze je tak opatřit prefixem, nebo příponou. Podobně jednoduše je možné zřetězit dvě proměnné:

exten => 999,1,Set(a=123)
exten => 999,n,Set(b=text${a})
exten => 999,n,NoOp(Hodnota b = ${b})       ;vypíše Hodnota b = text123
exten => 999,n,Set(c=${a}${b})
exten => 999,n,NoOp(${c})                   ;vypíše 123text123

Pro ilustraci uvedeme výstup na konzoli Asterisku, nezapomeňte nastavit úroveň logování alespoň na hodnotu 3 (core set verbose 3):

-- Executing [999@internal:1] Set("SIP/novak-0865dff8", "a=123") in new stack
-- Executing [999@internal:2] Set("SIP/novak-0865dff8", "b=text123") in new stack
-- Executing [999@internal:3] NoOp("SIP/novak-0865dff8", "Hodnota b = text123") in new stack
-- Executing [999@internal:4] Set("SIP/novak-0865dff8", "c=123text123") in new stack
-- Executing [999@internal:5] NoOp("SIP/novak-0865dff8", "123text123") in new stack

Při přiřazování proměnných je potřeba, aby před rovnítkem a za rovnítkem nebyly žádné mezery:

exten => 999,1,Set(promenna=1)
exten => 999,n,NoOp(x${promenna}x)   ;x1x
exten => 999,n,Set(promenna= 1)
exten => 999,n,NoOp(x${promenna}x)   ;x 1x
exten => 999,n,Set(promenna=1)
exten => 999,n,Set(promenna =2)
exten => 999,n,NoOp(x${promenna}x)   ;x1x
exten => 999,n,NoOp(x${promenna }x)  ;x2x
exten => 999,n,Set(promenna=)
exten => 999,n,NoOp(x${promenna}x)   ;xx

Jak je vidět z předchozího příkladu, mezera za rovnítkem se dosadí do proměnné a mezera před rovnítkem se použije jako součást jména proměnné. Poslední přiřazení Set(promenna=) je standardní způsob, jak vymazat obsah proměnné.

Hodnotu, která je přiřazena do proměnné, je možné uzavřít do uvozovek. Uvozovky se však chovají celkem speciálně, Asterisk je ignoruje:

exten => 999,1,Set(promenna="ahoj")
exten => 999,n,NoOp(x${promenna}x)          ; xahojx
exten => 999,n,Set(promenna= "ahoj")
exten => 999,n,NoOp(x${promenna}x)          ; x ahojx
exten => 999,n,Set(promenna=nazdar"ahoj")
exten => 999,n,NoOp(x${promenna}x)          ;xnazdarahojx

Předdefinované proměnné kanálu

Některé proměnné kanálu jsou nastaveny automaticky. V jejich jménech se používají velká písmena a narozdíl od uživatelských proměnných jsou předdefinované proměnné citlivé na velikost písmen. Příkladem předdefinované proměnné je volané číslo uložené v proměnné ${EXTEN}.

exten => 999,1,NoOp(${EXTEN})   ; vypíše 999
exten => 999,n,NoOp(${exten})   ; vypíše prázdný řetězec
exten => 999,n,Set(EXTEN=555)
exten => 999,n,NoOp(${EXTEN})   ; vypíše 999
exten => 999,n,Set(exten=888)
exten => 999,n,NoOp(${exten})   ; vypíše 888
exten => 999,n,NoOp(${EXTEN})   ; vypíše 999

Některé předdefinované proměnné jsou jen pro čtení. Jak je vidět z příkladu, přiřazení do proměnné EXTEN její hodnotu nezměnilo.

Globální proměnné

Vše, co jsme dosud napsali o proměnných kanálu plati i pro globální proměnné. Rozdíl spočívá hlavně ve způsobu přiřazení. K odlišení se používá konstrukce GLOBAL.


exten => 999,1,Set(GLOBAL(globalni_promenna)="ahoj")
exten => 999,n,NoOp(${globalni_promenna})

V případě, že existuje globální proměnná a proměnná kanálu se stejným jménem, má přednost proměnná kanálu:

exten => 999,1,Set(GLOBAL(a)=Globalni)
exten => 999,n,NoOp(${a})                ; Globalni
exten => 999,n,Set(a=Lokalni)
exten => 999,n,NoOp(${a})                ; Lokalni
exten => 999,n,NoOp(${GLOBAL(a)})        ; Globalni

Globální proměnné lze vytvořit také v sekci [globals] v souboru extensions.conf. Následující příklad počítá hovory přijaté na extension 999.

[globals]
counter=0

[internal]
exten => 999,1,Set(GLOBAL(counter)=$[${GLOBAL(counter)}+1])
exten => 999,n,NoOp(${GLOBAL(counter)})
exten => 999,n,Answer()
exten => 999,n,Playback(hello-world)
exten => 999,n,Hangup()

Čítač counter se vynuluje vždy při reloadu konfigurace. Pokud chcete, aby se hodnoty globálních proměnných zachovávaly i při reloadu, můžete použít volbu clearglobalvars=no v sekci [general] souboru extensions.conf.

Proměnné prostředí

Proměnné prostředí jsou přístupné pro čtení i zápis a přistupuje se k nim pomocí konstrukce ENV.

exten => 999,1,NoOp(${ENV(PATH)})
exten => 999,n,Set(ENV(PATH)="/sbin:/bin")

Podřetězce

Pomocí speciálního zápisu ve tvaru ${promenna:ofset}, nebo ${promenna:ofset:delka} lze vybrat jen část řetězce, který je uložen v proměnné. ofset určuje počátek podřetězce a delka jeho délku. Je-li uveden jen ofset, použijí se všechny znaky až do konce řetězce. První znak má ofset 0. Je-li ofset záporný, počítá se pozice prvního znaku zprava.


${123456789:1}        - vrací řetězec 23456789
${123456789:-4}       - vrací řetězec 6789
${123456789:0:3}      - vrací řetězec 123
${123456789:2:3}      - vrací řetězec 345
${123456789:-4:3}     - vrací řetězec 678

Jako ofset nebo delka může být použita i proměnná. Na závěr dnešního dílu si ukážeme trochu složitější příklad, který na základě volaného čísla odvodí zkratku dne v týdnu.

;pravidlo odpovídá telefonním číslům 991 až 997
;z volaného čísla vybereme třetí číslici
exten => _99[1-7],1,Set(cislice=${EXTEN:2:1})

;vynásobíme dvěma a posuneme tak, aby z 991 vyšla nula
exten => _99[1-7],n,Set(pozice=$[${cislice}*2-2])

exten => _99[1-7],n,Set(dny=PoUtStCtPaSoNe)
exten => _99[1-7],n,Set(den=${dny:${pozice}:2})
exten => _99[1-7],n,NoOp(den v tydnu je ${den})

Užitečné odkazy

Na závěr uvedeme některé užitečné odkazy na stránky s popisem předdefinovaných proměnných a funkcí, stránky bohužel nejsou vždy aktuální. Některým funkcím se budeme věnovat v pokračování seriálu.