355 500 произведений, 25 200 авторов.

Электронная библиотека книг » Джим Меггелен » Asterisk™: будущее телефонии Второе издание » Текст книги (страница 14)
Asterisk™: будущее телефонии Второе издание
  • Текст добавлен: 7 октября 2016, 17:17

Текст книги "Asterisk™: будущее телефонии Второе издание"


Автор книги: Джим Меггелен


Соавторы: Джаред Смит,Лейф Мадсен

Жанр:

   

ОС и Сети


сообщить о нарушении

Текущая страница: 14 (всего у книги 41 страниц)

exten => 123,n,WaitExten(5)

И Background(), и WaitExten() позволяют абоненту производить набор номера. После этого Asterisk пытается найти в текущем контексте добавочный номер, соответствующий введенным абонентом цифрам. Если Asterisk находит однозначное соответствие, она направляет вызов на этот добавочный номер. Продемонстрируем это, добавив несколько строк в наш пример:

exten => 123,1,Answer()

exten => 123,n,Background(main-menu)

exten => 123,n,WaitExten()

exten => 2,1,Playback(digits/2)

exten => 3,1,Playback(digits/3)

exten => 4,1,Playback(digits/4) Если вызвать добавочный номер 123 из примера выше, он воспроизведет звуковое сообщение с фразой «main menu» (главное меню) и после этого будет ожидать ввода цифр 2, 3 или 4. Если нажать одну из этих цифр, Asterisk воспроизведет ее для вас. Также вы обнаружите, что, если ввести другую цифру (например, 5), Asterisk не обеспечит ожидаемого результата.

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

exten => 123,1,Answer()

exten => 123,n,Background(main-menu)

exten => 123,n,WaitExten()

exten => 1,1,Playback(digits/1)

exten => 2,1,Playback(digits/2)

exten => 3,1,Playback(digits/3)

exten => 4,1,Playback(digits/4) Наберите добавочный номер 123 и затем по подсказке главного меню введите 1. Почему Asterisk сразу же не воспроизводит этот номер? Потому, что цифра 1 неоднозначна; Asterisk не понимает, какой добавочный номер вызывается, 1 или 123. Он ожидает несколько секунд ввода другой цифры (например, 2 для вызова добавочного номера 123). Если набора никаких других цифр не последовало, по завершении времени ожидания Asterisk направляет вызов на добавочный номер 1. (Задавать собственные значения времени ожидания мы научимся в главе 6.) Прежде чем двигаться дальше, посмотрим, что было сделано на данный момент. Вызвав наш диалплан, абоненты услышат приветствие. Если они нажмут 1, то услышат номер 1, если 2 – то номер 2 и т. д. Для начала это неплохо, но давайте это все немного усовершенствуем. С помощью приложения Goto() (Перейти к) заставим диалплан повторять приветствие после воспроизведения номера.

Как следует из его имени, приложение Goto() используется для перенаправления вызова в другую часть диалплана. Синтаксис Goto() требует передачи в него в качестве аргументов целевого контекста, добавочного номера и приоритета:

exten => 123)n)Goto(к.онтек.ст,добавочныйномер,приоритет)

Теперь давайте применим приложение Goto() в нашем диалплане:

[incoming]

exten => 123,1,Answer()

exten => 123,n,Background(main-menu)

exten => 1,1,Playback(digits/1) exten => 1,n,Goto(incoming,123,1)

exten => 2,1,Playback(digits/2) exten => 2,n,Goto(incoming,123,1)

Две новые строки (выделенные курсивом) обеспечат возвращение управления над вызовом добавочному номеру 123 после воспроизведения выбранного номера.

Если вы внимательно посмотрите на приложение Goto(), то поймете, что в него на самом деле можно передавать один, два или три аргумента. Если передается только один аргумент, Asterisk предположит, что это основной приоритет текущего добавочного номера. Если передано два аргумента, Asterisk будет трактовать их как добавочный номер и приоритет, к которым надо перейти в текущем контексте. В данном примере были переданы все три аргумента для наглядности, но, если бы мы задали только добавочный номер и приоритет, результат был бы аналогичным.

