Курсы по использованию Asterisk

IP-телефония — технология будущего. Обучитесь работе с IP-АТС Asterisk для того чтобы внедрить и профессионально использовать при решении коммуникационных задач.

Работайте с Asterisk профессионально!

Многоуровневая защита IP-АТС Asterisk

Телефонные станции очень часто становятся объектами хакерских атак. Узнайте, каким образом необходимо строить многоуровневую защиту для Вашей IP-АТС.

Не оставьте хакерам шансов. Защитите свой Asterisk от атак.

Используйте Веб-Интерфейс для удобства настройки

Панель управление FreePBX позволяет легко и удобно управлять всей системой. Научитесь эффективно использовать FreePBX для решения своих задач.

Управление станцией и статистика в окне браузера.

Научитесь работать с Asterisk из консоли

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

Научитесь «тонкой» настройке Asterisk

Цель курсов - максимум практики.

Обучение нацелено на практическую работу с IP-оборудованием: платы потоков E1, VoIP-телефонные аппараты, голосовые шлюзы FXS и прочее.

Обучение на реальном оборудовании — залог успеха.

Эффективное использование сервисных кодов перевода вызова в Asterisk

База знаний Настройка Asterisk
Многие знают о существовании в Asterisk сервисных кодов для управляемого и неуправляемого перевода вызова, далеко не все знают особенности их настройки. В этой статье будет описана настройка сервисных кодов для эффективного использования перевода вызова.

Настройка параметров сервисных кодов Asterisk

Настройки сервисных кодов Asterisk находятся в файле features.conf, по умолчанию, сервисные коды следующие:
управляемый перевод - не задан
неуправляемый перевод - #
отбой вызова - *

Как видите, управляемым переводом вообще нельзя пользоваться по умолчанию. Вносим в раздел [featuremap] файла features.conf:

[featuremap]
atxfer=*
blindxfer=##
disconnect=**

Для применения изменений в файле features.conf, нужно выполнить команду в CLI Asterisk «features reload»:

asterisk -rx "features reload"

Теперь имеем следующие сервисные коды:
управляемый перевод - *
неуправляемый перевод - ##
отбой вызова - **

Схожесть кодов управляемого перевода и отбоя вызова не является проблемой, т.к. в описываемой схеме эти коды никогда не будут доступны пользователю одновременно.
В разделе файла features.conf [general] указываются различные параметы сервисных кодов, обратите внимание на следующие:
featuredigittimeout - максимальная задержка между вводом символов при наборе сервисных кодов в миллисекундах. Значение по умолчанию - 1000, т.е. 1 секунда. Для ввода сервисных кодов, предлагаемых в этой статье, секунды должно хватить. Для ввода более сложных сервисных кодов пользователям может периодически не хватать времени, поэтому рекомендуется увеличить значение этого параметра до 2000.
transferdigittimeout - максимальная задержка в секундах между вводом символов при наборе номера адресата перевода. Значение по умолчанию - 3. Для более комфортного ввода номера, нужно увеличить это время до 4-5 секунд.
Atxferdropcall - при значении по умолчанию «no», если при упарвляемом переводе переводящий кладёт трубку не дожидаясь ответа адресата перевода и адресат перевода так и не принимает вызов до достижения таймаута вызова (значение параметраatxfernoanswertimeout), Asterisk попытается вернуть вызов переводящему. Asterisk может пытаться вызвать переводящего определённое количество раз (значение параметра atxfercallbackretries) с определённым интервалом (значение параметра atxferloopdelay). Если установить значение параметра atxferdropcall равным «yes», то Asterisk не будет пытаться вернуть вызов переводящему после неудачного управляемого перевода. Нужно установить значение «yes», если обработака вызова после неудачного перевода вызова реализована средствами диалплана.
ПРИМЕЧАНИЕ: Стандартный механизм возврата вызова после неудачного управляемого перевода не очень хорош, т.к. он не проверяет, свободен ли абонент, на которого должен вернуться вызов, не позволяет выполнять диалплан и не имеет возможности перевести вызов кому-либо другому, если абонент, совершивший перевод, не берёт трубку. Рекомендуется использовать вместо этого возврат вызова, реализованный средствами диалплана.

