Выполнение сервисных кодов на всех серверах Asterisk, соединённых с помощью DUNDi
Настройка DUNDi между серверами Asterisk — полдела, после этого часто встаёт вопрос о работе сервисных кодов между серверами Asterisk. В данной статье будут приведены необходимые настройки на примере двух функций, вызываемых сервисными кодами — пауза в очередях и прослушка с помощью ChanSpy.
Настройку 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.Готово, прослушка теперь тоже должна работать между серверами.
Остались вопросы?
Я - Першин Артём, менеджер компании Voxlink. Хотите уточнить детали или готовы оставить заявку? Укажите номер телефона, я перезвоню в течение 3-х секунд.
категории
- DECT
- Linux
- Вспомогательный софт при работе с Asterisk
- Интеграция с CRM и другими системами
- Интеграция с другими АТС
- Использование Elastix
- Использование FreePBX
- Книга
- Мониторинг и траблшутинг
- Настройка Asterisk
- Настройка IP-телефонов
- Настройка VoIP-оборудования
- Новости и Статьи
- Подключение операторов связи
- Разработка под Asterisk
- Установка Asterisk
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 сим-карты и настроить маршрутизацию вызовов по наиболее выгодному тарифу. Всё это позволяет экономить с первых минут пользования станцией.