# Глава 6. Основы диалплана > _Всё должно быть изложено так просто, как только возможно, но не более того._ > > — Альберт Эйнштейн Диалплан - это сердце вашей системы Asterisk. Он определяет, как звонки поступают в систему и выходят из нее. Диалплан является скриптовым языком, который определяет инструкции, которым Asterisk следует в ответ на вызовы, поступающие от каналов. В отличие от традиционных телефонных систем, диалплан Asterisk полностью настраивается. Опытные разработчики программного обеспечения считают код диалплана Asterisk архаичным и часто предпочитают управлять потоком вызовов с помощью API Asterisk, таких как AMI и ARI (которые мы обсудим в последующих главах). Независимо от ваших планов в этом отношении - изучение поведения Asterisk намного проще, если вы сначала поймете диалплан. Возможно, также стоит отметить, что диалплан Asterisk настроен на производительность и поэтому является самым быстрым способом выполнения потока вызовов с точки зрения быстродействия и минимальной нагрузки на систему. Диалплан работает быстро. В этой главе представлены основные понятия, которые лягут в базу любого диалплана, написанного вами. Не пропускайте слишком много из этой главы, так как примеры строятся друг на друге и это принципиально важно для Asterisk. Обратите также внимание, что эта глава ни в коем случае не является исчерпывающим обзором всех возможных вещей, которые может сделать диалплан; наша цель - охватить только самое необходимое. В последующих главах мы рассмотрим более сложные темы диалплана. Вам рекомендуется экспериментировать. ## Синтаксис диалплана Диалплан Asterisk задается в конфигурационном файле с именем *extensions.conf*, расположенном в каталоге */etc/asterisk*. Структура диалплана состоит из четырех иерархических компонентов: контекстов (Context), расширений (Extension), приоритетов (Priority) и приложений (Application) (смотри Рисунок 6-1).  _Рисунок 6-1. Иерархия диалплана_ Давайте нырнем прямо туда.
|
Примеры файлов конфигурации Основной файл extensions.conf был создан как часть процесса установки ранее в этой книге. Мы будем опираться на этот файл в этой главе. Asterisk также поставляется с подробным файлом extensions.conf, который может быть установлен с образцами файлов конфигурации (за это отвечает команда установки Как и говорилось, файл примера extensions.conf - это фантастический ресурс, полный примеров и идей, которые вы можете использовать после того, как изучили основные понятия. Если вы выполнили наши инструкции по установке, то найдете файл extensions.conf.sample в каталоге ~/src/asterisk-16./configs/samples (наряду со многими другими образцами файлов конфигурации). |
|
|
|
|
|
|
|
Если вы не относитесь к безопасности вашей системы Asterisk серьезно, то можете в конечном итоге поплатиться буквально. Пожалуйста, потратьте время и усилия, чтобы защитить вашу систему от мошенничества. |
|
|
|
Не ошибитесь: диалплан Asterisk весьма своеобразен. Многие люди избегают его вообще, и используют AGI и ARI для написания своего диалплана.Хотя, конечно, есть что сказать для написания диалплана на внешнем языке (и мы рассмотрим это в последующих главах), диалплан Asterisk является родным для него, и вы не получите лучшей производительности чем c ним. Код диалплана выполняется быстро.Кроме того, если вы хотите понять, как Asterisk думает - вам нужно понять его диалплан. |
|
Эта ошибка нарушит часть вашего диалплана и вы получите соответствующее сообщение, указывающее, что приложение не может быть найдено. |
|
Приложение Progress() Иногда полезно иметь возможность передавать информацию обратно в сеть перед ответом на вызов. Приложение |
|
|
|
|
|
|
|
Когда вы создаете диалплан, будет полезно открыть CLI Asterisk в новом окне. Вы будете часто перезагружать диалплан, и во время тестирования потока вызовов захотите увидеть что происходит. CLI Asterisk полезен для обеих этих вещей.
Поэтому лучше всего было бы редактировать файлы конфигураций в одном окне, а перезагружать и отлаживать в другом. |
|
В этом примере мы передали все три аргумента для ясности, но передача только расширения и приоритета имела бы тот же эффект, поскольку контекст назначения совпадает с исходным контекстом. |
|
|
|
|
${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 предупредит вас, если вы попытаетесь его использовать. Вместо этого, если вам действительно нужно всеохватывающее совпадение шаблона, используйте чтобы соответствовать всем строкам, которые начинаются с цифры, за которой следует один или несколько символов (см. ! если хотите иметь возможность соответствовать нулю или более символов):
Или этот, чтобы соответствовать любой буквенно-цифровой строке:
|
|
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.