Как настроить парковку вызова в Asterisk

Как настроить парковку вызова в Asterisk

Что такое парковка вызова?

Парковка вызовов – это способ перевести вызов в режим удержания, чтобы другой абонент группы мог получить вызов, если он знает, на какого абоненты поступил вызов. Естественная метафора, описывающая, как работает эта функция, – автостоянка. Фактически, многие варианты парковки вызовов используют терминологию парковки, например парковки и парковочные места, чтобы описать, что делают варианты.

У парковки было несколько воплощений, чтобы добавить функции на протяжении всей своей истории в Asterisk. В Asterisk 12 он получил еще один капитальный ремонт из-за серьезных архитектурных изменений в Asterisk. Функциональность парковки была извлечена из ядра Asterisk в загружаемый модуль res_parking.so. Приведенные ссылки относятся к Asterisk 13, но большая часть информации будет относиться к Asterisk 11 с некоторыми изменениями.

Глядя на кусочки

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

Если вы хотите, чтобы Asterisk управлял расширениями набора номеров, связанными с парковкой, вам необходимо рассмотреть следующие дополнительные параметры: context , parkext, parkext_exclusive и parkinghints. При настройке парковки для одного объекта вы должны включить сгенерированный контекст парковки в контекст вашей схемы набора номеров, чтобы вы могли парковать и получать вызовы, используя управляемые добавочные номера.

Есть три приложения, которые работают для реализации парковки вызовов. Два приложения размещают каналы на парковках, а одно извлекает их. Приложение Park помещает канал, на котором выполняется приложение, на парковку. Как и приложение Park, приложение ParkAndAnnounce также помещает канал, на котором выполняется приложение, на парковку. Приложение ParkedCall извлекает припаркованный канал на запрошенной парковке и месте.

Есть два основных различия между парком и парком и объявлением. Во-первых, отправляется звуковое объявление о том, где находится канал. Парк объявит каналу о парковке вызова. ParkAndAnnounce будет набирать анонсирующий канал. Когда анонсирующий канал отвечает, ParkAndAnnounce воспроизводит звуковое объявление и вешает трубку. Во-вторых, у Park есть специальная поддержка, чтобы справиться с ограничениями слепых передач, которые также могут повлиять на то, какая парковка используется.

Имя парковочной площадки, используемое для парковки или поиска канала, ищется в следующем порядке: 1) значение параметра парковки приложения, 2) значение переменной канала PARKINGLOT , 3) значение функции CHANNEL (парковочная площадка) и, наконец, 4) стоянка по умолчанию. То, как вы устанавливаете переменную канала PARKINGLOT или значение функции CHANNEL (парковочное место), зависит от вас и вашей абонентской группы. Самый простой способ – это установить драйвером канала значение по умолчанию при создании канала с помощью параметра varset или парковочного места, специфичного для конфигурации драйвера канала.

Вам может быть интересно, почему приложения Park и ParkAndAnnounce паркуют канал, на котором выполняется приложение, когда вы обычно хотите оставить человека, с которым разговариваете. Чтобы припарковать человека, с которым вы разговариваете, вы должны перенести его на парковку. Для трансфера, который вы посещаете, вы на самом деле оставляете себя, а затем отправляете другую сторону на парковку, чтобы занять ваше место. Для слепого перевода вы заставляете другую сторону парковаться самостоятельно.

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

Слепые трансферы имеют ограничения, когда дело доходит до парковки. Как правило, вы не можете получить звуковое объявление от Park о том, где на парковке припаркован вызов. Канал Parker больше не доступен для прослушивания объявления. Что еще хуже, вечеринка, на которой стоит парковка, имеет некоторый контроль над тем, на какую парковку они паркуются.

Приложение Park пытается обойти ограничения слепой передачи, пытаясь определить, переходите ли вы слепой на парковочный номер. Расширение парковки обнаруживается, если первым приоритетом расширения абонентской группы является приложение Park. Обнаруженное расширение парковки преобразует слепую передачу в передачу с псевдообслуживанием, которая завершает передачу после объявления. Приложение Park обычно не выполняется в процессе псевдообслуживания. Если добавочный номер парковки не обнаружен, у вас нет возможности узнать, где припаркован вызов, и вызов может быть припаркован на неожиданной парковке. Функция слепой передачи DTMF всегда может успешно использовать обходной путь. Метод слепой передачи технологии канала также использует обходной путь. Тем не мение, Технология канала может не дать вам услышать объявление о местоположении. Например, метод слепой передачи по протоколу SIP может не позволить вам услышать объявление о местоположении, поскольку телефоны SIP, возможно, уже отключили свой аудиопуть.

