# Глава 6. Основы диалплана > _Всё должно быть изложено так просто, как только возможно, но не более того._ > > — Альберт Эйнштейн Диалплан - это сердце вашей системы Asterisk. Он определяет, как звонки поступают в систему и выходят из нее. Диалплан является скриптовым языком, который определяет инструкции, которым Asterisk следует в ответ на вызовы, поступающие от каналов. В отличие от традиционных телефонных систем, диалплан Asterisk полностью настраивается. Опытные разработчики программного обеспечения считают код диалплана Asterisk архаичным и часто предпочитают управлять потоком вызовов с помощью API Asterisk, таких как AMI и ARI (которые мы обсудим в последующих главах). Независимо от ваших планов в этом отношении - изучение поведения Asterisk намного проще, если вы сначала поймете диалплан. Возможно, также стоит отметить, что диалплан Asterisk настроен на производительность и поэтому является самым быстрым способом выполнения потока вызовов с точки зрения быстродействия и минимальной нагрузки на систему. Диалплан работает быстро. В этой главе представлены основные понятия, которые лягут в базу любого диалплана, написанного вами. Не пропускайте слишком много из этой главы, так как примеры строятся друг на друге и это принципиально важно для Asterisk. Обратите также внимание, что эта глава ни в коем случае не является исчерпывающим обзором всех возможных вещей, которые может сделать диалплан; наша цель - охватить только самое необходимое. В последующих главах мы рассмотрим более сложные темы диалплана. Вам рекомендуется экспериментировать. ## Синтаксис диалплана Диалплан Asterisk задается в конфигурационном файле с именем *extensions.conf*, расположенном в каталоге */etc/asterisk*. Структура диалплана состоит из четырех иерархических компонентов: контекстов (Context), расширений (Extension), приоритетов (Priority) и приложений (Application) (смотри Рисунок 6-1). ![](pics/pic6-1.png) _Рисунок 6-1. Иерархия диалплана_ Давайте нырнем прямо туда.
Примеры файлов конфигурации Основной файл extensions.conf был создан как часть процесса установки ранее в этой книге. Мы будем опираться на этот файл в этой главе. Asterisk также поставляется с подробным файлом extensions.conf, который может быть установлен с образцами файлов конфигурации (за это отвечает команда установки Как и говорилось, файл примера extensions.conf - это фантастический ресурс, полный примеров и идей, которые вы можете использовать после того, как изучили основные понятия. Если вы выполнили наши инструкции по установке, то найдете файл extensions.conf.sample в каталоге ~/src/asterisk-16./configs/samples (наряду со многими другими образцами файлов конфигурации). |
Это очень важное соображение. В традиционных УАТС, для таких вещей как прием вызова, как правило, существует набор значений по умолчанию, что означает, в случае, если вы забудете их определить, они, вероятно, будут работать в любом случае. В Asterisk все наоборот. Если вы не скажете Asterisk, как обрабатывать каждую ситуацию, и он столкнется с чем-то, что не может обработать - вызов, как правило, будет отклонен. |
Имена контекстов имеют максимальную длину 79 символов (80 символов минус 1 завершающий null). |
Это одна из наиболее важных концепций для понимания при работе с каналами и диалпланом. Устранение неполадок потока вызовов намного проще, если вы понимаете связь между контекстом канала (который сообщает каналу, где подключаться к диалплану) и контекстом диалплана (где мы создаем поток вызовов, который происходит при поступлении вызова). |
Asterisk wiki описывает несколько шагов, которые вы должны предпринять, чтобы сохранить вашу систему Asterisk в безопасности. Жизненно важно чтобы вы прочитали и поняли эту страницу. Если вы игнорируете меры безопасности, изложенные там, то можете в конечном итоге позволить всем и каждому совершать междугородние или платные звонки за ваш счет! Если вы не относитесь к безопасности вашей системы Asterisk серьезно, то можете в конечном итоге поплатиться буквально. Пожалуйста, потратьте время и усилия, чтобы защитить вашу систему от мошенничества. |
Назначение имен для расширений может показаться необычной концепцией, но когда вы понимаете, что SIP поддерживает набор всех видов комбинаций символов (все, что является допустимым URI, строго говоря) - это имеет смысл. Это одна из особенностей, которая делает Asterisk настолько гибким и мощным. |
Не ошибитесь: диалплан Asterisk весьма своеобразен. Многие люди избегают его вообще, и используют AGI и ARI для написания своего диалплана.Хотя, конечно, есть что сказать для написания диалплана на внешнем языке (и мы рассмотрим это в последующих главах), диалплан Asterisk является родным для него, и вы не получите лучшей производительности чем c ним. Код диалплана выполняется быстро.Кроме того, если вы хотите понять, как Asterisk думает - вам нужно понять его диалплан. |
Очень распространенной ошибкой при написании меток является вставка запятой между номером приоритета и открывающейся скобкой, например:
Эта ошибка нарушит часть вашего диалплана и вы получите соответствующее сообщение, указывающее, что приложение не может быть найдено. |
Приложение Progress() Иногда полезно иметь возможность передавать информацию обратно в сеть перед ответом на вызов. Приложение |
Asterisk поставляется со многими профессионально записанными звуковыми файлами, которые могут быть найдены в каталоге звуков по умолчанию (обычно /var/lib/asterisk/sounds). При компиляции Asterisk можно установить различные наборы образцов звуков, записанных на различных языках и в различных форматах файлов. Мы будем использовать эти файлы во многих наших примерах. Некоторые из файлов в наших примерах взяты из дополнительного звукового пакета, который мы установили в Главе 3. Вы также можете иметь свои собственные звуковые подсказки, записанные в тех же голосах, что и стоковые подсказки, посетив www.theivrvoice.com. Далее в книге мы поговорим о том, как можно использовать телефон и диалплан для создания и управления собственными системными записями (или импорта .wav файлов). |
Если у вас нет настроенных каналов - сейчас самое время создать их. Существует реальное удовлетворение, приходящее от совершения вашего первого вызова в диалплан Asterisk в системе, которую вы построили с нуля. Люди получают эту ухмылку на лицах когда понимают, что они только что создали телефонную систему. Это удовольствие может быть и вашим, поэтому, пожалуйста, не идите дальше, пока не сделаете эту маленькую работу диалплана. Если у вас есть какие-либо проблемы, вернитесь к Главе 5 и проработайте примеры оттуда. |
Мы не рекомендуем Вам продвигаться вперед в этой книге, пока вы не проверите следующее:
|
Когда вы создаете диалплан, будет полезно открыть CLI Asterisk в новом окне. Вы будете часто перезагружать диалплан, и во время тестирования потока вызовов захотите увидеть что происходит. CLI Asterisk полезен для обеих этих вещей.
Поэтому лучше всего было бы редактировать файлы конфигураций в одном окне, а перезагружать и отлаживать в другом. |
Если посмотрите детали приложения В этом примере мы передали все три аргумента для ясности, но передача только расширения и приоритета имела бы тот же эффект, поскольку контекст назначения совпадает с исходным контекстом. |
В эти дни вы, скорее всего, будете использовать PJSIP в качестве типа канала, но в не слишком далеком прошлом общие типы технологий также включали DAHDI (для аналоговых и T1/E1/J1 каналов), старый канал SIP (до PJSIP) и IAX2.13 Если вы посмотрите на более старый диалплан, то можете увидеть некоторые из этих представленных протоколов. В дальнейшем рекомендуется и поддерживается только PJSIP и DAHDI. |
Обратите внимание, что имена переменных чувствительны к регистру. Переменная по имени |
${ENV(var)}
, где `var` - переменная среды Unix, на которую вы хотите ссылаться. Переменные среды обычно не используются в диалплане Asterisk, но они доступны в случае необходимости.
#### Добавление переменных в ваш диалплан
Теперь, когда мы узнали о переменных, давайте включим их в наш диалплан. Мы добавим три глобальные переменные, которые свяжут имя переменной с именем канала:
```
[general]
[globals]
UserA_DeskPhone=PJSIP/0000f30A0A01
UserA_SoftPhone=PJSIP/SOFTPHONE_A
UserB_DeskPhone=PJSIP/0000f30B0B02
UserB_SoftPhone=PJSIP/SOFTPHONE_B
[sets]
exten => 100,1,Dial(${UserA_DeskPhone})
exten => 101,1,Dial(${UserA_SoftPhone})
exten => 102,1,Dial(${UserB_DeskPhone},10)
same => n,Playback(vm-nobodyavail)
same => n,Hangup()
exten => 103,1,Dial(${UserB_SoftPhone})
exten => 110,1,Dial(${UserA_DeskPhone}&${UserA_SoftPhone}&${UserB_SoftPhone})
exten => 200,1,Answer()
```
Теперь давайте обновим наше тестовое меню:
```
[TestMenu]
exten => start,1,Answer()
same => n,Background(enter-ext-of-person)
same => n,WaitExten(5)
exten => 1,1,Dial(${UserA_DeskPhone},10)
same => n,Playback(vm-nobodyavail)
same => n,Hangup()
exten => 2,1,Dial(${UserA_SoftPhone},10)
same => n,Playback(vm-nobodyavail)
same => n,Hangup()
exten => 3,1,Dial(${UserB_DeskPhone},10)
same => n,Playback(vm-nobodyavail)
same => n,Hangup()
exten => 4,1,Dial(${UserB_SoftPhone},10)
same => n,Playback(vm-nobodyavail)
same => n,Hangup()
exten => i,1,Playback(pbx-invalid)
```
Редко имеет смысл жестко кодировать данные в диалплане. Почти всегда лучше использовать переменную.
Проверьте диалплан на предмет опечаток и протестируйте его. Также вы можете посмотреть как это выглядит в Asterisk CLI при выполнении:
```
# asterisk -rvvvvvv
*CLI> dialplan reload
-- Executing [201@sets:1] Goto("PJSIP/0000f30A0A01", "TestMenu,start,1")
-- Goto (TestMenu,start,1)
-- Exec [start@TestMenu:1] Answer("PJSIP/0000f30A0A01", "")
-- Exec [start@TestMenu:2] BackGround("PJSIP/0000f30A0A01", "enter-ext-of-person")
--
Если вы забудете подчеркивание в начале вашего шаблона - Asterisk подумает, что это просто именованное расширение и не будет выполнять сопоставление шаблонов. Это одна из самых распространенных ошибок, которые совершают люди, начинающие изучать Asterisk. |
Другой распространенной ошибкой является попытка использовать буквы X, Z и N буквально в соответствии с шаблоном; для этого оберните их в квадратные скобки (без учета регистра), как пример: |
Если вы не будете осторожны, подстановочные совпадения могут заставить ваши диалпланы делать то, что вы не ожидаете (например, сопоставление встроенных расширений, таких как i или h). Вы должны использовать подстановочное соответствие в шаблоне только после того, как сопоставили как можно больше других цифр. Например, следующий шаблон никогда не должен использоваться:
На самом деле, Asterisk предупредит вас, если вы попытаетесь его использовать. Вместо этого, если вам действительно нужно всеохватывающее совпадение шаблона, используйте чтобы соответствовать всем строкам, которые начинаются с цифры, за которой следует один или несколько символов (см. ! если хотите иметь возможность соответствовать нулю или более символов):
Или этот, чтобы соответствовать любой буквенно-цифровой строке:
|
NANP и мошенничество Североамериканский план нумерации (NANP) - это общая схема нумерации телефонов, используемая 19 странами Северной Америки и Карибского бассейна. Все эти страны имеют общий код страны 1. В США и Канаде существует достаточная конкуренция, что вы можете сделать междугородний звонок на большинство номеров в коде страны 1 и ожидать разумной платы. Однако многие люди не понимают, что 17 других стран, многие из которых имеют очень разные правила телекоммуникаций, разделяют NANP. В некоторые из этих мест довольно дорого звонить. Одна популярная афера с использованием NANP - попытка обмануть наивных североамериканцев в вызове дорогих поминутных платных номеров в карибской стране; абоненты считают, что, поскольку они набрали 1-NPA-NXX-XXXX чтобы дозвониться до номера - они будут платить по своему стандартному национальному междугороднему тарифу. Поскольку в рассматриваемой стране могут быть правила, допускающие такую форму вымогательства, абонент в конечном итоге несет ответственность за оплату вызова. Возможно, будет разумно блокировать звонки на коды регионов в страны NANP за пределами США и Канады, пока у вас не будет возможности пересмотреть свои тарифы на вызовы в эти страны. Википедия имеет хорошую ссылку на основы того, что вам нужно знать о NANP, в том числе какие NPA (коды регионов) какой стране принадлежат. |
${EXTEN:x}
, где x
- это позиция начала возвращаемой строки слева направо. Например, если значение `${EXTEN}` равно `95551212`, `${EXTEN:1}` равно `5551212`. Давайте попробуем другой пример:
```
exten => _XXX,1,Answer()
same => n,SayDigits(${EXTEN:1})
```
В этом примере приложение `SayDigits()` будет начинать со второй цифры и, таким образом, считывать только последние две цифры набранного добавочного номера.
Продвинутые возможности манипуляций с цифрами Переменная 94169671111
мы можем извлечь следующие строки цифр, используя конструкцию
Это очень мощная конструкция, но большинство из этих вариаций не очень распространены в обычном использовании. По большей части вы будете использовать |
n+200
и приоритет s
(для same), но их использование несколько устарело из-за существования меток приоритета. Обратите внимание, что расширения и приоритет s
- это два разных понятия.Background()
, которое очень похоже на Playback()
за исключением того, что оно позволяет получать ввод данных от вызывающего абонента. Вы можете прочитать больше об этом приложении в Главах 14 и 16.core show translation
в Asterisk CLI. Приведенные цифры показывают, сколько микросекунд требуется Asterisk для перекодирования одной секунды звука.Background()
из-за его названия, будет продолжаться дальше через следующие шаги в диалплане во время воспроизведения звука. На самом деле, его название относится к тому, что он воспроизводит звук в фоновом режиме, ожидая DTMF на переднем плане.TIMEOUT()
для получения информации о том, как изменить тайм-ауты по умолчанию. См. Главу 10 для получения информации о том, что такое функции диалплана.i
предназначено для перехвата недопустимых значений, предоставленных приложением диалплана, например Background()
. Оно не используется для сопоставления на неверно набранные номера или несовпадения шаблонов.DIALSTATUS
.