Обработка ошибочных вводов и времени ожидания

Теперь, когда создание нашего первого голосового меню уже близится к завершению, введем специальные добавочные номера. Во-первых, нам необходим добавочный номер для недействительных вводов; когда абонент нажимает не ту кнопку (например, 9 для предыдущего примера), вызов направляется на добавочный номер i. Во-вторых, необходим добавочный номер для обработки ситуаций, когда абонент не производит ввод вовремя (время ожидания по умолчанию – 10 с). Если абонент слишком долго не нажимает кнопку после запуска приложения WaitExten(), вызовы направляются на добавочный номер t. Вот как будет выглядеть диалплан после введения этих двух добавочных номеров: [incoming]

exten => 123,1,Answer()

exten => 123,n,Background(enter-ext-of-person) exten => 123,n,WaitExten()


exten => 1,1,Playback(digits/1)1,1,Playback(digits/1)
exten => 1,n,Goto(incoming,123,1)
exten => 2,1,Playback(digits/2)
exten => 2,n,Goto(incoming,123,1)
exten => 3,1,Playback(digits/3)
exten => 3,n,Goto(incoming,123,1)
exten => i,1,Playback(pbx-invalid)
exten => i,n,Goto(incoming,123,1)
exten => t,1,Playback(vm-goodbye)
exten => t,n,Hangup()

Использование добавочных номеров i и t делает диалплан несколько более надежным и практичным. Но надо сказать, он по-прежнему довольно примитивен, потому что внешние абоненты не имеют возможности соединения с реальным живым человеком. Для этого нам придется ознакомиться с еще одним приложением – Dial() (Звонить).

Использование приложения Dial()

Одно из самых ценных свойств Asterisk – это возможность установления соединения между разными абонентами. Это особенно полезно, когда абоненты используют разные методы связи. Например, абонент А может звонить по традиционной аналоговой телефонной линии, тогда как пользователь В может сидеть в кафе в другой части света и говорить по IP-телефону. К счастью, большую часть тяжелой работы по установлению соединения и выполнению преобразований между разными сетями Asterisk берет на себя. От вас требуется лишь научиться использовать приложение Dial().

Синтаксис Dial() немного сложнее, чем синтаксис приложений, которые применялись до сих пор, но не пугайтесь. Dial() принимает четыре аргумента. Первый – получатель вызова. Он состоит (в самой простой форме) из названия технологии (или транспортного протокола), с помощью которой выполняется вызов, символа слэш и имени удаленной конечной точки или ресурса. Самыми широко используемыми типами технологий являются Zap (для аналоговых каналов и каналов T1/E1/ J1), SIP и IAX2. Например, допустим, требуется вызвать конечную точку Zap, определенную как Zap/1, которая представляет собой FXS– канал с подключенным к нему аналоговым телефоном. Технология – Zap, ресурс – 1. Аналогично, для вызова устройства SIP (описанного в sip.conf) получателем вызова может быть SIP/Jane, а для устройства IAX (описанного в iax.conf) – IAX2/Fred. Если бы потребовалось, чтобы при вызове добавочного номера 123 диалплана Asterisk звонил по каналу Zap/1, мы бы ввели следующий добавочный номер: exten => 123,1,Dial(Zap/1)

Также можно звонить по нескольким каналам одновременно, объединяя получателей вызова с помощью символа амперсанда (&):

exten => 123,1,Dial(Zap/1&Zap/2&SIP/Jane) Приложение Dial() будет дозваниваться всем заданным получателям вызовов одновременно и установит связь с любым из заданных каналов, который ответит первым. Если приложение не может связаться ни с одним вызываемым абонентом, Asterisk задаст переменной DIALSTATUS (статус звонка) значение, соответствующее ситуации невозможности дозвониться на вызываемые номера, и продолжит выполнение следующего приоритета добавочного номера1.

