28 Апр
2012
Рубрика: Asterisk
Автор:    4 комментария

Asterisk переадресация

Важной функцией в телефоние является переадресация. Существует множество видов переадресаций, настроенных на любой вкус. Одна из них — безусловная переадресация. Ее можно по желанию переделать в условную переадресацию. Все усложняется потребностью в 2х транках или многоканальной линии. Для того, чтобы cделать переадресацию, используется база данных Asterisk astDB. Чтобы суметь включить и настроить переадресацию, надо разобрать по частям весь кусок диалплана, который отвечает именно за переадресацию:

exten => #21,1,Set(DB(REDIRECT/${CALLERID(num)})=${EXTEN})

exten => #21#,1,Set(NOREDIRNUM=${DB_DELETE(REDIRECT/${CALLERID(num)})})

exten => s,1,Set(REDIRECTNUM=${DB(REDIRECT/${EXTEN})})
exten => s,n,GotoIf($[${ISNULL(${REDIRECTNUM})}]?internal:redirect)
exten => s,n(internal),Dial(SIP/${EXTEN})
exten => s,n(redirect),Dial(SIP/TRUNK/${REDIRECTNUM})

Теперь разберем что за что отвечает. Переадресация включается по желанию клиента, как мы уже писали выше, то есть для того, чтобы она заработала, ее надо предварительно настроить, она не входит в первоначальный пакет услуг.

exten => #21,1,Set(DB(REDIRECT/${CALLERID(num)})=${EXTEN})

Вот тут и начинается использование базы данных Asterisk – она всегда запоминает набранную комбинацию цифр и номер, с которого осуществлялся набор.

Эти данные помещаются в базу данных в семейство REDIRECT по ключу ${CALLERID(num)}. То есть, процесс происходит так. Мы набираем #21 и номер, на который будет осуществляться переадресация. То есть он сохранится в таблице REDIRECT в строке ${CALLERID(num)} в базу данных Asterisk . Название строки ${CALLERID(num)} содержит в себе номер, из которого происходил вызов. В соседней ячейке, под названием
${EXTEN} в той же строчке будет введенный номер.

Примерно так же можно и выключить переадресацию:

exten => #21#,1,Set(NOREDIRNUM=${DB_DELETE(REDIRECT/${CALLERID(num)})})

Просто на клавиатуре надо набрать #21# и база Asterisk задействует утилиту DB_DELETE по отношению к вашей ячейке REDIRECT/${CALLERID(num)} и таким образом, просто освобождает ее от информации.

Если мы задали строку переадресации в базе данных, то как же происходит сам процесс переадресации? Все происходит несложно. Реализация вызова происходит следующим образом.

exten => s,1,Set(REDIRECTNUM=${DB(REDIRECT/${EXTEN})})

Для начала проверяют, сохранен ли вообще для этого абонента номер переадресации. Для этого переменной REDIRECTNUM присваивают номер, который сохраняется в ячейке REDIRECT/${EXTEN}. Если мы меняли значение для переадресации, то там номер, который мы ввели, если же мы не задавали специальные данные для переадресации, то там те же данные, что и в ячейке ${CALLERID(num)}, то есть наш номер. Далее производится проверка существования номера перадресации: Если переменная REDIRECTNUM ISNULL (пуста/неопределена) то мы переходим к строке с меткой internal и вызываем абонента по его основному номеру:

exten => s,n,GotoIf($[${ISNULL(${REDIRECTNUM})}]?internal:redirect)

Именно по тому номеру, который находиться в ячейке ${EXTEN} база данных и осуществит вызов. Если же абонент уже ставил номер на переадресацию, а потом удалял его, то ячейка ${EXTEN} пуста. Тогда база данных применяет утилиту internal и вызывает номер, который наведен в строке ${CALLERID(num)}.

exten => s,n(internal),Dial(SIP/${EXTEN})

Если же переменная REDIRECTNUM не пуста, то вызываем номер, указанный в ней.

exten => s,n(redirect),Dial(SIP/TRUNK/${REDIRECTNUM})