Примечание. Функция парковки одним касанием DTMF – это особый случай слепой передачи, и в настоящее время она ничего не сделает, если у вас нет Asterisk, управляющего расширениями диалплана для парковки.

Динамические парковки

Динамические парковки позволяют создавать новые парковки без перезагрузки конфигурации парковки. Чтобы использовать их, вы должны включить опцию parkeddynamic в глобальном разделе res_parking.conf .

Динамическая парковка создается, когда канал пытается получить доступ к неизвестной парковке. Новая парковка может использовать несколько переменных канала для определения новой парковки. Существует переменная канала , чтобы указать шаблон для стоянки автомобилей , чтобы использовать ( PARKINGDYNAMIC ), то parkext вариант ( PARKINGDYNEXTEN ), то parkpos вариант ( PARKINGDYNPOS ), а также место для парковки контекст опция ( PARKINGDYNCONTEXT ). Все эти переменные канала являются необязательными. Неуказанные и любые другие варианты парковки взяты из шаблона парковки. Однако управляемые добавочные номера новой парковки не могут перекрывать управляемые добавочные номера существующих парковок.

Положить кусочки вместе

Изучив парковку по частям, давайте применим эти знания, создав несколько вариантов парковки с несколькими местами для парковки.

Статическая настройка для организации

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

Сначала мы создадим конечные точки Алисы, Боба, Чарли, Дэвида и Эдди для демонстрационных вызовов. О, и мы также создадим конечную точку pa_system для демонстрации ParkAndAnnounce.

[transport-udp]
type=transport
bind=0.0.0.0
protocol=udp

[endpoint](!)
type=endpoint
allow=!all,ulaw
context=internal

[aor](!)
type=aor
max_contacts=1

[alice](endpoint)
aors=alice
[alice](aor)

[bob](endpoint)
aors=bob
[bob](aor)

[charlie](endpoint)
aors=charlie
set_var=CHANNEL(parkinglot)=custom_1
[charlie](aor)

[david](endpoint)
aors=david
set_var=CHANNEL(parkinglot)=custom_2
[david](aor)

[eddie](endpoint)
aors=eddie
set_var=CHANNEL(parkinglot)=custom_3
[eddie](aor)

; This endpoint needs to auto-answer, but for demonstration
; purposes you can manually answer it.
[pa_system](endpoint)
aors=pa_system
[pa_system](aor)

Теперь давайте создадим несколько статических парковок. Мы создадим три пользовательских парковки и парковку по умолчанию. Каждая автостоянка немного отличается, чтобы продемонстрировать, как ведут себя общие и эксклюзивные расширения доступа.

[general]

[lot](!)
context=parkedcalls
parkingtime=20
comebacktoorigin=no
comebackcontext=parking_timeout

[default](lot)
parkext=700
parkpos=701-702

[custom_1](lot)
; We can set parkext to 700 and share the default parking lot
; access extension because the access extension is general and
; can access any parking lot.
parkext=700
parkpos=711-712

[custom_2](lot)
parkext=720
parkpos=721-722
parkinghints=yes

[custom_3](lot)
parkext=730
parkext_exclusive=yes
parkpos=731-732

Теперь, чтобы создать план набора, поскольку Asterisk не очень хорош без него.

[internal]
exten=alice,1,NoOp()
same=n,Dial(PJSIP/alice,20,TK)
same=n,Hangup()

exten=bob,1,NoOp()
same=n,Dial(PJSIP/bob,20,tk)
same=n,Hangup()

exten=charlie,1,NoOp()
same=n,Dial(PJSIP/charlie,20,tk)
same=n,Hangup()

exten=david,1,NoOp()
same=n,Dial(PJSIP/david,20,tk)
same=n,Hangup()

exten=eddie,1,NoOp()
same=n,Dial(PJSIP/eddie,20,tk)
same=n,Hangup()

exten=740,1,NoOp()
same=n,ParkAndAnnounce(,,silence/1:call-waiting:letters/at:PARKED:auth-thankyou,PJSIP/pa_system)
same=n,Hangup()

include=parkedcalls

[parking_timeout]
exten=s,1,NoOp(Parked call channel that timed out: ${CHANNEL(name)})
same=n,Playback(vm-goodbye)
same=n,Hangup()