Приложение Dial() также позволяет устанавливать связь с удаленной конечной точкой VoIP, которая не была предварительно описана в конфигурационных файлах канала. Вот полный синтаксис такого типа соединения:

Dial(технология/пользователь[:пароль]@удаленный_хост[:порт][/удаленный_доба– вочный_номер])

В качестве примера можно позвонить на демонстрационный сервер Digium, который использует протокол IAX2, по следующему добавочному номеру:

exten => 500,1,Dial(IAX2/[email protected]/s)

Полный синтаксис приложения Dial() для звоноков по каналам Zap немного иной, как показано ниже:

Dial(Zap/[gGrR]канал_или_группа[/удаленный_добавочный_номер]) Например, вот как описывался бы вызов номера 1-800-555-1212 по Zap-каналу под номером 4.

exten => 501,1,Dial(Zap/4/18005551212) Второй аргумент приложения Dial() – время ожидания, задаваемое в секундах. Если время ожидания задано, Dial() будет пытаться дозвониться по заданным номерам в течение этого количества секунд, а потом перейдет к следующему приоритету добавочного номера. Если время ожидания не задано, Dial() будет дозваниваться на вызываемые каналы до тех пор, пока кто-нибудь не ответит или пока вызывающий абонент не повесит трубку. Введем для нашего добавочного номера время ожидания 10 с:

exten => 123,1,Dial(Zap/1,10) Если ответ на звонок получен до истечения времени ожидания, связь между каналами устанавливается и диалплан выполнен. Если вызываемый номер просто не отвечает, занят или недоступен по какой-то другой причине, Asterisk задаст переменную DIALSTATUS и перейдет к следующему приоритету добавочного номера.

Не беспокойтесь, позже мы рассмотрим переменные (в разделе «Использование переменных») и покажем, как заставить диалплан принимать решения на основании значения переменной DIALSTATUS.

Давайте применим то, что изучили на данный момент, в другом примере:

exten => 123,1,Dial(Zap/1,10)

exten => 123,n,Playback(vm-nobodyavail)

exten => 123,n,Hangup()

Как видите, этот пример будет воспроизводить звуковой файл vm– nobodyavail.gsm в случае, если звонок остается без ответа. Третий аргумент Dial() – строка опций. Она может содержать один или более символов, влияющих на поведение приложения Dial(). Список возможных опций слишком велик, чтобы приводить его здесь; рассмотрим лишь самую популярную из них – опцию m. Если указать m в качестве третьего аргумента, вызывающая сторона, пока выполняется дозвон до вызываемого абонента, будет слышать во время ожидания вместо гудков музыку (конечно, если эта музыка сконфигурирована правильно). Чтобы добавить опцию m в наш последний пример, просто изменим первую строку:

exten => 123,1,Dial(Zap/1,10,m) exten => 123,n,Playback(vm-nobodyavail) exten => 123,n,Hangup()

Теперь, когда мы научились использовать приложение Dial(), добавочные номера 1 и 2 в диалплане стали бесполезными. Давайте заменим их новыми добавочными номерами, которые позволят внешним абонентам дозваниваться до Джона (John) и Джейн (Jane):


[incoming]
exten =>123,1,Answer()
exten =>123,n,Background(enter-ext-of-person)
exten =>123,n,WaitExten()
exten => 1,1,Dial(Zap/1,10)
exten => 1,n,Playback(vm-nobodyavail)
exten => 1,n,Hangup()
exten => 2,1,Dial(SIP/Jane,10)
exten => 2,n,Playback(vm-nobodyavail)
exten => 2,n,Hangup()
exten =>i,1,Playback(pbx-invalid)
exten =>i,n,Goto(incoming,123,1)
exten =>t,1,Playback(vm-goodbye)
exten =>t,n,Hangup()