Для примеров, приведённых в этой статье, использовались следующие значения параметров в разделе [general] файла features.conf:

[general]
featuredigittimeout = 2000
atxferdropcall = yes
transferdigittimeout => 4

Написание диалплана Asterisk для обработки перевода вызовов

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

[global]
TRANSFER_CONTEXT=transfer
DIAL_OPTS=Tt
DIAL_TIME=20
OUT_DIAL_OPTS=T
OUT_DIAL_TIME=180
Q_OPTS=t
DEF_PROV_CID=78888888888
PROV1_CID=71111111111
PROV2_CID=72222222222
TRANSFER_FAILOVER=queues,600,1
[sub-mixmonitor]
exten => s,1,GotoIf($["${RECORDING_STARTED}" = "true"]?end)
same => n,Set(__RECORDING_FNAME=${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)}-${ARG1}-${CALLERID(num)}-${UNIQUEID}.wav)
same => n,Set(__RECORDING_STARTED=true)
same => n,MixMonitor(${RECORDING_FNAME},ab)
same => n,Set(AUDIOHOOK_INHERIT(MixMonitor)=yes)
same => n(end),Return
[local]
exten => _XXX,1,Gosub(sub-mixmonitor,s,1(${EXTEN}))
same => n,Dial(SIP/${EXTEN},${DIAL_TIME},${DIAL_OPTS})
same => n,ExecIf($["${THIS_IS_TRANSFER}" = "true"]?Return)
same => n,Hangup
exten => _XXX,hint,SIP/${EXTEN}
[queues]
exten => 600,1,Set(__PREVIOUS_QUEUE=${EXTEN})
same => n,Queue(reception,${Q_OPTS},,,600)
same => n,Hangup
exten => 601,1,Set(__PREVIOUS_QUEUE=${EXTEN})
same => n,Queue(sales,${Q_OPTS},,,600)
same => n,Hangup
[internal-default]
include => local
include => queues
exten => _8[2-689]XXXXXXXXX,1,Gosub(sub-mixmonitor,s,1(${EXTEN}))
same => n,Set(CALLERID(num)=${DEF_PROV_CID})
same => n,Set(CALLERID(name)=)
same => n,Dial(SIP/def_prov/${EXTEN},${OUT_DIAL_TIME},${OUT_DIAL_OPTS})
same => n,ExecIf($["${THIS_IS_TRANSFER}" = "true"]?Return)
same => n,Hangup
[from-10X]
include => local
include => queues
exten => _8[2-689]XXXXXXXXX,1,Gosub(sub-mixmonitor,s,1(${EXTEN}))
same => n,Set(CALLERID(num)=${PROV1_CID})
same => n,Set(CALLERID(name)=)
same => n,Dial(SIP/prov1/${EXTEN},${OUT_DIAL_TIME},${OUT_DIAL_OPTS})
same => n,ExecIf($["${THIS_IS_TRANSFER}" = "true"]?Return)
same => n,Hangup
[from-110]
include => local
include => queues
exten => _8[2-689]XXXXXXXXX,1,Gosub(sub-mixmonitor,s,1(${EXTEN}))
same => n,Set(CALLERID(num)=${PROV2_CID})
same => n,Set(CALLERID(name)=)
same => n,Dial(SIP/prov2/${EXTEN},${OUT_DIAL_TIME},${OUT_DIAL_OPTS})
same => n,ExecIf($["${THIS_IS_TRANSFER}" = "true"]?Return)
same => n,Hangup
exten => _810Z.,1,Gosub(sub-mixmonitor,s,1(${EXTEN}))
same => n,Set(CALLERID(num)=${PROV2_CID})
same => n,Set(CALLERID(name)=)
same => n,Dial(SIP/prov2/${EXTEN},${OUT_DIAL_TIME},${OUT_DIAL_OPTS})
same => n,ExecIf($["${THIS_IS_TRANSFER}" = "true"]?Return)
same => n,Hangup
[from-trunk]
exten => 78888888888,1,Set(CDR(did)=${EXTEN})
same => n,ExecIf($["${CALLERID(name)}" = ""]?Set(CALLERID(name)=${CALLERID(num)}))
same => n,Goto(queues,600,1)
exten => 71111111111,1,Set(CDR(did)=${EXTEN})
same => n,ExecIf($["${CALLERID(name)}" = ""]?Set(CALLERID(name)=${CALLERID(num)}))
same => n,Goto(queues,601,1)
exten => 72222222222,1,Set(CDR(did)=${EXTEN})
same => n,ExecIf($["${CALLERID(name)}" = ""]?Set(CALLERID(name)=${CALLERID(num)}))
same => n,Goto(local,110,1)

