в asterisk, debian

Получение состояния устройства в Asterisk 11 с помощью DEVICE_STATE()

Asterisk
Если используется Call Waiting (режим ожидания для второго входящего звонка при занятой линии) в Asterisk, то при звонке уже разговаривающему абоненту мы услышим в трубке обычные гудки дозвона.

В такой ситуации трудно понять, разговаривает ли сотрудник по второй линии или его просто нет на рабочем месте. Давайте разберемся с вариантами решения этой проблемы!

Самое очевидное решение — отключить поддержку второй линии, но тогда абонент не узнает кто еще пытался ему дозвониться. В Asterisk 11 данную проблему хорошо решает получение состояния устройства с помощью DEVICE_STATE().

Примечание. Функция DEVICE_STATE() используется для получения или установки состояний устройства. Также функция может использоваться для установки особенных состояний устройства из плана набора (в этом случае для указания имени состояния должен использоваться префикс «Custom:»)

В нашем случае используются телефонные аппараты Cisco 504G и Linksys SPA942, которые поддерживают четыре телефонные линии. В случае «занятости» аппарат Cisco 504G возвращает статус BUSY, а аппарат Linksys SPA942 возвращает статус INUSE.

Примечание. На самом деле существует девять возможных значений состояния устройства — UNKNOWN, NOT_INUSE, INUSE, BUSY, INVALID, UNAVAILABLE, RINGING, RINGINUSE и ONHOLD, но мы будем обрабатывать только два из них.

Для получения состояния устройства с помощью DEVICE_STATE() делаем следующее:

  • открываем на редактирование конфиг /etc/asterisk/sip.conf:
nano /etc/asterisk/sip.conf
  • в созданном ранее шаблоне [template-office] добавим строку:
...
callcounter=yes
...
  • открываем конфиг /etc/asterisk/extensions.conf:
nano /etc/asterisk/extensions.conf
  • и добавляем в контекст [office-in] (перед вызовом Dial) следующие строки:
...
exten => s,n,Log(NOTICE, "101 has DEVICE STATE ${DEVICE_STATE(SIP/101)}")
exten => s,n,GotoIf($["${DEVICE_STATE(SIP/101)}" = "BUSY"]?s-BUSY,1)
exten => s,n,GotoIf($["${DEVICE_STATE(SIP/101)}" = "INUSE"]?s-BUSY,1)
...

Теперь при звонке на номер 101 будет проверяться состояние телефонного аппарата, и если функция DEVICE_STATE() вернет состояние устройства BUSY или INUSE, то будет осуществлен условный переход на метку s-BUSY,1 для дальнейшей обработки звонка. Далее звонок будем обрабатывать с помощью голосового меню, организацию которого рассмотрим в следующей статье.

Выполнять обработку можно и без условного перехода, в этой же строке, например так:

exten => s,n,ExecIf($["${DEVICE_STATE(SIP/101)}" = "INUSE"]?Playback(abonent_zanyat))

Для применения изменений в конфигах Asterisk не забываем выполнить:

/etc/init.d/asterisk reload

Добавить комментарий

  1. Кратенько опишу конфигурацию

    sip.conf:
    [sip-trunk](!)
    type = friend
    host = dynamic
    insecure = invite
    context = sip-dg-in
    nat=force_rport,comedia
    canreinvite=no
    subscribecontext=BLF_Group

    [322000052](sip-trunk)
    defaultuser = 322424852
    secret = pass
    fromuser = 322424852

    [322000051](sip-trunk)
    defaultuser = 322424851
    secret = pass
    fromuser = 322424851

    [322000050](sip-trunk)
    defaultuser = 322424850
    secret = pass
    fromuser = 322424850

    extension.conf:

    [sip-dg-in]
    exten => _322000052,1,NoOp(«START CALL ${CALLERID(all)} or ${CALLERID(num)}»)
    ;Проверка на Праздничные
    same => n,GotoIfTime(*,*,6-8,jan?Holiday,rest,1)
    same => n,Goto(incoming-work,work,1) ;Круглосуточно

    [incoming-work]
    exten => _work,1,NoOp(Start call day)
    same => n,Set(CHANNEL(language)=ru)
    same => n,Answer
    same => n,Macro(monitor)
    same => n,Wait(0.5)
    same => n,Dial(SIP/101,20,Ttrm(moh3))
    same => n,System(sh /etc/asterisk/mycall-missed.sh ${CALLERID(num)}) ;Сообщ. о надобности перезвонить
    same => n,Background(/var/lib/asterisk/sounds/data0/IVR3) ;Мы заняты и Вам перезвоним
    same => n,Hangup
    exten => _1,1,NoOp(The ${EXTEN} was pressed by ${CALLERID(num)}) ;Нажали 1 для Калл-Бека
    same => n,System(sh /etc/asterisk/mycall-back.sh ${CALLERID(num)}) ;Сообщ. о запросе Калл-Бека
    same => n,Hangup

    [local-calls]
    exten => _1XX,1,NoOp(Start local call from ${CALLERID(num)})
    same => n,Macro(monitor)
    same => n,Dial(SIP/${EXTEN},,rTt)
    same => n,Hangup

    exten => _*1.,1,NoOp(«**** Start Calling from ${CALLERID(number)}****»)
    same => n,Macro(monitor)
    same => n,Dial(SIP/322000050/${EXTEN:2},,rTt)
    same => n,Hangup

    Промаркировать при входящем для локальных INT понятно где и как написать.
    А вот как быть с маркировкой входящих транков?
    Ладно еще могу вначале промаркировать, а как быть с обратным размаркированием?
    Ведь пришел звонок на запись типа:
    exten => _322000052,
    А как после звонка понять, как прописать чтобы именно этот транк установить в состояние свободен