Четвертый и последний аргумент приложения Dial() – URL. Если вызываемый канал поддерживает прием URL в момент вызова, заданный URL будет передан (например, если используется IP-телефон, поддерживающий прием URL, этот URL появится на дисплее телефона; аналогично, если используется программный телефон, URL может быть выведен на экран монитора). Этот аргумент применяется очень редко.

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

exten => 1,1,Dial(Zap/1,,m)

Добавление контекста для внутренних вызовов

До сих пор в наших примерах мы ограничивались одним контекстом, но, вероятно, справедливо предполагать, что в диалпланах практически всех установок Asterisk будет не один контекст, а больше. Как упоминалось в начале данной главы, одна из важных функций контекстов – разделение прав доступа (таких, как осуществление междугородних вызовов или звонков на определенные добавочные номера) для разных классов абонентов. В следующем примере наш диалплан будет дополнен созданием двух внутренних добавочных номеров, для которых будет настроена возможность звонить друг другу. Для этого создадим новый контекст, [employees] (служащие).

Как и в предыдущих примерах, предполагаем, что аналоговый канал FXS (Zap/1 в данном случае) уже сконфигурирован и что настройки файла zapata.conf таковы, что все вызовы, берущие начало в Zap/1, обрабатываются в контексте [employees]. В нескольких примерах в конце главы также будет предполагаться, что Zap-канал FXO сконфигурирован как Zap/4 и вызовы, поступающие на этот канал, направляются в контекст [incoming].

Также мы предположили, что имеется по крайней мере один SIP-канал (названный SIP/Jane), который используется в контексте [employees]. Это было сделано, чтобы показать пример использования других типов каналов.

Если вы не располагаете оборудованием для организации перечисленных выше каналов (таких, как Zap/4) или если используете другие имена каналов (например, не SIP/Jane), просто скорректируйте примеры соответственно конфигурации своей системы.

Теперь наш диалплан выглядит так:

[incoming]

exten => 123,1,Answer()

exten => 123,n,Background(enter-ext-of-person) exten => 123,n,WaitExten()

exten => 1,1,Dial(Zap/1,10)

exten => 1,n,Playback(vm-nobodyavail)

exten => 1,n,Hangup()

exten => 2,1,Dial(SIP/Jane,10) exten => 2,n,Playback(vm-nobodyavail) exten => 2,n,Hangup()

exten => i,1,Playback(pbx-invalid) exten => i,n,Goto(incoming,123,1)

exten => t,1,Playback(vm-goodbye) exten => t,n,Hangup()

[employees]

exten => 101,1,Dial(Zap/1)

exten => 102,1,Dial(SIP/Jane) В этом примере в контекст [employees] было добавлено два новых добавочных номера. Таким образом, человек, использующий канал Zap/1, может поднять трубку телефона и позвонить человеку, находящемуся на линии SIP/Jane, набрав номер 102. Точно так же телефон, зарегистрированный как SIP/Jane, может позвонить Zap/1, если пользователь наберет 101.

Добавочные номера 101 и 102 выбраны для примера произвольно, для своих добавочных номеров вы можете использовать любые другие цифры. Также необходимо помнить, что вы не ограничены трехзначными добавочными номерами; номер может включать столько угодно цифр. (Скажем так, почти сколько угодно. Добавочные номера не должны быть длиннее 80 символов, и нельзя использовать добавочные номера длиной в один символ для собственных нужд, поскольку они зарезервированы.) Не забывайте, что могут применяться и имена, как в данном примере: [incoming]

exten => 123,1,Answer()

exten => 123,n,Background(enter-ext-of-person) exten => 123,n,WaitExten()

exten => 1,1,Dial(Zap/1,10)

exten => 1,n,Playback(vm-nobodyavail)

exten => 1,n,Hangup()

exten => 2,1,Dial(SIP/Jane,10) exten => 2,n,Playback(vm-nobodyavail) exten => 2,n,Hangup()