Для настройки самой ОС на которой установлен Asterisk иногда захожу на форум http://www.cyberforum.ru/linux/.

4 комментария

  • Назвать этот метод чистой переадресацией нельзя. Это два отдельных вызова, в каждом из которых есть только номера А и B. В переадресованном вызове должны быть номера А, B и C.
    В описанной переадресации есть один, но большой минус — если во второй ноге вызова в качестве АОНа ставить номер B, тогда абонент C никогда не увидит реальный АОН абонента А. Если же, во второй ноге выставить в качестве АОНа номера абонента А, тогда локальный оператор (и уж МГ/МН точно) такой вызов зарубят, ибо АОН не их.

  • Еще минус. Это предполагает безусловную переадресацию только на внешний номер. Если аббоненту нужно переадресовать телефон на внутренний . Наверно как-то так но в синтаксисе не уверен
    exten => s,n,GotoIf($[${ISNULL(${REDIRECTNUM})}]?internal:redirect)
    exten => s,n(internal),Dial(SIP/${EXTEN})
    exten => s,n,GotoIf($[«${REDIRECTNUM:0:1}»=»9»]?external:internal)
    exten => s,n(external),Dial(SIP/TRUNK/${REDIRECTNUM})
    exten => s,n,HangUp()
    exten => s,n(internal),Dial(SIP/${REDIRECTNUM})
    exten => s,n,HangUp()

  • Проверил и настроил.
    Кривовато в области безусловной переадресации.Может что предложите.
    Для адаптации под себя нужно записать приветствия:
    [service]
    ;контекст для сервисных функций
    ; Условная
    exten => *92,1,Playback(vvedite_nomer_dlya_pereadresacii)
    same => n,Playback(beep)
    same => n,Read(cfwd)
    same => n,Playback(beep)
    same => n,Set(DB(REDIRECT/${CALLERID(num)})=${cfwd})
    same => n,Set(DB(REDIRTIMER/TIMER)=10)
    same => n,Playback(zvonki_pereadresovany_na_nomer)
    same => n,SayDigits(${DB(REDIRECT/${CALLERID(num))}})
    same => n,Playback(goodbay)
    ; Безусловная
    exten => *93,1,Playback(vvedite_nomer_dlya_pereadresacii)
    same => n,Playback(beep)
    same => n,Read(cfwd)
    same => n,Playback(beep)
    same => n,Set(DB(REDIRECT/${CALLERID(num)})=${cfwd})
    same => n,Set(DB(REDIRTIMER/TIMER)=1)
    same => n,Playback(zvonki_pereadresovany_na_nomer)
    same => n,SayDigits(${DB(REDIRECT/${CALLERID(num))}})
    same => n,Playback(goodbay)
    ; Отмена переадресации
    exten => *94,1,Set(NOREDIRNUM=${DB_DELETE(REDIRECT/${CALLERID(num)})})
    same => n,Playback(Pereadresaciya_otmenena)

    [default]
    exten =>_1XX,1,Verbose(——Internal Phone——)
    ;Начало блока переадресации
    same => n,Set(REDIRECTNUM=${DB(REDIRECT/${EXTEN})})
    same => n,GotoIf($[${ISNULL(${REDIRECTNUM})}]?internal:redirect)
    same => n(internal),Dial(SIP/${EXTEN})
    same => n,Hangup()
    same => n(redirect),GotoIf($[«${REDIRECTNUM:0:1}»=9]?extnum:intnum)
    same => n(extnum),Dial(SIP/${EXTEN},${DB(REDIRTIMER/TIMER)})
    same => n,Dial(SIP/Tumen/${REDIRECTNUM})
    same => n,HangUp()
    same => n(intnum),Dial(SIP/${EXTEN},${DB(REDIRTIMER/TIMER)})
    same => n,Dial(SIP/${REDIRECTNUM})
    same => n,HangUp()

  • И ещё таймеры поправить

    same => n,Set(DB(REDIRTIMER/${CALLERID(num)}/TIMER)=10)

    same => n(extnum),Dial(SIP/${EXTEN},${DB(REDIRTIMER/${EXTEN}/TIMER)})

Что вы думаете об этом?