Вторая часть статьи. Первая находится по адресу : здесь

Диалплан Freeswitch

Составные условия/Правила действий (Action Rules)

Вот более сложный пример, показывающий маршрутизацию по времени для организации поддержки.

Пользователь набирает направление 1100. Фактическое направление поддержки — 1105, работают они каждый день с 8 утра до 10 вечера, кроме пятницы, когда рабочий день длится с 8 утра до часу дня. В любое другое время звонки на 1100 перенаправляются на почтовый ящик поддержки. Обратите внимание, что break="on-false" стоит по умолчанию.

<!-- Можно не рассматривать следующий набор условий, если это значение истинно.-->
<condition wday="6" hour="8-12" break="on-true">    <!-- Пятница, 8.00 - 12.59 -->
    <action application="transfer" data="1105 XML default"/>
</condition>

<condition wday="1-5" hour="8-21" break="on-true">   <!-- Воскресенье - Четверг, 8.00 - 21.59 -->
    <action application="transfer" data="1105 XML default"/>
</condition>

<condition> <!-- это универсальный алгоритм, пересылающий вызов на голосовую почту в любое другое время. -->
    <action application="voicemail" data="default ${domain} 1105"/>
</condition>

В этом примере мы используем параметр break=never, чтобы заставить первое условие 'проваливаться' к следующему, независимо от того, истинно или ложно первое условие. Это полезно для установки определенных флагов в рамках обработки направления. В этом примере устанавливается переменная begins_with_one, если номер адресата начинается с 1.

<condition field="destination_number" expression="^(d+)$">
 ...другие действия, которые могут запрашивать параметр begins_with_one...
</condition>
</extension>

Шаблоны (Patterns) Asterisk

В дополнение к PCRE FreeSWITCH также поддерживает шаблоны Asterisk; любое выражение, которое начинается с символа подчеркивания (_) будет использовать для проверки эти шаблоны. Пожалуйста, обратите внимание, что некоторые шаблоны могут требовать особых команд для выхода, таких как "*"

Посмотрите на Mod_dialplan_asterisk

<extension name="_NXXXXXXXXX_asterisk">
    <condition field="destination_number" expression="_(NXXXXXXXXX)">
     <action application="bridge" data="sofia/internal/$1@example.com"/>
 </condition>
</extension>

<extension name="_*XX_with_escaping">
    <condition field="destination_number" expression="_(*XX)(.)">
    <action application="log" data="ERR captured $1 ~~~ $2"/>
        <action application="answer"/>
        <action application="playback" data="tone_stream://path=${base_dir}/conf/tetris.ttml;loops=10"/>
    </condition>
</extension>

Выражения (Variables)

Выражения условия могут соответствовать канальным переменным или массиву встроенных переменных.

Встроенные Выражения (Built-In Variables)

Следующие переменные, называемые 'caller profile fields', можно получить непосредственно из условия:

  • context Почему мы можем использовать контекст в качестве области профиля? Приведите, пожалуйста, примеры использования.

  • rdnis Перенаправленный номер, номер каталога, в который поступил прошлый вызов.

  • destination_number Набранный номер или номер, которого этот вызов пытается достичь (в данном контексте)

  • dialplan Имя, используемое модулем диалплана, такое имя предусмотрено для каждого модуля диалплана. Пример: XML

  • caller_id_name Имя вызывающего абонента (предоставляет User Agent, который нас вызывет).

  • caller_id_number Номер каталога звонящего участника (абонента) — может быть замаскирован (скрыт)

  • ani Автоматическая идентификация номера, номер вызывающего участника (абонента) — не может быть замаскирован

  • aniii Тип устройства, выполняющего вызов ANI2

  • uuid Уникальный идентификатор текущего вызова? (выглядит похоже на GUID)

  • surce Имя модуля FreeSWITCH, который принял вызов (например, PortAudio)

  • chan_name Имя текущего канала (например: PortAudio/1234). Приведите примеры, когда оно может быть использовано.

  • network_addr IP-адрес источника сигнала для вызова VoIP.

  • year Календарный год, 0-9999

  • yday День года, 1-366

  • mon Месяц, 1-12 (Январь = 1, и т. д.)

  • mday День месяца, 1-31

  • week Неделя года, 1-53

  • mweek Неделя месяца, 1-6

  • wday День недели, 1-7 (воскресенье = 1, понедельник = 2 и т. д.) или "sun", "mon", "tue" и т. д.

  • hour Час, 0-23

  • minute Минута (часа), 0-59

  • minute-of-day Минута дня, (1-1440) (полночь = 1, 1.00 = 60, 12.00 = 720 и т. д.)

  • time-of-day Диапазон времени в формате: hh:mm[:ss]-hh:mm[:ss] (секунды опционально) Пример: "08:00-17:00"

  • date-time Диапазон даты/времени в формате: YYYY-MM-DD hh:mm[:ss]~YYYY-MM-DD hh:mm[:ss] (секунды опционально, обратите внимание на тильду между датами) Пример: 2010-10-01 00:00:01~2010-10-15 23:59:59