exten => i,1,Playback(pbx-invalid) exten => i,n,Goto(incoming,123,1)

exten => t,1,Playback(vm-goodbye) exten => t,n,Hangup()

[employees]

exten => 101,1,Dial(Zap/1) exten => john,1,Dial(Zap/1)

exten => 102,1,Dial(SIP/Jane) exten => jane,1,Dial(SIP/Jane)

Конечно, не помешало бы добавить именные добавочные номера, если предполагается, что пользователи могут получать звонки по VoIP-про– токолу, такому как SIP, который поддерживает вызов по имени. Также нетрудно заметить, что в диалплане могут быть разные добавочные номера для вызова одной конечной точки, например добавочный номер 200 с выходом на канал SIP/George и добавочный номер 201, который воспроизводит некоторое сообщение, а затем звонит SIP/George. Теперь, когда наши внутренние абоненты могут звонить друг другу, мы значительно продвинулись на пути к созданию полного диалплана. Далее будет показано, как можно сделать диалплан более масштабируемым и пригодным к внесению изменений в будущем.

Использование переменных

Переменные, используемые в диалплане Asterisk, способствуют сокращению объема вводимого текста, делают код более понятным или вводят дополнительную логику. Тем, кто имеет опыт разработки программного обеспечения, вероятно, понятие переменной уже знакомо. Если нет, не стоит беспокоиться; мы объясним, что такое переменные и как они используются.

Переменные можно рассматривать как контейнер, в котором в данный момент времени может храниться одно значение. Например, мы могли бы создать переменную JOHN и присвоить ей значение Zap/1. Теперь при написании диалплана можно ссылаться на канал Джона по имени, а не запоминать, что Джон использует канал, названный Zap/1. Существует два способа использования переменной. Чтобы сослаться на имя переменной, просто вводится ее имя, например JOHN. Если, с другой стороны, требуется сослаться на ее значение, необходимо ввести знак доллара, открывающую фигурную скобку, имя переменной и закрывающую фигурную скобку. Вот как используется переменная в приложении Dial():

exten => 555,1,Dial(${JOHN}) В нашем диалплане Asterisk будет автоматически заменять все ссылки ${JOHN} значением, присвоенным переменной под именем JOHN.

Обратите внимание, что имена переменных чувствительны к регистру. JOHN и John – это разные переменные. Для удобства чтения все имена переменных в примерах будут записываться в верхнем регистре. Также следует помнить, что все переменные, заданные Asterisk, тоже будут записаны прописными буквами. Некоторые переменные, такие как CHANNEL или EXTEN, зарезервированы Asterisk. Не надо пытаться задавать их.

В диалплане используется три типа переменных: глобальные переменные, переменные канала и переменные среды. Кратко рассмотрим каждый из этих типов.

Глобальные переменные

Как следует из их названия, глобальные переменные применяются ко всем добавочным номерам во всех контекстах. Глобальные переменные полезны тем, что могут использоваться в любом месте диалплана, повышая читабельность и обслуживаемость кода. Предположим, имеется большой диалплан и несколько сотен ссылок на канал Zap/1. Теперь представим, что необходимо пересмотреть весь диалплан и изменить все эти ссылки на Zap/2. Это был бы, мягко выражаясь, долгий и чреватый ошибками процесс.

Но если бы в начале диалплана была определена переменная со значением Zap/1 и далее использовались лишь ссылки на нее, потребовалось бы изменить только одну строку.

Глобальные переменные объявляются в контексте [globals] в начале файла extensions.conf. Их можно также задать программно с помощью функции диалплана GLOBALQ[74]74
  Не беспокойтесь! Функции диалплана будут рассмотрены в разделе «Функции диалплана» главы 6.