Пояснения к диалплану:
- вызовы пользователей 100-109 совершаются в контексте from-10X
- вызовы пользователя 110 совершаются в контексте from-110
- вызовы остальных пользователей совершаются в контексте internal-default
- входящие вызовы приходят в контекст from-trunk
- номер очереди сохраняется в переменную PREVIOUS_QUEUE перед входом в очередь - после вызова MixMonitor вызывается функция AUDIOHOOK_INHERIT, это нужно для того, чтобы запись продолжалась после перевода вызова

Для того, чтобы абоненты могли использовать сервисные коды перевода вызова, приложения, осуществляющие вызовы абонентов, должны использоваться с опциями разрешающими использование сервисных кодов для перевода вызова. В приведённом диалплане приложения Dial и Queue используются с опциями t и/или T.
Опция t позволяет вызываемой стороне перевести вызов с помощью сервисного кода.
Опция T позволяет вызывающей стороне перевести вызов с помощью сервисного кода.
Если не указать хотя бы одну из этих опций, сервисные коды перевода вызова не будут работать ни для одной из сторон вызова.

Обратите внимание на то, что исходящие вызовы пользователей 100-109 и 110 осуществляются через различных провайдеров, к тому же, пользователю 110 разрешены международные вызовы, а всем остальным пользователям - нет, эти условия должны быть соблюдены при переводе вызова.

Теперь нужно написать диалплан, который будет осуществлять сам перевод. По умолчанию перевод набирает введённый номер адресата в текущем контексте. Чтобы изменить это поведение, нужно установить значение переменной TRANSFER_CONTEXT, перевод будет выполняться в контексте имя которого указано в переменной TRANSFER_CONTEXT. Можно добавить эту переменную в раздел [globals] файла extensions.conf, тогда переменная TRANSFER_CONTEXT будет автоматически устанавливаться на каждом новом канале (в приведённом диалплане это уже сделано).
Ниже приведён сам контекст transfer, используемый для перевода вызовов:

