Здравствуйте. Предположим, в каком то месте Gosub необходимо прыгнуть в другой контекст (минуя Return). Нашел такой вариант:
exten => s,1,Read(input,get-input)
exten => s,n,Gosub(validate,1)
exten => s,n,Dial(SIP/${input})
exten => validate,1,GotoIf($[ ${input} > 499 ]?error,1)
exten => validate,n,GotoIf($[ ${input} < 400 ]?error,1)
exten => validate,n,Return
exten => error,1,StackPop()
exten => error,2,Goto(s,1)
Это best practice или все-таки можно напрямую, без риска чего-то вроде утечки памяти при некорректно закрытой процедуре.
Также в Gosub одновременно реализована возможность передавать аргументы/возвращать результат, и менять значения channel variables (стандартный способ обмена инфой м/у контекстами). Это фича такая, или я не понимаю чего-то ?
best practice вот так
exten => s,1,Gosub(somefunction,s,1)
same => n,GotoIF(${ "${SOMEVAR}" == 1 }?othercontext,s,1)
[somefunction]
exten =>error,1,Set(SOMEVAR=1)
same => n,Return
манипулировать стеком это bad practice.
утечки не будет, но если потом гдето будет неучтенный Return может фигня выйти. хотя неучтенный ретурн тоже не очень хорошо.
кстати, валидация в астриске выполняется вот так
[validate]
exten => _4XX,1,Set(ERROR=0);добавляем для всех возможных патернов.
exten => _4XX,n,Return
include =>not_validated
[not_validated]
exten => _.,1,Set(ERROR=1);выполнится только если не сматчится ничего в validate
exten => _.,2,Return
[context]
exten => s,1,Set(loop=5)
same => n(read),Read(${add}input,get-input)
same => n,Gosub(validate,${input},1)
same => n,GotoIF($[ ${loop} > 5 ]?end)
same => n,GotoIF($[ "${ERROR}" != "1" ]?dial)
same => n,Set(loop=$[ ${loop} + 1 ])
same => n,Set(add=invalid_input&)
same => n,Goto(read)
same => n(dial),Dial(SIP/${input})
Задан: 2013-06-28 14:23:21 +0400
Просмотрен: 4,071 раз
Обновлен: Jun 28 '13
Проект компании "АТС Дизайн"
Asterisk® и Digium® являются зарегистрированными торговыми марками компании
Digium, Inc., США.
IP АТС Asterisk распространяется под лицензией
GNU GPL.
советую посмотреть на метки (labels) в экстеншнах. вообще лучше использовать AEL для таких вещей - гораздо проще и удобнее ИМХО...
octopas ( 2013-06-28 14:53:49 +0400 )редактироватьВ моем конкретном случае нужно выйти именно из Gosub.
bb2kp ( 2013-06-28 15:01:00 +0400 )редактироватьcmd DISA есть для такого.... непонятно что вы пытаетесь реализовать, а главное зачем? какие утечки памяти в контексте вызова? этто же не резидентная программа.. после вызова завершения вызова все равное все соберет мусоросборщик....
octopas ( 2013-06-28 15:19:46 +0400 )редактировать