; The following dialplan context is what Asterisk generates
; according to the parking lots defined in res_parking.conf.
;[parkedcalls]
;exten=700,1,Park()
;exten=701,1,ParkedCall(default,701)
;exten=702,1,ParkedCall(default,702)
;
;exten=711,1,ParkedCall(custom_1,711)
;exten=712,1,ParkedCall(custom_1,712)
;
;exten=720,1,Park()
;exten=721,hint,park:721@parkedcalls
;exten=721,1,ParkedCall(custom_2,721)
;exten=722,hint,park:722@parkedcalls
;exten=722,1,ParkedCall(custom_2,722)
;
;exten=730,1,Park(custom_3)
;exten=731,1,ParkedCall(custom_3,731)
;exten=732,1,ParkedCall(custom_3,732)

Как настроить парковку вызова в AsteriskТеперь проиллюстрируем, как работают эти парковки. Все сценарии в основном одинаковы. Алиса позвонит кому-нибудь, кто осуществит посещение трансфера на расширение доступа к парковке, и оставит ее там до 20-секундного перерыва. В этот момент Алиса услышит «до свидания» и звонок будет прерван. Каждый сценарий показывает, что Алиса может быть припаркована на другой парковке в зависимости от того, кто ее паркует и какое расширение доступа используется. Пока Алиса припаркована, ее может получить любой, если он наберет номер парковочного места (701, 711, 721 или 731), который она в данный момент занимает.

Алиса называет Боба, Чарли, Дэвида или Эдди. Затем Алиса обслуживается и передается на номер 700, 720, 730 или 740 для доступа к парковке. В таблице ниже показано, куда входит Алиса.

 

        | 700 | 720 | 730 | 740
-------------------------------
bob     | 701 | 701 | 731 | 701
charlie | 711 | 711 | 731 | 711
david   | 721 | 721 | 731 | 721
eddie   | 731 | 731 | 731 | 731

Что следует отметить:

Передача Алисы на общее расширение доступа к парковке позволяет Алисе парковаться на разных парковках в зависимости от того, кто ее перевез.

Перенос алисы на 730 всегда паркует алису на парковке custom_3, потому что это расширение доступа для парковки предназначено исключительно для custom_3 .

Когда Алиса припаркована на стоянке custom_2, имеются подсказки, позволяющие следить за тем, находится ли кто-то на парковке.

Когда Алиса переводится в 740, где Алиса припаркована, ParkAndAnnounce объявляет через систему оповещения, когда она набирает PJSIP /pa_system.

Статическая настройка для мультитенанта

Эта конфигурация парковки более желательна для мультитенантной договоренности. У каждого арендатора есть своя собственная парковка, и они единственные, кто может получить свои припаркованные звонки.

Сначала мы создадим конечные точки Алисы, Боба, Чарли, Дэвида и Эдди для демонстрационных вызовов.

[transport-udp]
type=transport
bind=0.0.0.0
protocol=udp

[endpoint](!)
type=endpoint
allow=!all,ulaw
context=internal

[endpoint_tenant_1](!,endpoint)
set_var=CHANNEL(parkinglot)=tenant_1

[endpoint_tenant_2](!,endpoint)
set_var=CHANNEL(parkinglot)=tenant_2

[aor](!)
type=aor
max_contacts=1

[alice](endpoint)
aors=alice
[alice](aor)

[bob](endpoint_tenant_1)
aors=bob
[bob](aor)

[charlie](endpoint_tenant_1)
aors=charlie
[charlie](aor)

[david](endpoint_tenant_2)
aors=david
[david](aor)

[eddie](endpoint_tenant_2)
aors=eddie
[eddie](aor)

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

[general]
 
; Anyone getting parked here got here in error because they
; are in an unclaimed parking lot. We'll park them briefly
; and try to send them back to whoever parked them.
[default]
context=parkedcalls
parkext=700
parkpos=701
parkingtime=2
 
[lot](!)
parkext=700
; Make the parking access extension exclusive so one-touch
; parking will always go to this parking lot. Otherwise
; this access extension is not used.
parkext_exclusive=yes
parkpos=701-702
parkingtime=20
comebacktoorigin=no
comebackcontext=parking_timeout
 
[tenant_1](lot)
context=park_tenant_1
 
[tenant_2](lot)
context=park_tenant_2

Теперь, чтобы создать план набора, поскольку Asterisk не очень хорош без него.

[internal]
exten=alice,1,NoOp()
same=n,Dial(PJSIP/alice,20,TK)
same=n,Hangup()

exten=bob,1,NoOp()
same=n,Dial(PJSIP/bob,20,tk)
same=n,Hangup()

exten=charlie,1,NoOp()
same=n,Dial(PJSIP/charlie,20,tk)
same=n,Hangup()

; General parking access extension shared by all tenants.
exten=700,Park()
same=n,Hangup()

