artem
14.11.2016
4655

Механизм hangup handler в Asterisk

Механизм hangup handler появился в Asterisk 11 и позволяет выполнять диалплан сразу после завершения вызова на канале. Использование hangup handler в диалплане обладает рядом преимуществ перед использованием экстеншена h. Во-первых, hangup handler срабатывает вне зависимости от того, в каком контексте происходит выполнение диалплана в момент завершения вызова, во-вторых, можно выполнить диалплан при завершении вызова на канале, на котором диалплан не выполняется, и последнее никак нельзя реализовать с помощью экстеншена h. Диалплан в Asterisk выполняется только на канале, инициировавшем вызов, также, приложения диалплана, создающие новые каналы (такие как Dial и Queue), позволяют выполнять диалплан на канале, ответившем на вызов, сразу после ответа. С помощью hangup handler можно выполнить диалплан на канале, ответившем на вызов, также и после завершения вызова на этом канале (при этом канал, инициировавший вызов, может продолжать существовать, например, в результате перевода вызова).

Использование механизма hangup handler:
Для начала подготовим контекст, который hangup handler будет выполнять. Контекст нужно писать таким же образом, как для приложений Gosub и GosubIf:

[sub-call-from-cid-ended]
exten => s,1,GotoIf($[“${ARG1}” = “” | “${ARG2}” = “”]?end)
same => n,System(curl –max-time 10 –data-urlencode ‘cid=${ARG1}’ –data-urlencode ‘operator=${ARG2}’ –data-urlencode ‘end=${EPOCH}’ http://stats-host.local/inbound & disown -h)
same => n,Set(DB(CALL_FROM_CID/${ARG1}/end)=${EPOCH})
same => n,Set(DB(CALL_FROM_CID/${ARG1}/answered_by)=${ARG2})
same => n(end),Return

ARG1 – номер звонившего, ARG2 – номер ответившего (hangup handler позволяет передавать аргументы точно так же, как Gosub и GosubIf)
Данный контекст отправляет с помощью curl информацию о завершении входящего вызова на некий гипотетический хост stats-host.local, собирающий статистику о вызовах.
Диалплан для добавления hangup handler, который выполнит контекст sub-call-from-cid-ended после завершения вызова на текущем канале:

same => n,Set(CHANNEL(hangup_handler_push)=sub-call-from-cid-ended,s,1(${CALLERID(num)},${EXTEN}))

Диалплан для удаления последнего добавленного hangup handler:

same => n,Set(CHANNEL(hangup_handler_pop)=)

Также можно добавить другой hangup handler на место удаляемого;

same => n,Set(CHANNEL(hangup_handler_pop)=sub-do-something-else,s,1)

Так можно удалить все hangup handler, добавленные на текущий канал (на канал можно добавить несколько hangup handler и они будут выполнены по порядку, начиная с последнего добавленного):

same => n,Set(CHANNEL(hangup_handler_wipe)=)

Как и в случае с hangup_handler_pop, можно добавить новый hangup handler на место удаляемых:

same => n,Set(CHANNEL(hangup_handler_wipe)=sub-do-something-else,s,1)

Пример использования hangup handler
В очереди inbound есть операторы Local/101@from-queue/n и Local/102@from-queue/n. На хост stats-host.local нужно отправлять HTTP-запрос в тот момент, когда оператор принимает вызов, и в тот момент, когда оператор прекращает участвовать в вызове. Вам может показаться, что задачу можно решить с помощью экстеншена h (ведь при вызове оператора выполняется диалплан в контексте from-queue), но если операторы очереди будут переводить полученные вызовы управляемым и неуправляемым переводом с помощью телефона и с помощью сервисных кодов Asterisk, то экстеншен h не всегда будет выполняться в момент завершения вызова оператора очереди. Ниже приведено решение с помощью hangup handler:
Так вызовы попадают в очередь:

[queues]
exten => inbound,1,Answer
same => n,Queue(inbound,t,,,300)
same => n,Hangup

Так выглядит вызов оператора из очереди

[from-queue]
exten => _1XX,1,Dial(SIP/${EXTEN},30,tU(sub-on-operator-answer^${CALLERID(num)}^${EXTEN}))
same => n,Hangup

Контекст, выполняемый в момент ответа оператора

[sub-on-operator-answer]
exten => s,1,GotoIf($[“${ARG1}” = “” | “${ARG2}” = “”]?end)
same => n,System(curl –max-time 10 –data-urlencode ‘cid=${ARG1}’ –data-urlencode ‘operator=${ARG2}’ –data-urlencode ‘start=${EPOCH}’ http://stats-host.local/inbound & disown -h)
same => n,Set(CHANNEL(hangup_handler_push)=sub-call-from-cid-ended,s,1(${ARG1},${ARG2}))
same => n(end),Return

 
avatar
  Подписаться  
Уведомление о

Остались вопросы?

Я - Першин Артём, менеджер компании Voxlink. Хотите уточнить детали или готовы оставить заявку? Укажите номер телефона, я перезвоню в течение 3-х секунд.

VoIP оборудование

ближайшие курсы

ближайшие Вебинары

ONLINE

Why Choose HUGE?

Unlimited pre-designed elements

Each and every design element is designed for retina ready display on all kind of devices

User friendly interface and design

Each and every design element is designed for retina ready display on all kind of devices

100% editable layered PSD files

Each and every design element is designed for retina ready display on all kind of devices

Created using shape layers

Each and every design element is designed for retina ready display on all kind of devices