[Закрыть]
. Вот пример использования обоих методов задания переменных в диалплане. В первом варианте глобальной переменной JOHN присваивается значение Zap/1. Эта переменная задается в момент, когда Asterisk выполняет синтаксический разбор диал– плана. Второй пример представляет, как можно задать глобальную переменную в процессе выполнения диалплана. В этом случае переменной George присваивается значение SIP/George при выполнении звонка на добавочный номер 124 в контексте [employees]: [globals] JOHN=Zap/1

[employees]

exten => 124,1,Set(GLOBAL(GEORGE)=SIP/George)

Переменные канала

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

Для использования в диалплане предопределено множество переменных каналов. Они описаны в файле channelvariables.txt, находящемся в подпапке doc папки исходного кода Asterisk. Переменные каналов задаются с помощью приложения Set():

exten => 125,1,Set(MAGICNUMBER=42) Многие варианты использования переменных каналов будут рассмотрены в главе 6.

Переменные среды

Переменные среды – это средство организации доступа к переменным среды UNIX из Asterisk. Для их использования служит функция диалплана ENV(). Ее синтаксис выглядит следующим образом: ${ENV(var)}, где var – переменная среды UNIX, на которую выполняется ссылка. Переменные среды используются в диалпланах Asterisk не часто, но они доступны на случай необходимости.

Добавление переменных в диалплан

Теперь, ознакомившись с переменными, применим их в нашем диалплане. Добавим глобальные переменные для двух людей, Джона и Джейн:


[globals][globals]
JOHN=Zap/1
JANE=SIP/Jane
[incoming]
exten => 123,1,Answer()
exten => 123,n,Background(enter-ext-of-person)
exten => 123,n,WaitExten()
exten => 1,1,Dial(${JOHN},W)
exten => 1,n,Playback(vm-nobodyavail)
exten => 1,n,Hangup()
exten => 2,1,Dial(${JANE},10)
exten => 2,n,Playback(vm-nobodyavail)
exten => 2,n,Hangup()
exten => i,1,Playback(pbx-invalid)
exten => i,n,Goto(incoming,123,1)
exten => t,1,Playback(vm-goodbye)
exten => t,n,Hangup()
[employees]
exten => W1,1,Dial(${JOHN})
exten => john,1,Dial(${JOHN})
exten => 102,1,Dial(${JANE})
exten => jane,1,Dial(${JANE})

Сопоставление с шаблонами

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

Синтаксис сопоставления с шаблонами

Используемые в шаблонах буквы и символы представляют определенные группы символов. Шаблоны всегда начинаются с символа подчеркивания (_). Он указывает Asterisk, что выполняется сопоставление с шаблоном, а не с явно заданным добавочным номером. (Безусловно, это означает, что имена добавочных номеров нельзя начинать с символа подчеркивания.)

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

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

X

Соответствует любому одиночному числу от 0 до 9.

Z

Соответствует любому одиночному числу от 1 до 9.

N

Соответствует любому одиночному числу от 2 до 9.

[15-7]

Соответствует любому однозначному числу из заданного диапазона. В данном случае шаблон соответствует одиночной цифре 1, 5, 6 или 7.

. (точка)

Универсальное соответствие; соответствует одному или более символам, любым.

1 Если не быть осторожным, сопоставления с групповым символом могут привести к тому, что диалплан будет делать совсем i не то, что предполагается (например, сопоставление с встроен- ными добавочными номерами, такими как i или h). Универсальное соответствие должно использоваться в шаблоне только после того, как сопоставлено максимально возможное количество цифр. Например, следующий шаблон, наверное, не должен применяться никогда:

На самом деле Asterisk предупредит в случае попытки его применения. Лучше по возможности используйте такой шаблон:

_X.

! (восклицательный знак)

Универсальное соответствие; соответствует нулю или более символам, любым.

Чтобы использовать сопоставление с шаблонами в своем диалплане, просто вставьте шаблон на место добавочного номера (или его имени):

