Благодаря Вам вопрос практически решен, осталась одна маленькая неприятность, связанная, наверное, с особенностями локального псевдоканала.
Сейчас у меня работает sip транк на 20 одновременных соединений, по нему заходят входящие звонки и совершаются исходящие, причем входящие приоритетнее. В диалплане 3 контекста: один для входящих и 2 для исходящих, также есть 2 глобальные переменные ICC и OCC - счетчики входящих и исходящих активных каналов соответственно, кроме того есть 20 ключей в базе вида "cs/cnXX" (XX - порядковый номер канала, выполняющий роль индекса ключа от 1 до 20), которые могут принимать значения "I" и "O".
В начале обработки входящих соединения я эксклюзивным вызовом макроса инкрементирую счетчик ICN и пробегаюсь по базе от 1 до 20 в поисках первого ключа с пустым значением, присваиваю локальной переменной CN индекс этого ключа, а самому ключу присваиваю значение "I". В конце обработки, тем-же макросом, я декрементирую счетчик и ключу с индексом CN присваиваю пустое значение. Всё работает железно (проверено на ~20000 входящих)
Для исходящий я делаю то-же самое в начале, только смотрю базу с конца (от 20 до 1) и присваиваю ключу значение "O". Если на вызов ответили то декремент и освобождение ключа я делаю в конце второго контекста, а если нет - то в конце первого. Вот тут возникает ситуация что на этапе декремента переменная CN=0. Очень редко, но бывает, соответственно ключ в базе не освобождается и логика рушиться.
В чем может быть бедулька?
Диалплан привожу:
Код: Выделить всё
[general]
static=yes
writeprotect=yes
clearglobalvars=yes
[globals]
ACC=20
ICC=0
OCC=0
[macro-assume]
exten => s,1,Set(GLOBAL(${ARG1})=$[${GLOBAL(${ARG1})}+1])
exten => s,n,Set(__CN=0)
exten => s,n,Set(CMP=${IF($[${ARG2}<${ARG3}]?>:<)})
exten => s,n,Set(INC=${IF($[${ARG2}<${ARG3}]?+:-)})
exten => s,n,Set(I=${ARG2})
exten => s,n(loop_start),GotoIf($[0${I}${CMP}0${ARG3}]?loop_end)
exten => s,n,GotoIf($["${DB(cs/cn${I})}"!=""]?step_end)
exten => s,n,Set(DB(cs/cn${I})=${ARG4})
exten => s,n,Set(__CN=${I})
exten => s,n,Goto(loop_end)
exten => s,n(step_end),Set(I=$[${I}${INC}1])
exten => s,n,Goto(loop_start)
exten => s,n(loop_end),NoOp
[macro-free]
exten => s,1,ExecIf($[0${CN}!=00]?Set(DB(cs/cn${CN})=))
exten => s,n,Set(GLOBAL(${ARG1})=$[${GLOBAL(${ARG1})}-1])
[macro-counter]
exten => s,1,Macro(${ARG1},${ARG2},${ARG3},${ARG4},${ARG5})
[answerer]
exten => s,1,MacroExclusive(counter,assume,ICC,1,${GLOBAL(ACC)},I)
...
exten => h,1,MacroExclusive(counter,free,ICC)
[caller_i]
exten => _X.,1,MacroExclusive(counter,assume,OCC,${GLOBAL(ACC)},1,O)
exten => _X.,n,Dial(SIP/trunk20/${EXTEN})
exten => h,1,ExecIf($[${DIALSTATUS}!=ANSWER]?MacroExclusive(counter,free,OCC))
[caller_sm]
...
exten => h,1,MacroExclusive(counter,free,OCC)
[incoming_trunk20]
include => answerer