artem
05.12.2018
4198

Выполнение сервисных кодов на всех серверах Asterisk, соединённых с помощью DUNDi

Настройка DUNDi между серверами Asterisk — полдела, после этого часто встаёт вопрос о работе сервисных кодов между серверами Asterisk. В данной статье будут приведены необходимые настройки на примере двух функций, вызываемых сервисными кодами — пауза в очередях и прослушка с помощью ChanSpy.

Сервисные коды на серверах Астериск с помощью DUNDi

Настройку DUNDi нужно выполнить по статье (шифрование SIP и RTP опционально, но вызовы между серверами должны совершаться по SIP). Чтобы не писать каждый раз диалплан для вызова номера через DUNDi, нужно написать контекст для Gosub на основе контекста outbound-dundi, приведённого в упомянутой статье:

[sub-dial-to-dundi]
exten => s,1,Set(DUNDI_MAPPING=direct)
same  => n,Set(DUNDI_RES=${DUNDILOOKUP(${ARG1},${DUNDI_MAPPING})})
same  => n,GotoIf($[«${DUNDI_RES}» = «»]?end)
same  => n,Set(DUNDI_HOST=${CUT(DUNDI_RES,@,2)})
same  => n,Set(DUNDI_HOST=${CUT(DUNDI_HOST,/,1)})
same  => n,GotoIf($[«${SIPPEER(from-${DUNDI_HOST},ip)}» = «»]?end)
same  => n,Dial(SIP/from-${DUNDI_HOST}/${ARG1},${TRUNK_RING_TIMER},${ARG2})
same  => n(end),Return

 Также нам дополнительно понадобится контекст, чтобы перебрать все результаты DUNDi-запроса и сделать вызов на все сервера сразу:

[sub-dial-to-dundi-all]
exten => s,1,Set(DUNDI_DIAL_STR=)
same  => n,Set(DUNDI_MAPPING=direct)
same  => n,Set(DUNDI_RES_ID=${DUNDIQUERY(${ARG1},${DUNDI_MAPPING})})
same  => n,Set(DUNDI_RES_COUNT=${DUNDIRESULT(${DUNDI_RES_ID},getnum)})
same  => n,Set(DUNDI_RES_I=1)
same  => n(next),GotoIf($[${DUNDI_RES_I} > ${DUNDI_RES_COUNT}]?end)
same  => n,GotoIf($[${DUNDI_RES_I} > 10]?end) ; safeguard — maximum 10 DUNDi results
same  => n,Set(DUNDI_RES=${DUNDIRESULT(${DUNDI_RES_ID},${DUNDI_RES_I})})
same  => n,GotoIf($[«${DUNDI_RES}» = «»]?next)
same  => n,Set(DUNDI_HOST=${CUT(DUNDI_RES,@,2)})
same  => n,Set(DUNDI_HOST=${CUT(DUNDI_HOST,/,1)})
same  => n,GotoIf($[«${SIPPEER(from-${DUNDI_HOST},ip)}» = «»]?next)
same  => n,ExecIf($[«${DUNDI_DIAL_STR}» != «»]?Set(DUNDI_DIAL_STR=${DUNDI_DIAL_STR}&SIP/from-${DUNDI_HOST}/${ARG1}):Set(DUNDI_DIAL_STR=SIP/from-${DUNDI_HOST}/${ARG1}))
same  => n,Set(DUNDI_RES_I=$[${DUNDI_RES_I} + 1])
same  => n,Goto(next)
same  => n(end),ExecIf($[«${DUNDI_DIAL_STR}» != «»]?Dial(${DUNDI_DIAL_STR},${TRUNK_RING_TIMER},${ARG2}))
same  => n,Return

Пауза в очередях

Абонентов с одного сервера вполне можно добавить в очередь, настроенную на другом сервере — было бы хорошо, чтобы абоненты могли переключать состояние паузы одновременно во всех очередях на всех серверах. В FreePBX для переключения состояния паузы используются стандартные сервисные коды *46 и _*46*X. (для настройки BLF на телефоне), оба сервисных кода вызывают контекст app-all-queue-pause-toggle.
Контекст app-all-queue-pause-toggle нужно заоверрайдить на всех серверах и привести к следующему виду (все изменения внесены между комментариями «start» и «end»):