[transfer]
exten => _X.,1,Set(DIAL_OPTS=${DIAL_OPTS}Hg)
same => n,Set(OUT_DIAL_OPTS=${OUT_DIAL_OPTS}Hg)
same => n,Set(Q_OPTS=${Q_OPTS}H)
same => n,Set(OUT_DIAL_TIME=45)
same => n,Set(TRANSFER_TO=${EXTEN})
same => n,Set(TRANSFERER=${CALLERID(num)})
same => n,GotoIf($["${BLINDTRANSFER}" = ""]?after_blindxfer_check)
same => n,Set(BL_TRANSFERER=${CUT(BLINDTRANSFER,-,1)})
same => n,Set(FIELDNUM=${FIELDQTY(BL_TRANSFERER,/)})
same => n,Set(BL_TRANSFERER=${CUT(BL_TRANSFERER,/,${FIELDNUM})})
same => n,ExecIf($["${BL_TRANSFERER}" != ""]?Set(TRANSFERER=${BL_TRANSFERER}))
same => n(after_blindxfer_check),NoOp(transferer: ${TRANSFERER})
same => n,GotoIf(${DIALPLAN_EXISTS(queues,${TRANSFER_TO},1)}?queues,${TRANSFER_TO},1)
same => n,Set(TR_CONT=${SIPPEER(${TRANSFERER},context)})
same => n,ExecIf($["${TR_CONT}" = ""]?Set(TR_CONT=internal-default))
same => n,Set(THIS_IS_TRANSFER=true)
same => n,Set(DIALSTATUS=)
same => n,Gosub(${TR_CONT},${TRANSFER_TO},1)
same => n,ExecIf($["${DIALSTATUS}" = "ANSWER"]?Hangup)
same => n,Goto(failover)
exten => failover,1,Playback(call-will-be-forwarded)
same => n,ExecIf($["${REGEX("^XFER_FAIL:" ${CALLERID(name)})}" = "0"]?Set(CALLERID(name)=XFER_FAIL: ${CALLERID(name)}))
same => n,Set(DIALSTATUS=)
same => n,GosubIf($["${EXTENSION_STATE(${TRANSFERER}@local)}" != "NOT_INUSE"]?local,${TRANSFERER},1)
same => n,ExecIf($["${DIALSTATUS}" = "ANSWER"]?Hangup)
same => n,Set(THIS_IS_TRANSFER=)
same => n,GotoIf($["${PREVIOUS_QUEUE}" != ""]?queues,${PREVIOUS_QUEUE},1)
same => n,Goto(${TRANSFER_FAILOVER})

Вкратце, контекст выполняет следующее:
- К опциям приложений Dial и Queue добавляется опция H, она позволяет завершить вызов сервисным кодом (в случае приложения Queue, опция H позволяет завершить вызов нажатием *, поэтому сервисный код отбоя вызова должен начинаться со *, чтобы его ввод работал и для приложения Dial и для приложения Queue). Выполнение этого сервисного кода во время управляемого перевода вызова позволит отменить перевод и вернуть вызов себе. В остальное время сервисный код будет недоступен, что предотвратит отбой вызоова из-за случайного ввода этого кода.
- К опциям приложения Dial добавляется опция g, она нужна для того, чтобы выполнение диалплана продолжалось после завершения приложения Dial (кроме случая, когда уничтожается канал звонящего).
- Определяется номер переводящего (переменная TRANSFERER) и его контекст (переменная TR_CONT). Перевод осуществляется в контексте пользователя, выполняющего вызов.
- Если переведённый вызов не был принят, проигрывается сообщение о том, что вызов будет переведён. Если переводящий всё ещё на линии, он поймёт, что перевод не удался и сможет вернуть вызов сервисным кодом.
- К CALLERID(name) добавляется префикс «XFER_FAIL: », чтобы пользователи видели, что это возврат после неудачного перевода.
- Если номер переводящего свободен, то производится попытка возврата вызова на номер переводящего.
- Если переводящий занят или не принял вызов, то вызов возвращается в последнюю очередь, в которую он входил.
- Если вызов ещё не был в очереди, он переводится на назначение по умолчанию (значение переменной TRANSFER_FAILOVER), в данном случае - очередь reception.

В результате, перевод вызова осуществляется следующим образом:
неуправляемый перевод - во время разговора нужно набрать сервисный код ##, ввести номер адресата перевода и нажать # или подождать 4 секунды.
управляемый перевод - во время разговора нужно нажать *, ввести номер адресата перевода и нажать # или подождать 4 секунды. Если адресат перевода не принимает вызов, можно ввести сервисный код ** для отмены перевода и возврата вызова себе. Также можно положить трубку не дожидаясь ответа адресата, если он не ответит, вызов вернётся к переводящему или в очередь, если переводящий занят/не доступен/не взял трубку.
Если сервисный код перевода вызова был введён случайно, для возврата вызова нужно просто нажать # без ввода номера.
Пользуйтесь таким переводом вызова и потери вызовов, связанные с неудачным переводом, будут сведены к минимуму.

asterisk, sip, настройка, коды, Time, call, callerid