Например:

<condition field="network_addr" expression="^192.168.1.1$"/>  <!-- адрес сети=192.168.1.1 >
<condition mon="2">   <!-- месяц=февраль -->

Встроенные переменные (Caller Profile Fields) против Переменных канала (Channel Variables)

Разница между caller profile field (встроенной переменной) и переменной канала может показаться запутанной.

Так получают доступ к области профиля абонента:

<condition field="destination_number" attributes...>

В то время как доступ к канальной переменной получают так:

<condition field="${sip_has_crypto}" attributes...>

Пожалуйста, обратите внимание на синтаксис ${variable_name}. Канальные переменные также могут быть использованы в выражениях действий. Кроме того, функции API можно вызвать изнутри выражения условия для обеспечения динамических данных. Например, вы можете использовать API cond:

<condition field="${cond(${my_var} > 12 ? YES : NO)}" expression="^YES$">
    <action application="log" data="INFO ${my_var} is indeed greater than 12"/>
</condition>

В этом примере тестируется переменная ${my_var}. Если её значение больше 12, возвращается "YES". В обратном случае возвращается "NO". Условие проверяет результаты для "YES" и заносит полученное сообщение в журнал FreeSWITCH.

Availability of Variables

Рекомендуется к прочтению пользователям Asterisk!

Диалплан XML имеет возможность проверки ряда условий, основанных на переменных с выражениями; однако, должно быть понятно, что некоторые переменные могут быть недоступны для тестирования условия, пока не выполнится первый переход или execute_extension (обходные пути смотрите ниже).

Причины

По существу, диалплан XML должен использоваться скорее для маршрутизации вызовов, чем для сложных или обширных тестов и оценок. Поэтому во FreeSWITCH сделаны доступными Lua, JavaScript, Perl, Python и другие API, поскольку они являются гораздо лучшей альтернативой по сравнению с придумыванием запутанных решений на основе XML или еще хуже, некоторых загадочных и запутанных аббревиатур, таких как "AEL".

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

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

Вот почему вы можете обнаружить, что какое-либо из условий XML не работает, хотя переменная и ее значение отображаются в

<action application="info"/>

Обходный путь

Обходным путём для этого может быть либо осуществление подавляющего большинства алгоритмов вашего диалплана на Lua, JavaScript или каком-то другом из доступных для диалплана скриптовых языков, ИЛИ создание направления, которое сделает переменные, нужные вам для проведения оценки условий, доступными для анализа внутри условий вашего XML-диалплана.

Примечание: Начиная с svn версии 14906 для некоторых приложений возможен запуск inline. Это означает, что они выполняются во время охоты, благодаря чему наборы канальных переменных для этих приложений становятся доступными для следующих условий во время охоты.

Действия (Actions) и Анти действия (Anti-Actions)

До сих пор мы видели примеры записей диалплана, содержащие условия наряду с действиями, которые выполняются при соответствии условий.

Вы можете также определить 'анти-действия', которые осуществляются, если условия для направления 'не выполняются'.

В этом примере значение ${my_var} сравнивается с 12, и сообщения заносятся в журнал при любом результате.

<condition field="${cond(${my_var} > 12 ? YES : NO)}" expression="^YES$">
    <action application="log" data="INFO ${my_var} is indeed greater than 12"/>
    <anti-action application="log" data="INFO ${my_var} is not greater than 12"/>