exten => _NXX,1,Playback(auth-thankyou) В этом примере шаблон соответствует трехзначному добавочному номеру в диапазоне от 200 до 999 (N соответствует любой цифре от 2 до 9, а каждый X – от 0 до 9). То есть, если бы абонент набрал любой трехзначный добавочный номер в диапазоне от 200 до 999 в данном контексте, он бы услышал звуковой файл auth-thankyou.gsm. Еще одна важная деталь, которую необходимо знать о сопоставлении с шаблонами: если Asterisk находит более одного шаблона, соответствующего набранному добавочному номеру, она будет использовать наиболее точный из них (слева направо). Скажем, задано два следующих шаблона и абонент набирает 555-1212:

exten => _555XXXX,1,Playback(digits/1) exten => _55512XX,1,Playback(digits/2)

В данном случае был бы выбран второй добавочный номер, потому что он более точно соответствует набранному номеру.

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

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

_NXXXXXX

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

_NXXNXXXXXX

NANP и мошенничество с оплатой звонков

Североамериканскийплан нумерации (North AmericanNumbering Plan, NANP) – это общая схема телефонной нумерации, используемая 19 странами в Северной Америке и Канаде. Код страны для стран NANP – 1.

В США и Канаде нормы и правила электросвязи довольно похожи (и удобны), поэтому на большинство междугородних номеров можно звонить, используя код страны 1, по разумной цене.