; General parking retrieval extensions shared by all tenants.
exten=_70[1-2],ParkedCall(,${EXTEN})
same=n,Hangup()

[parking_timeout]
exten=s,1,NoOp(Parked call channel that timed out: ${CHANNEL(name)})
same=n,Playback(vm-goodbye)
same=n,Hangup()

; The following dialplan context is what Asterisk generates
; according to the parking lots defined in res_parking.conf.
;[parkedcalls]
;exten=700,1,Park()
;exten=701,1,ParkedCall(default,701)
;
;[park_tenant_1]
;exten=700,1,Park(tenant_1)
;exten=701,1,ParkedCall(tenant_1,701)
;exten=702,1,ParkedCall(tenant_1,702)
;
;[park_tenant_2]
;exten=700,1,Park(tenant_2)
;exten=701,1,ParkedCall(tenant_2,701)
;exten=702,1,ParkedCall(tenant_2,702)

Теперь посмотрим, как работают эти изолированные стоянки для арендаторов. Если Алиса звонит Бобу, и он посещает переводит ее на номер 700, она попадает на парковку tenant_1 на парковочном месте 701. Только Алиса или Боб могут получить Алису, потому что их конечные точки настроены для доступа к парковке tenant_1 . Точно так же, если Алиса вызывает Дэвида, и он делает то же самое, то только Дэвид или Эдди могут получить Алису.

Динамическая настройка для мультитенанта

Это эквивалентно настройке «Статическая настройка для мультитенант» выше, но с использованием динамически создаваемых парковок. Нам просто нужно внести небольшие изменения в файлы конфигурации. Для pjsip.conf мы просто меняем определения шаблонов конечных точек для арендаторов. Для res_parking.conf мы включаем динамические парковки и заменяем статические парковки арендаторов на парковки, которые будут использоваться в качестве шаблона для динамических парковок арендаторов.

[transport-udp]
type=transport
bind=0.0.0.0
protocol=udp

[endpoint](!)
type=endpoint
allow=!all,ulaw
context=internal

[endpoint_tenant_base](!,endpoint)
set_var=__PARKINGDYNAMIC=tenant_template
set_var=__PARKINGDYNEXTEN=700

[endpoint_tenant_1](!,endpoint_tenant_base)
set_var=__PARKINGDYNCONTEXT=park_tenant_1
set_var=CHANNEL(parkinglot)=tenant_1

[endpoint_tenant_2](!,endpoint_tenant_base)
set_var=__PARKINGDYNCONTEXT=park_tenant_2
set_var=CHANNEL(parkinglot)=tenant_2

[aor](!)
type=aor
max_contacts=1

[alice](endpoint)
aors=alice
[alice](aor)

[bob](endpoint_tenant_1)
aors=bob
[bob](aor)

[charlie](endpoint_tenant_1)
aors=charlie
[charlie](aor)

[david](endpoint_tenant_2)
aors=david
[david](aor)

[eddie](endpoint_tenant_2)
aors=eddie
[eddie](aor)
[general]
parkeddynamic=yes

; Anyone getting parked here got here in error because they
; are in an unclaimed parking lot. We'll park them briefly
; and try to send them back to whoever parked them.
[default]
context=parkedcalls
parkext=700
parkpos=701
parkingtime=2

[tenant_template]
; We are intentionally not defining parkext to prevent
; creating unnecessary dialplan extensions for the parking
; lot. We are just using this parking lot as a template to
; create dynamic parking lots so we don't need the dialplan
; extensions. When a dynamic parking lot is created we will
; specify the parkext by setting the PARKINGDYNEXTEN channel
; variable.
;
; Make the parking access extension exclusive so one-touch
; parking will always go to this parking lot. Otherwise
; this access extension is not used.
parkext_exclusive=yes
parkpos=701-702
parkingtime=20
comebacktoorigin=no
comebackcontext=parking_timeout

План набора в extensions.conf такой же, как в примере «Статическая настройка для мультитенанта». Единственное отличие заключается в том, что места для парковки генерируются динамически при первом парковке на парковке, а не при загрузке res_parking.so.

Просто для удовольствия

Вы можете использовать Park для создания собственной очереди автоматического распределения вызовов. Вызывающие абоненты звонят и припарковываются на стоянке в очереди. Ваша внешняя программа очереди получает события парковки AMI о новых поступлениях и месте парковки, в которое они были помещены. Затем ваша программа очереди определяет, доступен ли агент для приема вызова, и использует действие источника AMI для вызова агента и выполнения приложения ParkedCall. чтобы найти абонента в очереди.