</condition>

Доступные действия

Смотрите API Reference и функции Диалплана

Inline Действия

Вы можете установить дополнительный атрибут inline="true" на любое действие, после чего оно будет выполняться во время фазы поиска диалплана:

<action inline="true" application="set" data="some_var=some_val"/>

Это даёт возможность использовать условие в следующем направлении, которое соответствует области ${some_var}.

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

Приложения, которые разрешено запускать inline:

  • check_acl

  • eval

  • event

  • export

  • log

  • presence

  • set

  • set_global

  • set_profile_var

  • set_user

  • unset

  • verbose_events

  • cidlookup

  • curl

  • easyroute

  • enum

  • lcr

  • nibblebill

  • odbc_query

Также имейте в виду, что запущенные inline приложения не отображаются в детализации звонков, как приложения, выполняемые обычным способом.

Полный синтаксис

<!-- Для перечисленных атрибутов первое значение в списке установлено по умолчанию -->
<extension name="unique_extension_name" continue="[false|true]">
<condition field="[field_name|${variable_name}|${api_func(api_args ${var_name})}]" expression="regular expression"
    break="[on-false|on-true|always|never]" require-nested="[true|false]">
    <condition ...><!-- Условия могут быть вложенными -->
    ...
    </condition>
    <action application="app name" data="app arg"/>
    <anti-action application="app name" data="app arg"/>
</condition>

<!-- В последовательности может быть любое количество тегов условий, в которых применяются одни и те же правила -->
</extension>

Короткое заключение

Полный алгоритм диалплана для версии 1.2.22:

Процесс поиска на направления останавливается на первом направлении, где условия принимают значение true, а continue="false" (по умолчанию).

Условия принимают значение true, если последнее проверенное условие истинно.

Условия проверяются вглубь до тех пор, пока:

break="on-false" и условие ложно

или break="on-true" и условие истинно

или break="always".

Условие истинно, если выражение выполнимо и либо нет вложенных условий, либо require-nested="false", либо вложенные условия принимают значение true.

Если условие имеет значение true, входящие в него действия подготавливаются для исполнения, в противном случае готовятся для исполнения анти-действия.

Если require-nested="true" (по умолчанию) и вложенные условия оцениваются как ложные, никакие анти-действия не подготавливаются. (Это сделано намеренно?)

Другие фишки Диалплана Freeswitch

Диалплан анализируется один раз, когда звонок переводит его парсер в состояние МАРШРУТИЗАЦИИ. В результате одного прохода по XML получается полный список инструкций, установленных в канал на основе проанализированных тегов <действие> или <анти-действие>.

Те, кто привык к Asterisk, могут ожидать звонка отслеживания диалплана, выполняющего приложения по мере их разбора, что позволяет получать данные от одного действия, чтобы повлиять на следующее действие. Но это не тот случай, за исключением областей типа ${api func(api arg ${var_name})} где во время проведения парсинга из модуля может быть выполнен подключаемый вызов api. Он предназначен, чтобы использоваться для отображения в режиме реального времени таких сведений, как дата и время или другой быстро доступной информации, и им не следует злоупотреблять.

Auto Hunt

Многие подключают функцию auto_hunt, после чего, в случае точного равенства имени направления набранному номеру, FreeSWITCH переключится на это направление, чтобы начать поиск. Хотя это может как соответствовать, так и не соответствовать условиям.

Набор через шлюз

"gateway" (шлюз) обрабатывается модулем mod_sofia как ключевое слово и это, очевидно, означает, что звонок будет проходить через настроенный шлюз.

Хотя есть исключение для шаблона sofia/profilename/extension@ip-address.

Если шлюз, например, называется "gw", линия соединения для отправки через него вызова на направление 100 будет:

<extension name="testing">
 <condition field="destination_number" expression="^(100)$">
 <action application="bridge" data="sofia/gateway/gw/$1"/>
</condition>
</extension>

"destination_number" – это переменная FreeSWITCH; она не должна подвергаться изменениям.

© Внимание! Все права на перевод принадлежат фирме Гарантум. При ссылке или цитировании данной информации обязательно вставляйте ссылку на источник.