понедельник, 12 мая 2014 г.

Голосового меню (IVR) в ASTERISK.



Опишем создание голосового меню, состоящего из приветствия и после приветствия, переключение на оператора. Файл в котором хранится фраза «Здравствуйте, вы позвонили в нашу компанию» называется welcome.wav и находится в директории /usr/local/etc/asterisk/ivr. Номер, который принимает звонки 444. А выглядеть меню будет так:

[sip-in]
exten => 444,1,Set(home="/usr/local/etc/asterisk/ivr")
exten => 444,2,Wait(1)
exten => 444,3,Playback(${home}/welcome)
exten => 444,4,Dial(SIP/operator)
Функция Playback, предназначена для проигрывания звуковых файлов, файлы должны быть подготовленны заранее, для Asterisk. Есть еще сходная функция Background, она отлдичается от Playback тем, что не блокирует нажатия на кнопки, то есть в момент проигрывания голосовых меню, позволяет реагировать на передаваемые звонившим DTMF.
Это простейший IVR и в нем отсутствует основная особенность IVR, нет никакого выбора. Поэтому приведем пример с диалогом. Тут будет присутствовать вторая начитка: «Для связи того что бы прослушать тарифы нажмите 1, для связи с оператором нажмите 2″. Файл содержащий эту начитку будет называться menu.wav и файл с тарифами соответсвенно tariff.wav. После прочтения инструкции должен осуществляться переход в главное меню.
Выглядит это так:
[sip-in]
exten => 444,1,Goto(menu,s,1)

[menu]
exten => s,1,Set(home="/ usr/local/etc/asterisk/ivr ")
exten => s,2,Wait(1)
exten => s,3,Playback(${home}/welcome)
exten => s,4,Playback(${home}/menu)
exten => s,5,WaitExten()

exten => 1,1,Playback(${home}/tariff)
exten => 1,2,Goto(s,1)

exten => 2,1,Dial(SIP/operator)

exten => t,1,Playback(make_choice)
exten => t,2,Goto(s,1)

exten => i,1,Playback(wrong_choice)
exten => i,2,Goto(s,1)
Goto – функция безусловного перехода. Если в качестве параметров ей передается 3 аргумента, это контекст, екстеншен и метка на которую нужно перейти. Если всего 2 аргумента, то подразумевается, что контекст текущий.
 i – это реакция на неправильно нажатую кнопку, Invalid input
t – реакция на истекшее время ожидания выбора.

Если их не описать то при истечении таймаута или при неправильно нажатой кнопке произойдет обрыв соединения.

четверг, 8 мая 2014 г.

Очереди звонков Asterisk

При телефонизации необходимость создания очереди звонков возникает достаточно часто. Например при наличии нескольких  менеджеров , руководитель хочет, что бы им на отдел поступали звонки и звонки равномерно распределялись по менеджерам, или что бы все звонки поступали ко всем сразу все это работает. Работает с помощью Queue.
С начала добавим в sip.conf наших менеджеров:
[111]
context=support
callerid="111" <111>
username=111
secret=*******
call-limit=1
callgroup=10
pickupgroup=15
dtmfmode=rfc2833
deny = 0.0.0.0/0.0.0.0
permit = 192.168.10.10/255.255.255.255

Теперь создадим очередь и добавим в конце описание нашей очереди. Описывается она в queues.conf:
[general]
persistentmembers = yes
autofill = yes

[queue1] ;Название нашей очереди
music = default ;Во время ожидания будет звучать музыка по умолчанию
strategy = ringall ;В очереди будут звонить все телефоны одновременно
timeout = 60
retry = 5
maxlen = 0
joinempty = yes ;разрешать входить в очередь даже в том случае, если все операторы не доступны
ringinuse = no

;Блок для анонса позиции в очереди
announce-frequency = 30 ;частота анонсов
announce-holdtime = no ;не объявлять приблизительное время ожидания
announce-position = limit ;если очередь слишком велика (более 6 вызовов), то
announce-position-limit = 6 ;информация о позиции выдаваться не будет, что бы
;не пугать пользователей

;Описываются пути к речевым файлам,
;которые используются для нашей простой очереди
queue-youarenext = /etc/asterisk/sounds/support/queue-youarenext
queue-thereare = /etc/asterisk/sounds/support/queue-thereare
queue-callswaiting = /etc/asterisk/sounds/support/queue-callswaiting
queue-thankyou = /etc/asterisk/sounds/support/queue-thankyou

;Описываем телефоны, которые будут принимать вызовы.
member=>SIP/111
member=>SIP/112
member=>SIP/113
member=>SIP/114

А теперь осталось направить входящие звонки на Queue. Для этого в extensions.conf, в том контексте в котором должны поступать звонки на очередь, прописываем:

exten => 101,1,Answer() 
exten => 101,n,Background(/etc/asterisk/sounds/support/ivr-techpodderzhka)
exten => 101,n,WaitExten(5)
exten => 101,n,Dial(${SIP/500,120,r)
exten => 1,1, Dial(${SIP/500,120,r)
exten => i,1, Dial(${SIP/501,120,r) ; если клиент набрал несуществующий номер пункта меню

exten => 2,1,Dial(SIP/111&SIP/112&SIP/113&SIP/114,r)
exten => 2,n,Playback(/etc/asterisk/sounds/support/queue-vsezanyaty)
exten => 2,n,Queue(queue1,t,,,300) 

среда, 7 мая 2014 г.

sip.conf

Перенаправление звонков


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

admin@asterisk:~$ echo > /etc/asterisk/followme.conf
admin@asterisk:~$ ee /etc/asterisk/followme.conf
[101]
number=>89161111111,30
number=>89122222222,30
context=>default
[102]
number=>89111111111,30
number=>89222222222,30
context=>default

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

Давайте добавим вызов приложения FollowMe в конец обработки вызова
трехзначных номеров в файле, описывающем план звонков:

admin@asterisk:~$ ee /etc/asterisk/extensions.conf

;...
exten => _1XX,1,Dial(SIP/${EXTEN},10)
 same => n,FollowMe(${EXTEN})
;...

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

вызывающим абонентом.

Cтандартные расширения диалплана


a: Вызывается, когда пользователь нажимает '*' во время проигрывания приветствия системы голосовой почты.
h: Вызывается, по завершению вызова.
i: Вызывается, при попытке вызова неизвестного екстеншена.
o: Расширение оператора, используется для обработки нажатия нуля в системе голосовой почты.
s: Стартовое расширение в контексте.
t: Вызывается, при наступлении состояния таймаута.
T: Вызывается, при наступлении состояния абсолютного таймаута, заданного функцией AbsolutTimeout.
e: Перехват расширений i,t и T для обработки ошибки в едином месте. Для выяснения типа ошибки может быть использована функция EXCEPTION()
failed: Используется, если auto-dial out вызов завершился неудачно (который имеет определённый контекст, приоритет и расширение).
fax: Используется для определения факса на Zap каналах.

talk: Используется в конъюнкции с BackgroundDetect.

Команды Goto и GotoIf в диалплане

Goto
Назначение
Переход на указанный приоритет, екстеншен или контекст

Описание
Goto([[context|]extension|]priority)

Устанавливает текущей приоритет выполнения команды в заданное значение, дополнительно можно указать екстеншен и контекст для совершения перехода. Специальное имя екстеншена BYEXTENSION используется в тех случаях, когда Вы хотите совершить переход с использованием текущего имени екстеншена, в другой контекст. Обратите внимание, что можно опустить необязательные параметры команды только в КОНЦЕ списка аргументов, нельзя опустить необязательный аргумент, идущий до или между заданными параметрами.

Варианты использования:
Goto(context,extension,priority)
Goto(extension,priority)
Goto(priority)

Примеры:
exten => 1,1,Goto(submenu,s,1) ; переход в контекст "submenu", на екстеншен "s", к команде с приоритетом 1
exten => 600,4,Goto(s,6) ; переход в текущем контексте, к екстеншену "s", к команде с приоритетом 6

exten => s,1,Dial(${ARG2},20,r)
exten => s,2,Goto(s-${DIALSTATUS},1)
exten => s-NOANSWER,1,Voicemail(u${ARG1})
exten => s-CHANUNAVAIL,1,Voicemail(b${ARG1})
exten => s-BUSY,1,Voicemail(b${ARG1})
exten => _s-.,1,Voicemail(u${ARG1})
Команда GotoIf()

Назначение
Переход по условию

GotoIf
Описание
GotoIf(condition?label1[:label2])

Переход к команде label1, если условие condition истина, или выполнение следующей, по приоритету, команды (или, если определено, переход к команде label2) если условие condition ложно, или:

GotoIf(condition?[label1]:label2)

Выполнение следующей, по приоритету, команды (или команды label1, если определено) если условие condition истина, или переход к команде label2, если условие condition ложно.

Параметры label1 или label2 могут быть опущены (в этом случае, ветвление возможно только по одному из условий). Отсутствие обоих точек перехода не допускается.

Условие condition - это текстовая строка. Если строка пустая или содержит "0", то условие будет считаться ложью. Если она содержит что-то другое, то условие будет истиной. Это сделано для совместимости с механизмом регулярных выражений, используемых в Asterisk.

Метка перехода задается в виде '[[контекст,]екстеншен,]приоритет. Итак, для нее мы можем задать следующие комбинации: (a) только приоритет, (b) екстеншен и приоритет, или (c) контекст, екстеншен и приоритет. Этот формат такой же, как и формат аргумента команды Goto.

Пример 1
  exten => 206,1,GotoIf($["${CALLERIDNUM}" = "303"]?3:2)
  exten => 206,2,GotoIf($["${CALLERIDNUM}" = "304"]?5:7)
  exten => 206,3,Dial(${SPHONE1},15,rt)
  exten => 206,4,Hangup
  exten => 206,5,Dial(${PHONE2},15,rt)
  exten => 206,6,Hangup
  exten => 206,7,MusicOnHold(default)

Пример 2
 ; Надо определить, являются ли первые три символа, полученного значения в переменной
; ${ENUM}, значениями SIP или IAX. Если нет, игнорируем эту переменную и переходим к
; приоритету 4, где осуществляем стандартный набор номера
 exten => _011X.,2,GotoIf($[$["${ENUM:0:3}" = "SIP"] | $["${ENUM:0:3}" = "IAX"]]?3:4)



Пример 3
  ; Этот пример проверяет на пустое значение callerID или на номер 800 серии.
  ; Вызывающим абонентам с номерами на 800 (обычно "telemarketers") или
  ; те, у которых не представлено caller ID, будет предложено нажать 1 для разговора.
  exten => s,1,NoOp(${CALLERID}) ; просто смотрим на callerID
  ; проверяем callerID. Если не задан, предлагаем абоненту нажать 1.
  exten => s,2,GotoIf($["${CALLERIDNUM}" = ""]?s|1000)
  ; Если номер начинается на 800, предлагаем абоненту нажать 1.
  exten => s,3,GotoIf($["${CALLERIDNUM:0:3}" = "877"]?s|1000)
  exten => s,4,GotoIf($["${CALLERIDNUM:0:3}" = "800"]?s|1000)
  ; OK, тут у нас нормальный callerID и точно не номер из 800 серии.
  ; Теперь вызываем нужный нам телефон:
  exten => s,5,Dial(SIP/604&SIP/602,25,tr)

  exten => s,1000,Background(press1tospeaktome)

взято с http://asterisk.ru/

Команды плана набора IP АТС Asterisk

Команды плана набора IP АТС Asterisk



Использование команды Dial

Использование команды Dial для SIP каналов

Формат команды Dial выглядит примерно так:

Dial(type/identifier,timeout,options,URL)

Для каналов SIP, параметр type всегда имеет значение - SIP. Остальные аргумент: timeout, options и URL описаны на странице описания команды Dial.

Параметр identifier может состоять из следующих трех частей:

[ exten@]peer [ :portno]

peer: имя вызываемого клиента. Это может быть одним из следующих значений:
клиент типа "peer" или "friend", который описан в файле sip.conf.
IP адрес (типа 192.168.1.8)
имя домена (например: asterisk.org).
exten: если задан этот параметр, тогда Asterisk будет запрашивать удаленный сервер соединение с екстеншеном exten.
portno: используемый UDP порт. Если не указан, Asterisk будет использовать стандартный SIP порт - 5060.
exten: если задан этот параметр, тогда Asterisk будет запрашивать удаленный сервер соединение с екстеншеном exten.

exten => s,1,Dial(SIP/ipphone)
; Вызов SIP клиента "ipphone", в соответствии с его параметрами в файле sip.conf
exten => s,1,Dial(SIP/john@foo.com)
; Вызвать абонента "john" на сервере foo.com
exten => s,1,Dial(SIP/192.168.1.8:9999,20)
; Отправить вызов на адрес 192.168.1.8 по порту 9999, с таймаутом ожидания - 20 секунд.
exten => s,1,Dial(SIP/8500@sip.com:9876)

; Соединиться с sip.com по порту 9876, запросить соединение с екстеншеном 8500.

Заметки по диалплану(extensions.conf)

В файле extensions.conf имя екстеншена является шаблоном, если оно начинается с символа подчеркивания (_).
В именах шаблонных екстеншенов, следующие символы имеют специальное значение и трактуются особым образом:
X соответствует любому числу от 0 до 9
Z соответствует любому числу от 1 до 9
N соответствует любому числу от 2 до 9
[1237-9] соответствует любому числу или диапазону чисел, которые заключены в квадратные скобки (в данном случае: 1,2,3,7,8,9)
. специальный символ, соответствует одному или более символов (не только цифрам)
! специальный символ, соответствует отсутствию, одному или более символов (не только цифрам)

В Asterisk существуют глобальные и специфичные для каналов переменные, используемые в качестве аргументов для команд. Переменные записываются в диалплане в виде ${foo}, где 'foo' это имя переменной. Имена должны начинаться с буквы и могут состоять из любых цифр и букв, но существуют предопределенные имена, вот некоторые из них:
${CONTEXT} Текущий контекст. 
${EXTEN} Текущий екстеншен. 
${EXTEN:x} Текущий екстеншен с удалением первых цифр(где х кол-во удаляемых цифр) 
${PRIORITY} Текущий приоритет 
${CALLERID} Текущий CallerID (имя и номер) 
${CALLERIDNUM} Текущий номер Caller ID 
${CALLERIDNAME} Текущее имя Caller ID 
${RDNIS} перенаправление DNIS 

В правилах можно использовать X – цифры от 0 до 9, Z – цифры от 1 до 9, N – цифры от 2 до 9 или последовательности цифр в квадратных скобках. 
К примеру для маршрутизации на номер начинающийся на 80 и состоящий из 11 цифр подойдет такое правило:
exten => _80XXXXXXXXX,1,Dial(SIP/provider1)
Подчеркивание в начале правила означает, что правило представляет изх себя регулярное выражение.
Правило которое говорит маршрутизировать звонки из 7 цифр:
exten => XXXXXXX,1,Dial(SIP/provider1)
 [sip-in]
exten => 444,1,Goto(menu,s,1) 
[menu] 
exten => s,1,Set(home="/home/menu") 
exten => s,2,Wait(1)
exten => s,3,Playback(${home}/welcome)
exten => s,4,Playback(${home}/menu)
exten => s,5,WaitExten()
exten => 1,1,Playback(${home}/tariff)
exten => 1,2,Goto(s,1)
exten => 2,1,Dial(SIP/operator)
exten => t,1,Playback(make_choice)
exten => t,2,Goto(s,1)
exten => i,1,Playback(wrong_choice)

exten => i,2,Goto(s,1)
Goto – функция безусловного перехода. Если в качестве параметров ей передается 3 аргумента, это контекст, екстеншен и метка на которую нужно перейти. Если всего 2 аргумента, то подразумевается, что контекст текущий. Так же появились екстеншены i – это реакция на неправильно нажатую кнопку, Invalid input и t – реакция на истекшее время ожидания выбора. Если их не описать то при истечении таймаута или при неправильно нажатой кнопке произойдет обрыв соединения.

Безопасность Asterisk

Устанавливаем лимит звонков
В случае взлома, для уменьшения затрат, рекомендую установить лимит одновременных звонков для аккаунтов в 1, чтобы злоумышленник не мог одновременно звонить на много направлений и, тем самым, быстрее расходовать ваши деньги.
[100]
call-limit=1
Используем deny/permit для аккаунтов Обязательный момент! Указываем для всех аккаунтов, которые не подразумевают подключение из интернета следующие строки:
[100]
deny=0.0.0.0/0.0.0.0
permit=10.1.1.1/24
permit=10.1.2.1/24
Отключаем guest-звонки
Если у вас нет необходимости принимать звонки без регистрации, обязательно выключите следующую опцию в sip.conf:
allowguest=yes => allowguest=no ; Allow or reject guest calls (default is yes)
Отключаем оповещение о неверном пароле
Практически у всех существуют аккаунты asterisk вида 100, 200, 700 и т.п. По умолчанию астериск выдает одну ошибку о неверном пароле для существующего аккаунта и другую для несуществующего аккаунта. С помощью спец. софта для подбора паролей, злоумышленник может быстро перебрать все короткие номера и подбирать пароли только к существующим аккаунтам, которые ответили «неверный пароль». Чтобы препятствовать этому, меняем опцию в sip.conf:
alwaysauthreject = no => alwaysauthreject = yes
После такой настройки, астериск будет давать одинаковый отбой для любых неверных авторизаций.

взято с http://www.mahno.su/

вторник, 6 мая 2014 г.

Русификация Asterisk


«Речь» Asterisk, записана в звуковых файлах в каталоге /usr/share/asterisk/sounds/. Для каждого языка создается подкаталог с соответствующим именем en, fr, ru. Каталог ru и его файлы загрузим с сайта разработчиков Asterisk. Какой каталог использовать, определяет директива language в описании канала или в общей (general) секции конфигурации (например, language=ru). Кроме имени каталога, директива language заставляет Asterisk учитывать грамматические категории языка (например, один номер – одно сообщение). Почему-то в штатных архивах русских сообщений нет нескольких файлов, необходимых для воспроизведения грамматических вариаций произношения. Выход – «обман» Asterisk. Он будет «думать», что говорит на английском, а файлы будут содержать русские фразы. Для русификации Asterisk выполняем:
$ cd /usr/share/asterisk/sounds/en
$ wget http://downloads.asterisk.org/pub/telephony/sounds/asterisk-core-sounds-ru-alaw-current.tar.gz
$ tar -xvf asterisk-core-sounds-ru-alaw-current.tar.gz


взято с http://samag.ru/