Звездочка: вперед, если узел недоступен

Я хотел бы ответить на входящие звонки, проверив, доступен ли конкретный узел, и набрать соответствующий номер соответствующим образом.

В настоящее время я сделал это:

exten => 1200,1,Answer()
same => n,Set(reachable=${SHELL(asterisk -rx "sip show peers" | grep ^cedrich-phone.*OK)})
same => n,GotoIf($["${LEN(${reachable})}" = "0"]?extoffline)
same => n,Dial(SIP/cedrich-phone,20)
same => n(extoffline),Dial(SIP/another-phone,20,tr)
same => n,Hangup()

Не могли бы вы сказать мне, является ли это приемлемым и можно ли его улучшить, используя лучшие практики?

3 ответа

Решение

Выполнение оболочки звездочки при входящем звонке просто не подходит мне. Это, вероятно, работает нормально, но разве не должен быть уже известен статус peer для звездочки?

Я использую функцию SIPPEER() с помощью которого вы можете запросить статус пира. Если первые 3 символа (из OK (44 ms)) является OK тогда вы можете позвонить сверстнику. Все остальные ситуации вы можете переслать другому пэру.

Я делаю что-то вроде этого:

exten => _202,1,Log(NOTICE,Dial Status of ${EXTEN}: ${SIPPEER(${EXTEN},status)})
exten => _202,n,GotoIf($["${SIPPEER(${EXTEN},status):0:3}"="OK "]?ok1:forward)
exten => _202,n(ok1),Log(NOTICE,Calling number is available)
exten => _202,n,Dial(SIP/${EXTEN},50,wW)
exten => _202,n,Hangup()
exten => _202,n(forward),Log(NOTICE,Calling forward number)
exten => _202,n,Dial(SIP/201,50,wW)
exten => _202,n,Hangup()

Это проверяет статус, прежде чем мы собираемся Dial() и идет к n(forward) если узел недоступен, занят или иным образом не в порядке.

Однако здесь есть небольшая проблема. Когда партнер отклоняет вызов (или по другой причине недоступен, например, он был в сети до нашей следующей онлайн-проверки), звонок не проходит.

Есть функция DIALSTATUS мы можем использовать после Dial() чтобы проверить, был ли звонок успешно отвечен. Так что используйте это после Dial() и если это не ответили, также сделайте вперед. (Это сработало в тесте, который я сделал. Отрицание вызова дало BUSY в лог и перешел к следующему сверстнику)

Вы получаете что-то вроде этого:

exten => _202,1,Log(NOTICE,Dial Status of ${EXTEN}: ${SIPPEER(${EXTEN},status)})
exten => _202,n,GotoIf($["${SIPPEER(${EXTEN},status):0:3}"="OK "]?ok1:forward)
exten => _202,n(ok1),Log(NOTICE,Calling number is available)
exten => _202,n,Dial(SIP/${EXTEN},50,wW)
exten => _202,n,Log(NOTICE,Dial status: ${DIALSTATUS})
exten => _202,n,GotoIf($["${DIALSTATUS)}"="ANSWER"]?ok2:forward)
exten => _202,n(ok2),Log(NOTICE,Successfull call)
exten => _202,n,Hangup()
exten => _202,n(forward),Log(NOTICE,Calling forward number)
exten => _202,n,Dial(SIP/201,50,wW)
exten => _202,n,Hangup()

Я не проверял этот последний бит (с DIALSTATUS), так что вы должны сделать некоторые тесты, но здесь, кажется, работает.

Как упоминалось в @arheops, вы можете использовать DEVICE_STATE(), чтобы получить статус определенного устройства, если это отображение 1:1 (1 учетная запись на 1 устройстве). Вы можете использовать следующее:

${DEVICE_STATE(${CHANNEL(channeltype)}/${CHANNEL(peername)})}

Другой возможностью является функция EXTENSION_STATE(), если у вас есть отображение 1: много (одно расширение с более чем одним устройством).

Оба могут иметь подсказки, как описано здесь, если вам нужно иметь одного пользователя для использования нескольких устройств. Здесь вы можете увидеть, как делать динамические подсказки

Использование системы в диалплане откроет оболочку и вызовет 2 процесса для каждого звонка.

Конечно, у звездочки есть функция для вашей задачи. Это описано во всех книгах.

-= Info about function 'DEVICE_STATE' =- 

[Synopsis]
Get or Set a device state. 

[Description]
The DEVICE_STATE function can be used to retrieve the device state from any
device state provider. For example:
NoOp(SIP/mypeer has state ${DEVICE_STATE(SIP/mypeer)})
NoOp(Conference number 1234 has state ${DEVICE_STATE(MeetMe:1234)})
The DEVICE_STATE function can also be used to set custom device state from
the dialplan.  The 'Custom:' prefix must be used. For example:
Set(DEVICE_STATE(Custom:lamp1)=BUSY)
Set(DEVICE_STATE(Custom:lamp2)=NOT_INUSE)
You can subscribe to the status of a custom device state using a hint in
the dialplan:
exten => 1234,hint,Custom:lamp1
The possible values for both uses of this function are:
UNKNOWN | NOT_INUSE | INUSE | BUSY | INVALID | UNAVAILABLE | RINGING |
RINGINUSE | ONHOLD
Другие вопросы по тегам