Однако многие даже не догадываются, что NANP используют 19 стран, подчас с очень разными правилами электросвязи. (Более подробную информацию об этом можно найти по адресу http://www.nanpa.com.)

Очень популярно мошенничество с использованием NANP, когда наивных американцев обманным путем заставляют звонить в страны Карибского бассейна по номерам, звонок по которым оплачивается поминутно, как междугородний; абоненты верят, что, если набрать 1-NPA-NXX-XXXX, звонок будет оплачиваться по стандартным национальным тарифам на междугородние звонки. Поскольку в данном государстве могут действовать правила, допускающие такого рода мошенничество, абоненту в итоге приходится оплачивать телефонные счета.

Единственный способ предотвратить такого рода деятельность – блокировать определенные междугородние коды (например, 809) и снимать ограничения только в случае необходимости.

Обратите внимание, что ни один из данных шаблонов не станет обрабатывать междугородние звонки. Скоро мы рассмотрим этот вопрос. Попробуем другой шаблон:

_1NXXNXXXXXX

Данный шаблон немного сложнее. Он соответствует 1, за которой следует код города от 200 до 999, а затем – любой семизначный номер. В зоне действия NANP этот шаблон будет использоваться для сопоставления с любым междугородним номером[75]75
  Те, кто вырос в Северной Америке, возможно, думают, что 1, которую они набирают при звонках по межгороду, – это «международный код». Это неправильно. 1 – это международный код страны для всех стран, использующих NANP. Помните это, если вам когда-нибудь придется давать свой номер телефона кому-то из другой страны. Они могут не знать кода вашей страны и, таким образом, не смогут дозвониться вам, имея только код города и номер телефона. Полный номер телефона с кодом страны записывается так: +1 NPA NXX XXXX (где NPA – код города) – например +1 416 555 1212.


[Закрыть]
. Теперь еще более хитрый пример: _011.

Если, увидев этот шаблон, вы лишь почесали затылок, посмотрите на него еще раз. Заметили точку в конце? Этот шаблон соответствует любому номеру, начинающемуся с 011 и имеющему по крайней мере еще одну цифру. В NANP это соответствует международному телефонному номеру. (Мы будем использовать эти шаблоны в следующем разделе для добавления в наш диалплан возможностей выполнения исходящих звонков.)

Использование переменной канала ${EXTEN}

Мы знаем, о чем вы думаете... Вы сидите и задаете себе вопрос: «Так что же делать, если я хочу использовать сопоставление с шаблонами, но мне надо знать, какие цифры набираются?» К счастью, у Asterisk есть ответ. При каждом звонке на добавочный номер Asterisk сохраняет набранный номер в переменной канала ${EXTEN}. Чтобы протестировать ее, можно использовать приложение SayDigits():

exten => _XXX,1,SayDigits(${EXTEN})

В этом примере приложение SayDigits() будет воспроизводить для вас набранный вами трехзначный добавочный номер.

Часто переменную ${EXTEN} удобно использовать для удаления определенного количества цифр в начале добавочного номера. Это осуществляется с помощью синтаксиса ${EXTEN:x}, где x – разряд, с которого должна начинаться возвращаемая строка, считая слева направо. Например, если значение EXTEN – 95551212, ${EXTEN:1} равно 5551212. Рассмотрим другой пример:

exten => _XXX,1,SayDigits(${EXTEN:1})

В этом примере приложение SayDigits() начнет воспроизведение со второй цифры, таким образом, будут воспроизведены только две последние цифры набранного добавочного номера.

Более сложные операции с номерами

Полный синтаксис переменной ${EXTEN} – ${EXTEN: x: у}, где x – начальное положение, а у – количество цифр, которое должно быть возвращено. Пусть задана строка набора:

94169671111

Используя конструкцию ${EXTEN:x:y}, можно извлечь следующие цифровые строки:

${EXTEN:1:3} – будет возвращена строка 416. ${EXTEN:4:7} – будет возвращена строка 9671111. ${EXTEN:-4:4} – строка будет начинаться с четвертого символа с конца и включает четыре символа, что даст 1111. ${EXTEN:1} – будет возвращено все после первой цифры, 4169671111 (если количество цифр, которое должно быть возвращено, не задано, будет возвращена вся оставшаяся строка). Это очень мощная структура, но большинство из приведенных ее вариантов используются редко. Чаще всего вы будете применять ${EXTEN:1}, чтобы отбросить внешний код доступа.

Активация исходящих вызовов

Теперь, когда мы ознакомились с шаблонами, можно переходить к тому, как обеспечить абонентам возможность осуществлять исходящие звонки. Первое, что мы сделаем, – добавим переменную в контекст [globals], чтобы определить, какой канал будет использоваться для исходящих вызовов:

[globals] JOHN=Zap/1 JANE=SIP/Jane OUTBOUNDTRUNK=Zap/4

Далее добавим в диалплан контекст для исходящих вызовов. Возможно, сейчас вы задаетесь вопросом: «Зачем нужен отдельный контекст для исходящих звонков?» Это делается для того, чтобы иметь возможность управлять тем, какие абоненты имеют право делать исходящие звонки и какого типа могут быть эти звонки. Сначала создадим контекст для локальных вызовов. Не будем отступать от традиций и первой цифрой в наших шаблонах поставим 9, чтобы пользователи для звонка на внешний номер набирали 9: [outbound-local]

exten => _9NXXXXXX,1,Dial(${OUTBOUNDTRUNK}/${EXTEN:1}) exten => _9NXXXXXX,n,Congestion() exten => _9NXXXXXX,n,Hangup()

Обратите внимание, что цифра 9 на самом деле не обеспечивает выхода на внешнюю линию, как это происходит во многих традиционных системах офисных АТС. После набора цифры 9 в аналоговой линии сразу же пропадет тональный сигнал готовности линии. Если вам хочется, чтобы зуммер продолжался даже после набора цифры 9, добавьте следующую строку (сразу после описания контекста): ignorepat => 9

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

Повторим, что было сделано. Мы добавили глобальную переменную OUTBOUNDTRUNK, которая просто определяет канал, используемый для исходящих вызовов1. Также был введен контекст для локальных исходя-Это обеспечивает то преимущество, что, если однажды будет принято решение передавать вызовы по какому-то другому каналу, надо будет отредактировать имя канала, заданное как значение переменной OUTBOUNDTRUNK только в контексте [globals], а не менять вручную все ссылки на этот канал по всему диалплану.


    Ваша оценка произведения:

Популярные книги за неделю