[app-all-queue-pause-toggle]
include => app-all-queue-pause-toggle-custom
exten => s,1(start),Answer
exten => s,n,Wait(1)
exten => s,n,Macro(user-callerid,)
;start
exten => s,n,AGI(queue_devstate.agi,toggle-pause-all,${REALCALLERIDNUM})
exten => s,n,GosubIf($[${TOGGLEPAUSED}]?sub-dial-to-dundi-all,s,1(*046${REALCALLERIDNUM}):sub-dial-to-dundi-all,s,1(*047${REALCALLERIDNUM}))
;end
exten => s,n,Playback(dictate/pause&${IF($[${TOGGLEPAUSED}]?activated:de-activated)})
exten => s,n,Macro(hangupcall,)

Теперь на каждый сервер нужно добавить контекст для обработки вызовов на _*046X. и на _*047X. (контекст не должен отвечать на вызов, иначе вызовы на другие сервера могут прекратиться досрочно)

[from-pbxs-queue-pause]
exten => _*046X.,1,ResetCDR
same  => n,NoCDR
same  => n,PauseQueueMember(,Local/${EXTEN:4}@from-queue/n)
same  => n,Hangup
exten => _*047X.,1,ResetCDR
same  => n,NoCDR
same  => n,UnpauseQueueMember(,Local/${EXTEN:4}@from-queue/n)
same  => n,Hangup

Контекст from-pbxs-queue-pause нужно включить в контекст from-pbxs, который в нашем случае используется для обработки вызовов от других серверов:

[from-pbxs]
include => ext-findmefollow
include => ext-local
include => from-pbxs-queue-pause

С этим сервисным кодом всё, теперь при звонке на *46 или _*46*X. пауза должна включаться/выключаться на всех серверах, соединённых по DUNDi.

Прослушка с помощью ChanSpy

Для прослушки будем использовать не стандартный функционал FreePBX, а самописный диалплан. Вот контексты, реализующие прослушку (один для прослушки, второй для суфлирования):

[ext-chanspy-spy]
exten => _X.,1,GotoIf(${DIALPLAN_EXISTS(ext-local,${EXTEN},1)}?local:external)
same  => n(local),Answer
same  => n,Wait(0.5)
same  => n,Set(SPY_CHAN=SIP/${EXTEN})
same  => n,Set(SPY_OPTS=qe(SIP/${EXTEN}))
same  => n,ChanSpy(${SPY_CHAN},${SPY_OPTS})
same  => n,Goto(end)
same  => n(external),GotoIf($[«${SIP_HEADER(X-Asterisk-ChanSpy)}» != «»]?end)
same  => n,SIPAddHeader(X-Asterisk-ChanSpy:spy)
same  => n,Gosub(sub-dial-to-dundi,s,1(${EXTEN}))
same  => n(end),Hangup

[ext-chanspy-whisper]
exten => _X.,1,GotoIf(${DIALPLAN_EXISTS(ext-local,${EXTEN},1)}?local:external)
same  => n(local),Answer
same  => n,Wait(0.5)
same  => n,Set(SPY_CHAN=SIP/${EXTEN})
same  => n,Set(SPY_OPTS=wqe(SIP/${EXTEN}))
same  => n,ChanSpy(${SPY_CHAN},${SPY_OPTS})
same  => n,Goto(end)
same  => n(external),GotoIf($[«${SIP_HEADER(X-Asterisk-ChanSpy)}» != «»]?end)
same  => n,SIPAddHeader(X-Asterisk-ChanSpy:whisper)
same  => n,Gosub(sub-dial-to-dundi,s,1(${EXTEN}))
same  => n(end),Hangup

Разграничение доступа к прослушке выходит за рамки данной статьи, поэтому просто предположим, что на прослушку и суфлирование ведут сервисные коды *61 и *62:

exten => _*61X.,1,Goto(ext-chanspy-spy,${EXTEN:3},1)
exten => _*62X.,1,Goto(ext-chanspy-whisper,${EXTEN:3},1)

Как Вы заметили, при звонке на другой сервер добавляется SIP-заголовок X-Asterisk-ChanSpy, нужно написать его обработчик в контексте, в который приходят вызовы от других серверов, т.е. from-pbxs. Для этого придётся поменять структуру from-pbxs, что будет полезно и в дальнейшем, если Вам понадобится обрабатывать ещё какие-либо кастомные заголовки:

[from-pbxs]
exten => _*.,1,Goto(from-pbxs-post,${EXTEN},1)
exten => _X.,1,GotoIf($[«${SIP_HEADER(X-Asterisk-ChanSpy)}» != «»]?chanspy:normal)
same  => n(chanspy),GotoIf($[«${SIP_HEADER(X-Asterisk-ChanSpy)}» = «spy»]?ext-chanspy-spy,${EXTEN},1)
same  => n,GotoIf($[«${SIP_HEADER(X-Asterisk-ChanSpy)}» = «whisper»]?ext-chanspy-whisper,${EXTEN},1)
same  => n,Hangup
same  => n(normal),Goto(from-pbxs-post,${EXTEN},1)

[from-pbxs-post]
include => ext-findmefollow
include => ext-local
include => from-pbxs-queue-pause

ВНИМАНИЕ: т.к. экстеншены доступные на сервере теперь описаны не в контексте from-pbxs, а в контексте from-pbxs-post, нужно во всех маппингах в файле /etc/asterisk/dundi.conf указать from-pbxs-post вместо from-pbxs, затем применить настройки DUNDi. Напоминаю, что все описанные изменения нужно производить на всех серверах, соединённых по DUNDi.Готово, прослушка теперь тоже должна работать между серверами.

Инструменты Linux для диагностики.png

Подписаться
Уведомить о
guest
0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

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

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

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


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

10 доводов в пользу Asterisk

Распространяется бесплатно.

Asterisk – программное обеспечение с открытым исходным кодом, распространяется по лицензии GPL. Следовательно, установив один раз Asterisk вам не придется дополнительно платить за новых абонентов, подключение новых транков, расширение функционала и прочие лицензии. Это приближает стоимость владения станцией к нулю.

Безопасен в использовании.

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

Надежен в эксплуатации.

Время работы серверов некоторых наших клиентов исчисляется годами. Это значит, что Asterisk работает несколько лет, ему не требуются никакие перезагрузки или принудительные отключения. А еще это говорит о том, что в районе отличная ситуация с электроэнергией, но это уже не заслуга Asterisk.

Гибкий в настройке.

Зачастую возможности Asterisk ограничивает только фантазия пользователя. Ни один конструктор шаблонов не сравнится с Asterisk по гибкости настройки. Это позволяет решать с помощью Asterisk любые бизнес задачи, даже те, в которых выбор в его пользу не кажется изначально очевидным.

Имеет огромный функционал.

Во многом именно Asterisk показал какой должна быть современная телефонная станция. За многие годы развития функциональность Asterisk расширилась, а все основные возможности по-прежнему доступны бесплатно сразу после установки.

Интегрируется с любыми системами.

То, что Asterisk не умеет сам, он позволяет реализовать за счет интеграции. Это могут быть интеграции с коммерческими телефонными станциями, CRM, ERP системами, биллингом, сервисами колл-трекинга, колл-бэка и модулями статистики и аналитики.

Позволяет телефонизировать офис за считанные часы.

В нашей практике были проекты, реализованные за один рабочий день. Это значит, что утром к нам обращался клиент, а уже через несколько часов он пользовался новой IP-АТС. Безусловно, такая скорость редкость, ведь АТС – инструмент зарабатывания денег для многих компаний и спешка во внедрении не уместна. Но в случае острой необходимости Asterisk готов к быстрому старту.

Отличная масштабируемость.

Очень утомительно постоянно возвращаться к одному и тому же вопросу. Такое часто бывает в случае некачественного исполнения работ или выбора заведомо неподходящего бизнес-решения. С Asterisk точно не будет такой проблемы! Телефонная станция, построенная на Asterisk может быть масштабируема до немыслимых размеров. Главное – правильно подобрать оборудование.

Повышает управляемость бизнеса.

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

Снижает расходы на связь.

Связь между внутренними абонентами IP-АТС бесплатна всегда, независимо от их географического расположения. Также к Asterisk можно подключить любых операторов телефонии, в том числе GSM сим-карты и настроить маршрутизацию вызовов по наиболее выгодному тарифу. Всё это позволяет экономить с первых минут пользования станцией.