Приложения реального времени (PBXApp)
Модуль Приложений Реального Времени CommuniGate Pro обеспечивает инфраструктуру для создания и использования приложений, обрабатывающих различные Сигналы.
Приложения Реального Времени используются для обработки голосовых звонков, включая обслуживание голосовой почты, работу авто-секретаря, организацию конференций и т.д. В этих приложениях реализованы функции «IP-PBX», основывающиеся на стандартах Интернет и обеспечивающие альтернативу существующим PBX (АТС, УПАТС).
Приложение Реального Времени может активироваться при отправке Сигнала определённому пользователю, а некоторые Сигналы могут быть явно направлены на обработку в Приложения Реального Времени.
Программное обеспечение Сервера CommuniGate Pro поставляется с несколькими встроенными Приложениями. Эти приложения обладают большими возможностями по настройке и подходят для использования в большинстве «типовых» случаев.
Если вы хотите научиться изменять настройки встроенных Приложений и/или вы хотите создавать свои собственные Приложения Реального Времени, то ознакомьтесь с этим разделом.
Среды приложений
Среда для Приложений Реального Времени является набором файлов, которые могут включать в себя:
CGPL файлы с кодом Приложений и кодом модулей.
Произвольные служебные файлы - например, записанные заранее медиа файлы.
Директории с файлами для различных Языков.
Среды разработаны таким образом, чтобы они могли поддерживать работу нескольких разных человеческих (разговорных) языков. По умолчанию языком Среды является Английский. Для поддержки других языковых файлов Среда должна иметь языковые директории, названные по имени поддерживаемого в них языка (french, russian, japanese и т.д.)
Языковая директория может содержать такие же файлы, что и Среда, но она не может иметь поддиректорий.
Задача Приложения Реального Времени может выбирать используемый язык. При выборе языка, не являющегося языком по умолчанию, код приложения пытается прочитать файл из Среды Приложения, используя выбранную языковую поддиректорию. Если в языковой поддиректории файл не найден, то запрашивается файл из самой Среды Приложения (то есть, используется язык по умолчанию).
Сервер CommuniGate Pro поставляется со «стандартной» Средой Приложений Реального Времени. Эта Среда содержит некоторые базовые приложения и все файлы, необходимые для нормальной работы этих приложений, а также некоторые полезные разделы кода и медиа файлы.
Каждая система CommuniGate Pro имеет общесерверную Среду Приложения. В установках с Динамическим Кластером CommuniGate Pro также существует общекластерная Среда Приложения. Для того, чтобы изменить эти Среды, откройте через Веб Интерфейс Администратора область Домены и пройдите по ссылке PBX.
Каждый Домен CommuniGate Pro имеет свою собственную Среду Приложения. Для изменения этой Среды, откройте через Веб Интерфейс Администратора область Домены, откройте для требуемого Домена его Установки и пройдите по ссылке PBX.
Изменения общекластерной Среды, а также изменения Среды для Общих Доменов автоматически распространяются на все члены Кластера.
Так как Домены могут иметь свои собственные Среды Приложений, различные приложения в разных Доменах могут иметь одинаковые имена.
Все файлы Среды Приложений для символов вне ASCII должны использовать кодировку UTF-8.
Иерархия файлов среды
Задачи Приложений Реального Времени выполняются «от имени» определённого Пользователя CommuniGate Pro.
Когда Приложению требуется «файл среды» и выбран язык по умолчанию, Сервер ищет этот файл последовательно в:
Среде Домена Пользователя.
общесерверной Среде (или, если Пользователь находится в Общем Домене) в общекластерной Среде.
в Стандартной Среде.
Если выбран язык, не являющийся языком по умолчанию, то Сервер ищет этот файл в языковых поддиректориях вышеперечисленных Сред. Если файл не найден в какой-либо из этих директорий, то осуществляется поиск в самих вышеперечисленных Средах. Таким образом, если файл для требуемого языка не был создан, то будет использоваться язык по умолчанию (Английский).
Такая иерархия обеспечивает простую настройку Приложений. Пользователи во всех Доменах могут использовать одинаковые Стандартные или общесерверные Приложения, а Администраторы конкретного Домена могут настраивать эти приложения под свой домен, загружая пользовательские файлы в Среды своего Домена.
Управление средами
Веб Интерфейс Администратора имеет страницы для Редактирования Среды Приложений Реального Времени, которые позволяют обслуживать общесерверные, общекластерные и доменные Среды Приложений.
Для обслуживания общесерверных и общекластерных Сред, откройте через Веб Интерфейс Администратора раздел Пользователи нажмите на ссылку PBX.
Для обслуживания Среды Домена, откройте через Веб Интерфейс Администратора раздел Пользователи, выберите требуемый Домен и нажмите на ссылку PBX. Для создания и изменения Среды Приложений Домена Администратор Домена должен обладать правом доступа "Может модифицировать PBX Приложения (CanModifyPBXApps )".
Страница Редактирование Среды содержит список всех "видимых" в этой Среде файлов: тут перечисляются как файлы, непосредственно загруженные в эту конкретную Среду, так и все файлы, загруженные в Среды и используемые как источник "файлов по умолчанию" для этой Среды:
Файлы, непосредственно загруженные в Среду, имеют флажок в столбце Помеченные. Файлы из других Сред, "видимые" в этой Среде, имеют в этом столбце слово default.
Вы можете скачать любой файл из Среды, щёлкнув по имени файла.
Вы можете загрузить в Среду файл, нажав на кнопку Выбор Файла и выбрав файл, находящийся на вашем компьютере, а затем нажав на кнопку Загрузить Файл.
Вы можете удалить любой из загруженных в Среду файлов, отметив его флажком и нажав на кнопку Удалить Помеченные.
Если вы загружаете в Среду файл с расширением .sppr или .sppi, то Редактор предполагает, что в этом файле содержится код какой-либо CG/PL программы и пытается скомпилировать этот код.
Если вы загружаете в Среду файл с расширением .settings, то Редактор предполагает, что в этом файле содержится словарь и пытается разобрать его.
Если компилятор обнаруживает ошибку, то файл не загружается в Среду, содержимое файла отображается на странице Редактирования, и маркер красного цвета <—ERROR→ показывает точное место ошибки.
Сервер помещает используемые файлы Среды Реального Времени во внутренний Кэш. Если вы загружаете файл в любую Среду, то Кэш среды очищается автоматически. Если вы загружаете файл в Среду Кластерного Домена или в общекластерную Среду, то изменённый файл автоматически распространяется по всем членам Кластера.
Вы можете загрузить набор файлов, выбрав TAR-архив (файл с именем расширения .tar). Например, если у вас есть TAR-архив с созданными ранее Приложениями Реального Времени, вы можете открыть Среду, которую вы хотите изменить и загрузить в неё файл .tar. Сервер распакует архив и будет сохранять каждый файл индивидуально, как будто бы они загружались по отдельности.
На странице Редактирования содержится также список всех языковых директорий:
Для создания нового Варианта, введите его название и нажмите на кнопку Создать.
Для того, чтобы открыть языковую директорию, щёлкните мышкой по её имени. Редактор отобразит имя Языка и ссылку Наверх, с помощью которой вы можете вернуться к списку файлов языка по умолчанию.
CLI/API
Для управления Средами Приложений может использоваться Интерфейс Командной Строки/API. Дополнительную информацию смотрите в разделе Администрирование Приложений Реального Времени.
Виртуальные Области в Хранилище Файлов
Среда Приложений может быть изменена при помощи клиентов, работающих по протоколам FTP и HTTP, приложений CG/PL или любых других методов, обеспечивающих доступ к Хранилищу Файлов Пользователя.
Специальные директории
$DomainPXBApp, $
Модель приложения
Приложения Реального Времени запускаются как Задачи. Запуская Приложение, Сервер CommuniGate Pro запускает новую Задачу и указывает ей начать выполнение с main - точки входа раздела кода указанного Приложения.
Задача Приложения Реального Времени может быть запущена в режиме disconnected, а может являться частью какой-либо одной сессии Реального Времени (такой, как телефонный звонок) с некоторым участником/абонентом (peer). Участником является любая единица, принимающая участие в коммуникациях Реального Времени, например: SIP телефон, шлюз в ТфОП, удалённое Приложение Реального Времени, взаимодействующее через SIP протокол, локальное Приложение Реального Времени (то есть, некоторая другая Задача).
Если Задача взаимодействует с каким-либо участником в сессии, она может работать в одном из следующих режимов:
incoming
входящая сессия (в телефонной терминологии - звонок, в SIP терминологии - запрос INVITE) была направлена Задаче, но Задача ещё не приняла сессию (звонок).
provisioned
входящая сессия была направлена Задаче, Задача ещё не приняла сессию, но уже отправила предварительный ответ вызывающей стороне.
connecting
задача инициировала исходящую сессию (звонок), но сессия ещё не была установлена.
connected
Задача приняла водящую сессию или Задача установила исходящую сессию.
Задача может как получать от участника Сигналы, так и отправлять Сигналы сама. Сигналы могут использоваться для окончания текущей сессии, изменения параметров сессии и т.д. Некоторые из Сигналов, отправляемые участнику, обрабатываются непосредственно самой Средой для Приложений Реального Времени, тогда как другие Сигналы передаются на обработку Задаче.
Задача Приложения Реального Времени может иметь связанный с ней Медиа Канал. При установлении сессии, Медиа Канал Задачи соединяется с медиа каналом участника.
Задача может использовать свой Медиа Канал для отправки медиа (аудио, видео) данных участнику, а также для записи отправляемых участником медиа данных.
Задача может переключать медиа поток участника на другие направления - например, для отделения сервиса музыка при ожидании от других медиа сервисов. При переключении (отключении) медиа, поступающего от участника, Медиа Канал Задачи не может использоваться, но Задача все ещё может контролировать участника, отправляя ему Сигналы, а также будет в состоянии получать Сигналы от участника. Задача может переключить (подключать) медиа, поступающее к/от участника обратно, к своему собственному Медиа Каналу.
Медиа Канал создаёт пространство разговора. Задача может присоединять медиа от других участников к собственному Медиа Каналу Задачи. Эта операция создаёт пространство разговора (или конференцию), которая включает в себя собственного участника Задачи и всех участников, чьи медиа потоки присоединены к этой Задаче. Медиа, отправляемое любым участником, находящимся в пространстве разговора, ретранслируется на всех других участников в этом пространстве, используя специальные алгоритмы смешивания данных и параметры, заданные для этого типа медиа.
Задача с присоединённым медиа участника может использовать свой Медиа Канал для одновременной отправки медиа данных как своему собственному участнику, так и всем присоединённым участникам.
Перевод звонка
Задачи Приложения Реального Времени могут автоматически обрабатывать запросы на Перевод Звонка.
При получении Задачей запроса REFER (от удалённого клиента или от другой Задачи), она может:
обработать его автоматически (этот метод используется по умолчанию)
отвергнуть его
передать его в приложение
Если Задача настроена на автоматическую обработку запросов REFER, она создаёт новый запрос INVITE и отправляет его на адрес, указанный в поле Refer-To:. В процессе обработки запроса INVITE задача информирует участника о ходе обработки, отправляя запросы NOTIFY.
Если запрос INVITE выполнен успешно, то Задача посылает текущему участнику Сигнал BYE (если только она сама не получила ранее Сигнал BYE от текущего участника) и затем она переключает свои диалоги по обмену Сигналами и Медиа Канал на нового участника:
Сигнал INVITE, инициированный сигналом REFER, может содержать данные аутентификации. Приложение может указать Задаче:
аутентифицировать сигнал INVITE как сигнал, приходящий от текущего Пользователя. Этот метод используется по умолчанию.
аутентифицировать сигнал INVITE как сигнал, приходящий от участника/абонента (от единицы, отправившей сигнал REFER).
отвергать сигналы REFER.
Для обработки "сопровождаемого" Перевода Звонка, ядро Приложения Реального Времени определяет все сигналы INVITE, в которых присутствуют поля Replaces. Если данные из диалога, указанные в полях Replaces, соответствуют активному диалогу, установленному в любой Задаче Реального Времени, то сигнал INVITE направляется этой Задаче. Задача посылает текущему участнику сигнал BYE и переключает свой сигнальный диалог на источник этого сигнала INVITE, а также переключает на единицу, отправившую сигнал INVITE, свой Медиа Канал.
Эта обработка происходит автоматически и является прозрачной для приложения, в котором обрабатывается Задача.
Мост между звонками
Пара Задач Приложений Реального Времени может построить Медиа Мост. При создании Медиа Моста участники Задачи обмениваются медиа, но каждая Задача оставляет за собой контроль за сигналами, идущими от участника.
Для построения моста:
приложение некоторой работающей Задачи A использует функцию CG/PL StartBridge для отправки специального события [bridgeStart] Задаче B. В запросе содержится описание медиа участника текущей Задачи A.
запущенное приложение Задачи B получает этот запрос.
приложение Задачи B использует функцию CG/PL AcceptBridge для построения моста.
ядро Приложения Реального Времени посылает сигнал re-INVITE участнику Задачи B, переключая его Медиа на Медиа участника Задачи A.
ядро Приложения Реального Времени посылает событие [bridgeResponse] в Задачу A. Это событие содержит описание медиа участника Задачи B.
в Задаче B завершается операция AcceptBridge и приложение Задачи B продолжает работу.
когда Задача A получает событие [bridgeResponse], ядро Приложения Реального Времени обрабатывает это событие самостоятельно и не доставляет его в приложение Задачи A.
ядро Приложения Реального Времени отправляет re-INVITE участнику Задачи A, переключая его Медиа на Медиа участника Задачи B.
операция StartBridge в Задаче A завершается и приложение Задачи A продолжает работу.
Если между Задачами A и B построен мост, то одна из Задач (в нашем примере - Задача B) может получить от своего участника сигнал re-INVITE. Новое описание медиа в этом сигнальном запросе может попросить Задачу изменить параметры её медиа (приостановить/продолжить, переключить на другой источник медиа и т.д.). Этот сигнал re-INVITE обрабатывается автоматически и не требует участия со стороны работающего приложения Задачи:
ядро Приложения Реального Времени посылает специальное событие [bridgeUpdate] в Задачу A. Это событие содержит новое описание медиа.
ядро Приложения Реального Времени самостоятельно обрабатывает событие [bridgeUpdate] и не доставляет его в работающее Приложения Задачи A.
ядро Приложения Реального Времени посылает сигнал re-INVITE участнику Задачи A, переключая его на новый источник Медиа участника Задачи B.
ядро Приложения Реального Времени посылает новое описание медиа участника A (полученное в отклике re-INVITE) Задаче B как специальное событие [bridgeResponse].
когда Задача B получает событие [bridgeResponse], ядро Приложения Реального Времени обрабатывает его самостоятельно и не доставляет его в приложение Задачи B.
новое полученное описание медиа Задачи A отправляется участнику B как отклик на начальный сигнал re-INVITE, переключая участника Задачи B на новое медиа участника Задачи A.
Если между Задачами A и B построен мост, то одна из Задач (в нашем примере - Задача A) может получить от своего участника запрос на Перевод Звонка (REFER):
ядро Приложения Реального Времени формирует сигнал INVITE для Задачи A и отправляет его участнику; в Сигнале содержится описание медиа участника Задачи B.
сигнал INVITE заканчивается успешно, описание медиа нового участника Задачи A (участника C) получено.
ядро Приложения Реального Времени автоматически посылает специальное событие [bridgeUpdate] в Задачу B с новым описанием медиа участника.
когда Задача B получает событие [bridgeUpdate], ядро Приложения Реального Времени обрабатывает это событие самостоятельно и не доставляет его в приложение Задачи B.
ядро Приложения Реального Времени посылает сигнал re-INVITE участнику Задачи B, переключая его на источник Медиа нового участника Задачи A.
Если между Задачами A и B построен мост, то одна из Задач (в нашем примере - Задача A) может получить от своего участника сигнал запроса на Перевод Звонка - INVITE, в котором есть Replaces (доставляемый модулем Signal в зависимости от содержимого полей Replaces):
ядро Приложения Реального Времени автоматически посылает специальное событие [bridgeUpdate] в Задачу B с новыми параметрами медиа участника A.
ядро Приложения Реального Времени посылает сигнал re-INVITE участнику Задачи B, переключая его на источник Медиа нового участника Задачи A.
ядро Приложения Реального Времени отправляет отклик INVITE новому участнику Задачи A, с параметрами медиа участника Задачи B, соединяя нового участника Задачи A с медиа участника Задачи B.
Если между Задачами A и B построен мост, то одна из Задач (в нашем примере - Задача A) может разорвать Медиа Мост:
приложение Задачи A использует функцию BreakBridge CG/PL для того, чтобы разорвать Медиа мост.
ядро Приложения Реального Времени автоматически отправляет специальное событие [bridgeClose] в Задачу B и посылает сигнал re-INVITE участнику Задачи A, переключая его на Медиа Канал Задачи A.
когда Задача B получает событие [bridgeClose], ядро Приложения Реального Времени автоматически отправляет запрос re-INVITE участнику Задачи B, переключая его на Медиа Канал Задачи B.
ядро Приложения Реального Времени доставляет событие [bridgeClose] приложению Задачи B.
Если между Задачами A и B построен мост, то одна из Задач (в нашем примере - Задача A) может получить от своего участника сигнал на отсоединение (BYE), либо участник может прекратить работу по каким-либо другим причинам. В этом случае:
ядро Приложения Реального Времени автоматически посылает специальное событие [bridgeClose] в Задачу B.
когда Задача B получает событие [bridgeClose], ядро Приложения Реального Времени автоматически отправляет запрос re-INVITE участнику Задачи B, переключая его на Медиа Канал Задачи B.
ядро Приложения Реального Времени доставляет событие [bridgeClose] приложению Задачи B.
Ядро Приложения Реального Времени может создавать Медиа Мост, используя Медиа Канал Задачи как "медиа релей" (ретранслятор медиа).
B2BUA (узел сопряжения)
Функциональность Моста между Звонками используется в технологии B2BUA. Пара Задач Реального Времени, соединённая через Мост, может работать как "умный прокси": в то время, как участники, соединённые с этими задачами, взаимодействуют напрямую, управляющие сигналы между ними контролируются Задачами и приложения Задач не прекращают свою работу.
CG/PL приложения
Приложения Реального Времени могут быть написаны на языке CG/PL.
Если Задача создаётся для обработки входящего звонка, то её выполнение начинается с точки входа main указанного CG/PL приложения.
Приложения Реального Времени могут использовать поддерживаемую в CG/PL возможность внешнего объявления. Когда вызывается раздел кода (процедура или функция), объявленный как внешний, то из среды загружается файл с именем раздела кода и расширением .sppi. Код программы в этом файле должен содержать раздел кода с указанным именем и требуемым типом (процедуру или функцию).
Код программы в файле .sppi может содержать также и другие разделы программы.
В Приложении Реального Времени могут использоваться следующие встроенные процедуры и функции.
Ввод
ReadInput(timeOut)
Эта функция используется для получения Задачей разнообразных событий: символ DTMF (символ тонового набора), введённый участником, сигналы, отправленные участником, а также События, отправляемые как другими Задачами, так и самой системой. Дополнительную информацию смотрите в разделе CG/PL События.
Значение timeOut должно быть числом, задающим максимальный период ожидания (в секундах). Если значение timeOut является нулём, то функция проверяет наличие уже ожидающих прочтения цифр или событий, не ожидая дополнительно.
Функция возвращает:
строку с первым символом DTMF из DTMF буфера Задачи. Этот символ удаляется из буфера Задачи.
словарь с первым ожидающим Событием. Событие удаляется из очереди Событий Задачи.
нулевое значение, если в течении указанного периода времени не был получен DTMF символ или Событие.
При отсоединении участника, Задача получает от системы Событие Disconnect (в словаре этого События отсутствует элемент .sender).
IsDisconnectEvent(input)
Эта функция возвращает истину, если значением input является Событие Disconnect.
//// Пример: ReadInput()// Принять входящий звонок (остановиться, если не удалось).// Проиграть звуковой файл PressPound.// Подождать 5 секунд каких-нибудь событий.// Если символ "решётка" ("#") был нажат,// проиграть звуковой файл Good.// Иначе,// проиграть звуковой файл Bad.// Остановиться.//entry Main isif AcceptCall() != null then stop; end if;PlayFile("PressPound");PlayFile(ReadInput(5) == "#" ? "Good" : "Bad");end entry;
Сигналы
AcceptCall()
Эта функция принимает входящую сессию при условии, если Задача находится в режиме incoming или provisioned.
Эта функция возвращает нулевое значение, если сессии принята успешно и Задача переведена в режим connected.
Если сессия не может быть принята, то эта функция возвращает строку с кодом ошибки и Задача переводится в режим disconnected.
13
RedirectCall(newURI)
Эта процедура перенаправляет входящую сессию при условии, что Задача находится в режиме incoming или provisioned.
Значение newURI должно быть строкой или массивом строк. Входящая сессия перенаправляется на указанный URI (несколько URI в случае массива), и Задача переводится в режим disconnected.
ForkCall(newURI)
Эта процедура перенаправляет входящую сессию при условии, что Задача находится в режиме incoming или provisioned.
Значение newURI должно быть строкой или массивом строк. Входящая сессия перенаправляется на указанный URI, но текущая Задача остаётся в том же состоянии и впоследствии сможет принять, отвергнуть, перенаправить, отправить промежуточный отклик или подключить другого участника.
ProvisionCall(media,reliably)
Эта функция отправляет промежуточный Ответ на Запрос входящей сессии, при условии, что Задача находится в режиме incoming или provisioned.
Если значение startMedia не является нулевым, то создаётся Медиа Канал Задачи, Задача переводится в режим provisioned и может использовать операции Медиа Канала (такие как PlayFile) для "контроля посылки вызова" ("тоны дозвона", КПВ).
Если значение reliably не является нулевым, то требуется подтверждение отклика (SIP PRACK) и Задача приостанавливается до момента прихода такого подтверждения.
Эта функция возвращает нулевое значение если ответ был успешно отправлен.
Если промежуточный ответ не может быть отправлен, то эта функция возвращает строку с кодом ошибки.
ProvisionCall(parameters)
Функция является расширением описанного выше варианта функции ProvisionCall. Параметры функции передаются в виде словаря parameters, который может содержать следующие элементы:
media
если этот элемент указан, то он имеет тот же эффект, как ненулевое значение параметра media описанного выше варианта функции ProvisionCall.
reliably
если этот элемент указан, то он имеет тот же эффект, как ненулевое значение параметра reliably описанного выше варианта функции ProvisionCall.
responseCode
если этот элемент указан, его значением должно быть число из диапазона 101..199 (включительно). Он задаёт код ответа, который будет отправлен. Если этот элемент отсутствует, то используется значение 180.
responseText
если этот элемент указан, его значением должна быть строка. Она задаёт текстовый код ответа, который будет отправлен. Если этот элемент отсутствует, то используется значение по умолчанию.
reasonCode
если этот элемент указан, его значением должно быть позитивное число. В ответ будет добавлен заголовок Reason, со значением составленным из этого элемента и reasonText.
Если значение этого элемента меньше 1000, в качестве протокола в заголовке используется SIP, в противном случае используется протокол Q.850, и из значения вычитается 1000.
reasonText
если этот элемент указан, его значением должна быть строка. Этот элемент используется только совместно с reasonCode.
RejectCall(responseCode)
Эта процедура отвергает входящую сессию при условии, что Задача находится в режиме incoming или provisioned.
Значением responseCode должно быть числовое значение между 400 и 699. Это число отправляется обратно вызывающей стороне как код Ответа на Сигнал. Если обратно отправляется код 401, и запрос пришёл извне Сервера CommuniGate Pro (через SIP протокол), то модуль SIP сервера добавляет надлежащие поля в ответ, чтобы способствовать Аутентификации клиента.
Параметром responseCode может быть словарь с необязательными полями responseCode, responseText, reasonCode, reasonText, которые имеют тот же смысл, что поля параметра функции ProvisionCall().
Задача переводится в режим disconnected.
//// Пример: RedirectCall()/ProvisionCall()// Дать предварительный ответ на звонок (остановиться, если не получилось).// Если местное время между 12:00 и 13:00,// ответвить звонок ещё и на user1 в этом же домене.// Проиграть звуковой файл «PleaseWait».// Если местное время - до 8:00 или после 17:00,// перенаправить звонок на user2 в этом же домене и остановиться.// Иначе,// Принять звонок (остановиться, если не получилось).// Проиграть звуковой файл Welcome и остановиться.//entry Main isif ProvisionCall(true,true) != null then stop; end if;currentTime = TimeOfDay(GMTToLocal(GMTTime()));currentHour = currentTime / 3600;if currentHour >= 12 and currentHour <= 13 thenForkCall("sip:user1@" + MyDomain());stop;end if;PlayFile("PleaseWait");if currentHour < 8 or currentHour >= 17 thenRedirectCall("sip:user2@" + MyDomain());stop;end if;if AcceptCall() != null then stop; end if;PlayFile("Welcome");end entry;
Обратите внимание: если ожидающий входящий звонок был прерван, то Задача получает событие Disconnect, и её состояние изменяется на disconnected.
SetCallParameters(parameters)
Эта процедура устанавливает параметры звонка (диалог INVITE).
Значение parameters должно быть словарём с новыми параметрами звонка. Существующие значения параметров удаляются.
Для всех запросов диалога используются следующую параметры:
Max-Forwards
положительное число, используемое для ограничения числа "переходов" ("хопов"), которое может проходить запрос.
customIdentity
строка или словарь, используемая как значение заголовка P-Asserted-Identity. Это поле добавляется также в предварительные ответы.
Privacy
строка или массив строк, которые будут использоваться как поле заголовка Privacy.
IPSource
адрес IP, который переопределяет правила Сервера и явно устанавливает адрес IP источника для исходящих пакетов SIP и локально генерируемых медиа данных.
allowedAudioCodecs
массив со списком аудио кодеков, которые могут быть включены в описание медиа (SDP), отправляемое этой задачей своим абонентам.
allowedVideoCodecs
массив со списком видео кодеков, которые могут быть включены в описание медиа (SDP), отправляемое этой задачей своим абонентам. Если этот массив пуст, отправляемый объект SDP не включает медиа поток для видео, если только это не ответ на предложение с видео потоком в SDP.
allowedSSRC
если этот параметр установлен в "NO", все атрибуты "ssrc" удаляются из SDP.
allowedAttributes
если значение параметра - "nonCustom", то все нестандартные атрибуты (с именами, начинающимися с x-) удаляются из SDP.
если значение параметра - "required", все необязательные атрибуты удаляются из SDP. Атрибуты "phone", "info", "uri", "email", "time", "zone", "key", "bandwidth", "title" тоже удаляются из SDP.
Следующие параметры используются при установлении диалогов:
Session-Expires
неотрицательное число, задающее время действия сессии по умолчанию (время обновления диалога). Если устанавливается значение, равное нулю, то обновления диалога не происходит.
Некоторые параметры используются при установлении звонка (функциями StartCall, StartBridgedCall), а некоторые - при приёме звонка (функцией AcceptCall) - смотрите ниже.
StartCall(destination)
Эта функция инициирует исходящую сессию. Задача должна быть в состоянии disconnected.
Значение destination должно быть строкой, содержащий URI, на который отправляется запрос на сессию, или словарём, содержащим следующие элементы:
"" (пустая строка)
URI, на который отправляется запрос на сессию.
From (необязательно)
адрес электронной почты, URI или другие данные, используемые в поле From. Если они не указаны, то используются данные текущего Пользователя.
To (необязательно)
адрес электронной почты, URI или другие данные, используемые в поле To. Если они не указаны, то используется URI запроса.
Call-ID (необязательно)
строка, используемая для поля Call-ID запроса. Если она не указана, то генерируется новый Call-ID.
Следующие необязательные параметры берутся из словаря destination. Если они отсутствуют (или destination не является словарём), то они берутся из параметров текущего звонка, заданных при помощи процедуры SetCallParameters:
authUsername, authPassword
данные аутентификации (имя и пароль) для использования в исходящем запросе после получения ответа 401.
Expires
число, указывающее максимальную продолжительность вызова (в секундах).
Subject
строка Subject запроса.
Remote-Party-Id
массив словарей, используемых для создания полей заголовка Remote-Party-Id.
Privacy
строка или массив строк, используемая для создания поля Privacy запроса.
Diversion
массив, используемый для создания полей Diversion запроса.
P-CGP-Private
строка, используемая для создания поля P-CGP-Private запроса. Это поле может использоваться для передачи произвольных параметров между отправляющей и принимающей Задачами (в одной или разных системах).
P-CGP-Local
строка, используемая для создания поля P-CGP-Local запроса. Это поле может использоваться для передачи произвольных параметров между отправляющей и принимающей Задачами (только в пределах одного сервера или в пределах одного Кластера).
P-Billing-Id
строка, используемая для создания поля P-Billing-Id запроса. Эта строка попадает и в детализацию звонков (записи CDR, создаваемые самим сервером).
Call-Info
массив, используемый для создания полей Call-Info запроса.
Alert-Info
строка, используемая для создания поля Alert-Info запроса.
Replaces
строка или словарь, с помощью которых создаётся поле Replaces запроса. Если используется словарь, то он должен содержать строковые значения Call-ID, fromTag, toTag и логическое значение early-only.
Via
если этот атрибут задан, то он должен содержать URI. Этот URI добавляется в запрос как один из элементов маршрута (Route), чтобы запрос прошёл через указанный URI.
NoInitSDP
если задан этот параметр, то запрос на установление звонка не содержит SDP локального Медиа Канала.
No100rel
если указан этот параметр, в исходящем запросе не объявляется поддержка расширения SIP "100rel".
mediaRelay
если задан этот параметр, то для звонка всегда используется Проксирование Медиа.
TimerB
если указан этот параметр, то его числовое значение используется вместо стандартного значения "Таймера B" протокола SIP: система ожидает указанное количество секунд какого-либо ответа (например, 100-Trying) на отправленный запрос.
Relay
если этот параметр задан и его значение - "NO", то исходящий запрос по протоколу SIP не сможет быть переправлен на адреса, не входящие в список клиентских.
encryptMedia
если этот параметр задан и его значение - "NO", отправляемые этой Задачей предложения SDP не будут содержать атрибутов, необходимых для шифрования медиа потоков.
Эта функция возвращает строку с кодом ошибки, если исходящий вызов не может быть инициирован.
Если исходящий вызов был успешно инициирован, то функция возвращает нулевое значение и Задача начинает получать от системы События, возникающие во время звонка: ноль или больше Событий с предварительными ответами, за которым следует одно Событие с окончательным ответом.
Если исходящая сессия задача была успешно установлена, то Задача получает Событие с окончательным ответом без параметров.
Если исходящая сессия задача не была успешно установлена, то Задача получает Событие с окончательным ответом, в котором есть параметр: строка с кодом ошибки.
IsCallProvisionEvent(input)
Эта функция возвращает истину, если значением input является Событие с предварительным ответом на вызов. В противном случае функция возвращает нулевое значение.
IsCallCompletedEvent(input)
Эта функция возвращает истину, если значением input является Событие с окончательным ответом на вызов. В противном случае функция возвращает нулевое значение. Если Задача получает Событие с окончательным ответом, то процесс обработки сигналов вызова завершается. Если Событие имеет параметр, то звонок заканчивается неудачно; в этом случае в параметре содержится строка с кодом ошибки.
CancelCall()
Если у Задачи имеется ожидающий окончательного ответа исходящий вызов (инициированный при помощи функции StartCall), то эта процедура прекращает выполнение этого вызова (при этом Задача не получит События с окончательным ответом).
Disconnect()
Disconnect(reasonCode,reasonText)
Эта процедура заканчивает активную сессию (если есть), и Задача переводится в состояние disconnected.
Если был указан параметр reasonCode, его значением должно быть позитивное число, а значением reasonText должна быть строка. При посылке абоненту запроса BYE, в него будет добавлен заголовок Reason с составленными из reasonCode и reasonText значением.
//// Пример: StartCall()/Disconnect()// Принять входящий звонок (остановиться, если не удалось).// Запомнить URI вызывающей стороны.// Проиграть звуковой файл CallBack.// Disconnect();// Вернуть звонок (остановиться, если не получилось).// Проиграть звуковой файл IamBack и остановиться.//entry Main isif AcceptCall() != null then stop; end if;fromWhom = RemoteURI();PlayFile("CallBack");Disconnect();if StartCall(fromWhom) != null then stop; end if;loopinput = ReadInput(3600);exitif not IsCallProvisionEvent(input);null;end loop;if not IsCallCompletedEvent(input) or elseinput.parameter != null then stop; end if;PlayFile("IamBack");end entry;
IsConnected()
Эта функция возвращает истину, если Задача находится в состоянии connected.
IsHalfConnected()
Эта функция возвращает истину, если Задача находится в состояниях connected или provisioned.
Диалог
RemoteURI()
Эта функция возвращает строку с URI абонента (взятых из адресов диалога From/To). Если сессия отсутствует, функция возвращает нулевое значение.
LocalURI()
Эта функция возвращает строку с URI Задачи.
IncomingRequestURI()
Эта функция возвращает строку с URI ожидающего ответа входящего запроса INVITE. Если ожидающий ответа входящий запрос INVITE отсутствует, то функция возвращает нулевое значение.
RouteLocalURI(uri)
Эта функция пытается провести Маршрутизацию для адреса электронной почты, задаваемого URI. Если URI не может быть разобран или для адреса из URI невозможно провести маршрутизацию, или он маршрутизируется в адрес, не являющийся локальным (то есть, адрес электронной почты принадлежит другой системе), то функция возвращает нулевое значение. В противном случае функция возвращает адрес электронной почты того пользователя CommuniGate Pro, на которого указывает адрес из URI после проведения маршрутизации.
Эта функция позволяет вам корректно обрабатывать все Переадресаторы, Псевдонимы и другие методы маршрутизации, используемые в CommuniGate Pro.
RemoteIPAddress()
Эта функция возвращает объект типа адрес IP, с которого был получен или на который был отправлен запрос на установление сессии. Эта пара IP адрес/порт является фактическим адресом абонента или адресом прокси, используемого для ретрансляции сигналов абонента.
RemoteAuthentication()
Эта функция возвращает либо нулевое значение, если запрос на начало сессии не был аутентифицирован, либо строку с адресом электронной почты аутентифицированного пользователя.
PendingRequestData(fieldName)
Эта функция возвращает элемент данных из ожидающего ответа входящего запроса.
Если запрос ожидает ответа, то функция возвращает следующие данные, в зависимости от значения fieldName, которое должно являться строкой:
Call-ID
функция возвращает строку со значением Call-ID запроса.
From, To, Referred-By
функция возвращает словарь, если такое поле существует в этом запросе. В словаре содержатся следующие элементы:
"" (элемент с пустой строкой-ключом)
адрес (в форме username@domain)
@realName
строка, в которой содержится часть адреса "отображаемое имя" (Display Name)
@schema
строка со схемой URI запроса (sip, если схема не указана явно)
@port
номер порта, указанный в URI
@tag
параметр "tag" заголовка
@field-params
словарь с другими параметрами заголовка.
@headers
словарь с заголовками URI.
anyOtherName
параметр URI.
Все элементы, кроме адреса, являются необязательными.
Remote-Party-Id, History-Info
функция возвращает массив, если такое поле существует в этом запросе. Каждый элемент массива является словарём, в котором содержатся следующие элементы аналогично заголовку From.
Foreign-Asserted-Identity
функция возвращает массив словарей с полями P-Asserted-Identity запроса. Каждый словарь содержит такие же элементы, как и словарь для заголовка From.
Route, Record-Route, Diversion, Via, Path, Supported, Require, Proxy-Require, Privacy, Allow, Allow-Events
функция возвращает массив, содержащий одну или более строк со значениями полей. Если никаких значений не существует, то функция возвращает нулевое значение.
CSeq
функция возвращает число - значение числовой части поля CSeq.
Max-Forwards
функция возвращает число - значение поля Max-Forwards.
User-Agent, Reason, P-CGP-Private, P-CGP-Local
функция возвращает строку - значение поля. Если поле отсутствует, то функция возвращает нулевое значение.
Accept
функция возвращает массив, содержащий 2 строки для каждого значения поля: допустимый тип содержимого (content type) и допустимый подтип содержимого (content subtype). Если поле отсутствует, то функция возвращает нулевое значение.
xmlsdp
функция возвращает представление XML для данных SDP в запросе.
Если нет ожидающего ответа запроса, то функция возвращает нулевое значение.
PendingRequestExData(fieldName)
Эта функция возвращает нестандартный элемент данных ожидающего ответ входящего запроса.
Значение fieldName должно быть строкой. В ней указывается имя нестандартного поля запроса.
Если запрос ожидает ответа, то функция возвращает строку, в которой содержатся данные из указанного поля запроса.
Если ожидающего ответа запроса нет, то функция возвращает нулевое значение.
SetLocalContactParameter(paramName,paramValue)
Эта процедура позволяет установить параметры заголовка Contact, используемого в запросах и ответах диалога этой Задачи.
Значение paramName должно быть строкой. В нём указывается имя параметра.
Если значением paramValue является непустая строка, то она указывает значение параметра.
Если для paramValue указана пустая строка, то добавляется параметр без значения (такой как isfocus).
Если значением paramValue является непустая строка, то она указывает значение параметра.
DTMF
Каждая Задача имеет строку буфера DTMF (буфера тонового набора). При получении символа DTMF либо в Запросе INFO, либо в пакете медиа данных (через Медиа Канал), символ добавляется в этот буфер.
DTMF()
Эта функция возвращает строку с текущим содержанием буфера DTMF. Буфер DTMF не изменяется. Обычно эта функция не используется; используйте вместо неё функцию ReadInput().
ClearDTMF()
Эта процедура очищает буфер DTMF.
SetInterruptOnDTMF(arg)
Эта функция устанавливает флаг, прерывающий воспроизведение медиа при получении символов DTMF.
Значение arg задаёт новое значение флага: если его значение является нулевым, то получение символов DTMF не прерывает воспроизведение медиа, в противном случае получение символов DTMF прерывает воспроизведение медиа.
При создании Задачи значение этого флага устанавливается в значение истина.
Функция возвращает предыдущее значение этого флага.
SendDTMF(symbol)
Эта функция посылает абоненту символ DTMF.
Значение symbol должно быть строкой, в которой содержится 1 символ DTMF.
Эта функция возвращает нулевое значение, если символ был отправлен; в противном случае возвращается строка с кодом ошибки.
//// Пример: ReadInput()/SendDTMF()// Принять входящий звонок (остановиться, если не удалось).// В течение 10 секунд подождать ввода. Если ввода нет - остановиться.// Если введена цифра// проиграть эту цифру и послать её обратно.// (используя файлы с записью произношения цифр "0" ... "9")// Если введена звёздочка ("*"),// подождать цифру (3 секунды)// и проиграть значение квадрата цифры (2 цифры)// При вводе ("#"), или если Абонент// отсоединился, или Поступило любое другое событие, то остановиться.//entry Main isif AcceptCall() != null then stop; end if;loopinput = ReadInput(10);if input == «*» theninput = ReadInput(3);if IsString(input) and input != "#" theninput = "*" + input;end if;end if;exitif not IsString(input) or input == "#";if Substring(input,0,1) != "*" thenPlayFile(input);void(SendDTMF(input));elseinput = Number(Substring(input,1,1);product = input * input;PlayFile(String(product/10));PlayFile(String(product%10));end if;end loop;end entry;
Медиа
PlayFile(fileName)
PlayFile(fileName,msec)
Эта процедура запрашивает файл из Среды Приложения и воспроизводит его. В строковом параметре fileName задаётся имя файла. Если указанное имя файла не содержит расширения файла, то к нему добавляются поддерживаемые расширения, и попытка повторяется.
Файл должен содержать медиа данные в одном из поддерживаемых форматов.
Значение msec, если указано, должно быть числом. Эта процедура воспроизводит указанный файл в течении msec миллисекунд, повторяя, если время его воспроизведения короче, чем указанный период, файл с начала. Если параметр msec имеет отрицательное значение, то файл воспроизводится в цикле без ограничения времени.
Воспроизведение останавливается или прерывается, если сессия заканчивается или буфер DTMF не пуст (если только Прерывание при DTMF не было выключено), или если Задаче было направлено Событие.
Play(waveData)
Play(waveData,msec)
Эта процедура воспроизводит блок данных waveData.
Блок данных должен содержать медиа данные в одном из поддерживаемых форматов.
Если указан параметр msec, он обрабатывается аналогично процедуре PlayFile.
Воспроизведение останавливается или прерывается, если сессия заканчивается или буфер DTMF не пуст (если только Прерывание при DTMF не было выключено), или если Задаче было направлено Событие.
PlayTone(freq,msec)
PlayTone(freq,msec,freq2)
PlayTone(freq,msec,freq2,ratio)
Процедура проигрывает "тон" (синусоидальную волну). Значение freq должно быть неотрицательным числом - частотой волны (в Герцах). Если значение равно нулю, то генерируется тишина.
Если указан параметр msec, он обрабатывается аналогично процедуре PlayFile.
Если указан параметр freq2, генерируется комбинация двух синусоидальных волн, а значением параметра должно быть положительное число с частотой второй волны (в Герцах).
Значение ratio, если указано, должно быть положительным числом в диапазоне 0..10000. Оно задаёт относительную амплитуду второй волны из расчёта, что амплитуда первой принята за 100.
Воспроизведение останавливается или прерывается, если сессия заканчивается или буфер DTMF не пуст (если только Прерывание при DTMF не было выключено), или если Задаче было направлено Событие.
GetPlayPosition()
Эта функция возвращает число - часть медиа данных (в миллисекундах), воспроизведённая последней операцией PlayFile или Play.
Если медиа воспроизводилось по кругу, то длиной воспроизведённой части является продолжительность воспроизведения последнего "круга": так, если 3-х секундный отрывок проигрывался по кругу и его воспроизведение было прервано после 7.2 секунд, то функция возвращает значение 1200.
Если последняя операция Play* не воспроизводила звук (из-за того, что буфер тонового набора DTMF был не пустой или в очереди отсутствовало Событие), то функция возвращает либо 0, либо отрицательное значение.
SetPlayPosition(arg)
Эта процедура указывает непосредственно следующей за ней операции Play* начинать воспроизведение не с начала фрагмента.
Значение arg должно быть неотрицательным числом. Оно указывает количество миллисекунд, которое должно быть пропущено до начала воспроизведения медиа данных операциями Play*.
IsPlayCompleted()
Эта функция возвращает значение истина, если медиа данные были полностью проиграны последней операцией Play*. Если проигрывание медиа данных было прервано, то функция возвращает нулевое значение.
Record(timeLimit)
Эта функция записывает входящие аудио данные. Значение timeLimit должно быть положительным числом, задающим максимальную продолжительность записи в секундах.
Запись останавливается или прерывается, если сессия заканчивается или буфер DTMF не пуст, или если Задаче было направлено Событие.
Функция возвращает либо нулевое значение, если запись была остановлена, либо блок данных с записанным аудио в формате WAV.
SetLocalHold(flag)
Эта процедура ставит текущий вызов "на удержание" (если flag имеет значение истина) или снимает его с удержания (если flag имеет нулевое значение).
Эта процедура может использоваться только, когда задача находится в состоянии connected и медиа мост у Задачи отсутствует.
ReleaseMediaChannel()
Эта процедура освобождает Медиа Канал Задачи (и связанные с ним системные ресурсы).
Эта процедура может использоваться, когда Задача находится в состоянии disconnected, или у участника Задачи существует медиа мост.
MediaOption(optionName)
MediaOption(optionName,newValue)
Эта функция возвращает текущее значение опции Медиа Канала.
Если указан ненулевой параметр newValue, его значение используется для установки опции.
Значение optionName должно быть строкой - она определяет имя опции. Поддерживаются следующие опции:
"preplay"
числовая опция, определяет количество предзаписанных медиа данных (в миллисекундах) для отправки абоненту заранее, чтобы заполнить буферы борьбы с джиттером.
"mixerDelay"
числовая опция, задаёт задержку (в миллисекундах) для Медиа Канала, прежде чем он начинает получать входные данные для микширования с данными других медиа каналов в случаях, когда соединено более 2х активных Медиа Каналов (конференции). Чем больше задержка, с тем большим качеством миксер Медиа Канала может смешивать медиа потоки от участников конференции с неустойчивым сетевым соединением.
"inputSilenceLevel"
числовая опция, задаёт минимальный уровень входящих аудио данных. Если уровень (громкость) ниже указанного значения, данные обрабатываются, как если бы они были тишиной: не записываются и в случае миксеров с более чем 2 медиа каналам (конференции) такие данные не участвуют в микшировании.
"skipSilence"
числовая опция, задаёт ограничение по времени (в миллисекундах). Когда Медиа Канал записывает входящие медиа данные и уровень громкости этих данных ниже "уровня тишины" (смотрите выше), и эта фактическая тишина длится дольше указанного лимита времени, запись приостанавливается. Она продолжается сразу, как только громкость входящих аудио данных превысит "уровень тишины".
"stopRecordOnPause"
числовая опция, управляет записью тишины. Когда Медиа Канал записывает входящие медиа данные и уровень громкости этих данных ниже "уровня тишины" (смотрите выше), и эта фактическая тишина длится дольше лимита времени, указанного в опции "skipSilence", запись останавливается, если эта опция установлена в 1. Также симулируется получение приложением DTMF события #15.
"mixMOH"
числовая опция, указывает, должны ли микшироваться аудио данные от абонента, который поставил звонок на удержание и шлёт "музыку на удержании" (MOH). Если установлено значение 1, эти медиа данные обрабатываются, со значением по умолчанию 0 эти данные игнорируются.
Если к Медиа Каналу подсоединено не более двух абонентов, "музыка на удержании" (MOH) всегда обрабатывается.
//// Пример: Record()/PlayFile()/Play()// Принять входящий звонок (остановиться, если не удалось).// Проиграть звуковой файл GreetingIs.// Прочитать текущее приветствие из// файла MyGreeting.wav в Хранилище Файлов Пользователя.// Играть приветствие в цикле.// Если нажата "1", перезаписать файл приветствия и выйти// Если нажата "2" , проиграть "Beep" и записать приветствие.//entry Main isif AcceptCall() != null then stop; end if;PlayFile("GreetingIs");prompt = ReadStorageFile("MyGreeting.wav");loopif IsData(prompt) then Play(prompt); end if;input = ReadInput(10);exitif not IsString(input) or else input == "#";if input == "1" thenif WriteStorageFile("MyGreeting.wav",prompt) thenPlayFile("Goodbye"); stop;end if;PlayFile("Failure");elif input == «2» thenPlayFile("Beep");prompt = Record(30);elsePlayFile("InvalidEntry");end if;end loop;PlayFile("GoodBye");end entry;
Мосты и миксеры
StartBridge(taskRef)
Эта функция посылает специальное Событие StartBridge указанной Задаче, с запросом на приём медиа абонента Задачи.
Значение taskRef должно быть описателем задачи. Оно задаёт Задачу, которой отправляется запрос.
Эта функция возвращает нулевое значение, если указанная Задача успешно переключила медиа абонента Задачи. В противном случае, функция возвращает строку с кодом ошибки.
Текущая Задача должна быть в состоянии incoming, provisioned или connected.
Текущая задача ставится в ожидание, требуемая Задача получает специальное Событие StartBridge.
IsStartBridgeEvent(input)
Эта функция возвращает истину, если значением input является Событие StartBridge. В противном случае функция возвращает нулевое значение.
RejectBridge(input,errorCode)
Эта функция отвергает запрос StartBridge.
Значение параметра input должно быть Событием StartBridge, которое необходимо отвергнуть.
Значение параметра errorCode должно быть строкой.
Функция StartBridge в Задаче, которая отправила Событие StartBridge, выходит из состояния ожидания и возвращает строку с кодом ошибки.
Эта функция возвращает нулевое значение, если ожидающий входящий звонок был успешно отвергнут. В противном случае, функция возвращает строку с кодом ошибки.
AcceptBridge(input)
Эта функция строит Медиа Мост с Задачей, которая отправила Событие StartBridge.
Значение параметра input должно быть Событием StartBridge, которое необходимо принять.
Эта функция возвращает нулевое значение, если Медиа Мост был установлен успешно. В противном случае, функция возвращает строку с кодом ошибки.
Функция StartBridge в Задаче, которая отправила Событие StartBridge, выходит из состояния ожидания. Та функция возвращает нулевое значение, если Мост был установлен; в противном случае возвращается строка с кодом ошибки. Если эта Задача находилась в состоянии incoming или provisioned, звонок принимается, и Задача переходит в состояние connected.
При успешной установке Медиа Моста между парой Задач, медиа их абонентов соединяются друг с другом. Медиа Каналы Задач отсоединяются от их абонентов и операции Медиа Каналов (PlayFile, Record и т.д.) использоваться не могут.
Пока Медиа Мост активен, Задача не может использовать функции StartBridge, AcceptBridge и AttachMixer.
BreakBridge()
Эта функция убирает Медиа Мост, созданный в результате успешного выполнения функции StartBridge или AcceptBridge.
Медиа Канал Задачи заново соединяется с медиа каналом абонента.
Задаче, с которой был построен Мост, отправляется специальное событие BreakBridge.
Эта функция возвращает нулевое значение, если существующий медиа мост был убран успешно. В противном случае, функция возвращает строку с кодом ошибки.
IsBreakBridgeEvent(input)
Эта функция возвращает истину, если значением input является Событие BreakBridge. В противном случае функция возвращает нулевое значение.
Когда Задача получает Событие BreakBridge, она не должна использовать процедуру BreakBridge(), так как Медиа Мост уже был удалён.
Если Задача отсоединяется от участника, или участник Задачи отсоединяется самостоятельно (штатно или в результате ошибки) и существует активный Медиа Мост, то этот Медиа Мост убирается автоматически.
//// Пример: StartBridge()/AcceptBridge()/BreakBridge()// Принять входящий звонок (остановиться, если не удалось).// Создать новую задачу, чтобы выполнить код Caller (инициатора звонка),// и послать ей Событие с URI, на который надо послать вызов.// Проиграть аудио файл PleaseWait.// Подождать События StartBridge от Задачи Caller.// Принять его и работать в цикле, пока пользователь не отсоединится.//// Код Caller:// В виде События от родительской Задачи получить URI, на который надо совершить звонок// Соединиться на этот URI и проиграть аудио файл YouGotACall// С помощью StartBridge установить мост, работать в цикле, пока пользователь не отсоединится//entry Caller forward;procedure ControlBridge() forward;entry Main isif AcceptCall() != null then stop; end if;callerTask = spawn Caller;if callerTask == null or elseSendEvent(callerTask,"dial","sip:internal@partner.dom") != null thenPlayFile("Failure");stop;end if;PlayFile("PleaseWait");input = ReadInput(30);if not IsStartBridgeEvent(input) or elseAcceptBridge(input) != null thenPlayFile("Failure");stop;end if;// we have established a bridgeControlBridge();PlayFile("GoodBye");end entry;//// Код Задачи Caller//entry Caller is// подождать событие «dial» от главной задачиinput = ReadInput(30);if input == null or input.what != «dial» then stop; end if;mainTask = input.sender;// Вызвать URI, указанный в параметре События// Если соединение не получится, послать Событие// главной задаче и остановитьсяresultCode = StartCall(startEvent.parameter);if resultCode != null thenvoid(SendEvent(mainTask,"result",resultCode));stop;end if;// подождать любое Событие кроме событий предварительных ответовloopinput = ReadInput(3600);exitif not IsCallProvisionEvent(input);end loop;// родитль посылает "stop" - тогда мы сразу умираемif IsDictionary(input) and then input.what == "stop" then stop; end if;if not IsCallCompletedEvent(input) or else input.parameter != null thenvoid(SendEvent(mainTask,"result","generic error"));stop;end if;if StartBridge(mainTask) != null thenPlayFile("Failure");stop;end if;// мост построенControlBridge();PlayFile("GoodBye");end entry;//// Контролируем сигнализацию абонента:// пока для медиа установлен мост:// выйти, если абонент прекратит звонок или нажмёт «#»// или если мост будет убран//procedure ControlBridge() isloopinput = ReadInput(3600);exitif IsBreakBridgeEvent(input) or elseIsDisconnectEvent(input) or else input == "#";end loop;void(BreakBridge());end procedure;
AttachMixer(input)
Значение параметра input должно быть Событием StartBridge, отправленным этой Задаче.
Эта функция присоединяет медиа абонента Задачи-отправителя к Медиа Каналу этой Задачи.
Эта функция возвращает нулевое значение, если медиа абонента Задачи-отправителя было успешно присоединено к Медиа Каналу этой Задачи. В противном случае, функция возвращает строку с кодом ошибки.
Функция StartBridge в Задаче-отправителе выходит из состояния ожидания. Функция StartBridge возвращает нулевое значение, если медиа поток абонента Задачи-отправителя был успешно присоединён. В противном случае, эта функция возвращает строку с кодом ошибки.
Обратите внимание: Если функция AttachMixer использовалась в момент нахождения Задачи в состоянии disconnected и Задача не имеет Медиа Канала, то для этой Задачи создаётся новый Медиа Канал.
DetachMixer(taskRef)
Эта функция отсоединяет медиа абонента указанной Задачи от Медиа Канала этой Задачи.
Значение taskRef должно быть описателем задачи.
Функция возвращает нулевое значение, если медиа абонента указанной Задачи было успешно присоединено к Медиа Каналу этой Задачи, и если это медиа абонента было успешно воссоединено с указанной Задачей.
Указанная Задача получает Событие BreakBridge.
Функция возвращает строку с кодом ошибки, если медиа абонента другой Задачи не может быть отсоединено.
Значение taskRef может быть нулевым значением. В этом случае медиа абонентов всех других Задач отсоединяется от Медиа Канала этой Задачи.
MixerAttached()
Эта функция возвращает массив описателей задачи всех Задач, которые соединили медиа потоки своих абонентов с Медиа Каналом этой Задачи.
Если этот Медиа Канал Задачи не имеет никакого другого медиа потока абонентов других Задач, то эта функция возвращает нулевое значение.
MuteMixer(taskRef,flag)
Эта процедура определяет, должен ли Медиа Канал Задачи игнорировать данные от указанной Задачи.
Значение taskRef должно быть описателем Задачи. Медиа поток абонента этой Задачи должен быть подключён к Медиа Каналу текущей Задачи.
Значение taskRef может быть нулевым; в этом случае управляется медиа поток абонента текущей Задачи.
Значение flag указывает операцию: если flag имеет значение истина, то медиа абонента игнорируется; в противном случае Медиа Канал начинает обрабатывать медиа от абонента.
Если значение flag равно строке "special", медиа поток этого абонента не передаётся другим "нормальным" абонентам.
Если значение flag равно строке "hearsSpecial", этот абонент получает медиа потоки от "особых" абонентов ("special").
Если значение flag равно строке «hearsMute», этот абонент получает медиа потоки от всех абонентов (приглушенных, специальных, активных).
Если значение flag равно строке «hearsNormal», этот абонент не получает медиа потоки от «особых» абонентов ("special").
Если медиа участника другой Задачи соединено с Медиа Каналом Задачи, то все медиа направляются в единое пространство разговора (в конференцию).
Эта задача не может использовать функции StartBridge или AcceptBridge.
Обратите внимание: в определённых случаях система может преобразовывать операцию функции AcceptBridge в операцию функции AttachMixer. Как результат этого, операция BreakBridge может использоваться такой Задачей, которая имеет только один другой медиа поток абонента, подсоединённый к своему Медиа Каналу.
Если Задача отсоединяется от участника или участник Задачи отсоединяется самостоятельно (штатно или в результате ошибки) и существует медиа участника другой Задачи, соединённое с этим Медиа Каналом Задачи, то система отсоединит его автоматически.
StartBridgedCall(destination,event)
Эта функция работает также, как функция StartCall, но значение event должно быть Событием StartBridge, отправленным в эту задачу входящей Задачей. Задача инициирует вызов, используя описание медиа из данных События (описывающие медиа участника входящей Задачи).
Предварительные ответы доставляются в текущую Задачу как События, а также они отправляются входящей Задаче (смотрите ниже).
Если вызов успешен, то между Задачами строится Медиа Мост, текущая Задача получает Событие с окончательным ответом, и операция StartBridge во входящей Задаче завершается успешно.
Если вызов заканчивается неуспешно, то текущая Задача получает Событие с окончательным ответом, но входящей Задаче никакого События не посылается. Текущая Задача может либо попытаться осуществить новую операцию StartBridgedCall, либо она может использовать операции AcceptBridge/AttachMixer/RejectBridge для обработки полученного события StartBridge.
Если входящая Задача закончила выполнение, или Задача поставила входящий звонок на ожидание, и этот звонок был прерван, то инициированный исходящий звонок прерывается, и текущая Задача получает событие BreakBridge.
Перевод звонка
TransferSupported()
Эта функция возвращает истину, если абонент поддерживает операции Перевода Звонка; в противном случае функция возвращает нулевое значение.
IsCallTransferredEvent(input)
Эта функция возвращает истину, если значением input является Событие CallTransferred. В противном случае функция возвращает нулевое значение.
TransferCall(destination)
Эта функция делает попытку «несопровождаемого» перевода. Задача должна быть в состоянии connected.
Значение destination должно быть строкой, содержащий URI или адрес электронной почты, на который должен быть переведён звонок.
Если перевод звонка заканчивается неудачно, то функция возвращает строку с кодом ошибки.
Если перевод звонка заканчивается успешно, то функция возвращает нулевое значение.
Когда операция завершается, Задача остаётся в состоянии connected, за исключением ситуации, при которой абонент отключился явно (путём отправки запроса BYE).
StartTransfer(taskRef)
Эта функция посылает специальное Событие StartTransfer указанной Задаче, прося её подключить абонентов Задачи напрямую.
Значение taskRef должно быть описателем задачи. Оно задаёт Задачу, которой отправляется запрос.
Эта функция возвращает нулевое значение, если указанная Задача успешно подключила абонентов. В противном случае, функция возвращает строку с кодом ошибки.
Текущая Задача должна быть в состоянии connected.
Текущая задача ставится в ожидающее состояние, требуемая Задача получает специальное Событие StartTransfer.
IsStartTransferEvent(input)
Эта функция возвращает истину, если значением input является Событие StartTransfer. В противном случае функция возвращает нулевое значение.
RejectTransfer(input,errorCode)
Эта функция отвергает запрос StartTransfer.
Значение параметра input должно Событием StartTransfer, которое необходимо отвергнуть.
Значение параметра errorCode должно быть строкой.
Функция StartTransfer в Задаче, которая отправила Событие StartTransfer, выходит из состояния ожидания и возвращает строку с кодом ошибки.
AcceptTransfer(input)
Эта функция соединяет абонента текущей Задачи с абонентом Задачи, отправившей Событие StartTransfer.
Значением параметра input должно быть Событие StartTransfer, которое необходимо принять.
Эта функция возвращает нулевое значение, если абоненты были успешно соединены. В противном случае, функция возвращает строку с кодом ошибки.
Функция StartTransfer в Задаче, которая отправила Событие StartTransfer, выходит из состояния ожидания. Та функция возвращает нулевое значение, если абоненты были соединены; в противном случае возвращается строка с кодом ошибки.
Если абоненты были соединены, то обе Задачи остаются в состоянии connected, за исключением ситуации, когда их абоненты явно отправили Сигналы на отсоединение. Задачи должны либо выйти, либо использовать процедуру Disconnect для полного отсоединения от своих абонентов.
Запросы INFO
Приложения могут отправлять и получать запросы INFO.
Определённые INFO запросы (такие, как запросы с событиями DTMF) обрабатываются автоматически и не имеют отношения к настоящему разделу.
Данные INFO запросов представлены в виде словаря, в котором содержатся следующие элементы:
Content-Type
Этот необязательный элемент с типом строка содержит Content-Type тела запроса (такое, например, как application).
Content-Subtype
Этот необязательный элемент с типом строка содержит подтип Content-Type тела запроса.
«» (пустой ключ)
Этот необязательный элемент (строка, блок данных или объект XML) содержит тело запроса.
SendCallInfo(params)
Эта функция посылает участнику Задачи запрос INFO. Задача должна быть в состоянии connected.
Значение params должно быть словарём, в котором содержатся данные запроса INFO.
Если операция заканчивается неудачно, то функция возвращает строку с кодом ошибки.
Если операция заканчивается успешно, то функция возвращает нулевое значение.
При отправке Задаче запроса INFO, Задача получает специальное Событие CallInfo. В элементе parameter События содержится словарь - данные запроса INFO.
IsCallInfoEvent(input)
Эта функция возвращает истину, если значением input является Событие CallInfo. В противном случае функция возвращает нулевое значение.
Запросы REGISTER
Приложения могут посылать запросы REGISTER на внешние сервера SIP.
Детали запроса REGISTER представляются в виде словаря со следующими элементами:
targetDomain
Эта строка задаёт имя домена регистрации.
Via
Этот необязательный элемент задаёт адрес удалённого сервера в случаях, когда он отличается от значения targetDomain или не может быть определён по этому значению из DNS.
fromAddress
Эта строка задаёт полный Адрес Регистрации на удалённом сервере.
Call-ID, CSeq
Эти строковые параметры задают поля запроса REGISTER, необходимые для поддержания регистрации в активном состоянии.
authUsername, authPassword
Эти строки используются для аутентификации запроса.
«» (пустой ключ)
Эта строка задаёт значение для Contact URI запросы REGISTER. Этот URI должен использоваться удалённым сервером SIP как адрес назначения для запросов INVITE при обработке звонков, входящих на Адрес Регистрации на удалённом сервере.
SendCallRegister(params)
Функция отправляет запрос REGISTER на внешний сервер SIP. Приложение должно быть в состоянии disconnected.
Значением params должен быть словарь с данными запроса REGISTER.
Если операция заканчивается неудачно, то функция возвращает строку с кодом ошибки.
Если операция заканчивается успешно, то функция возвращает Отметку Времени окончания запрошенной регистрации.
При успешном выполнении запроса REGISTER функция возвращает Отметку Времени - время согласно GMT, до которого регистрация должна быть повторена. Приложение должно обеспечить повторную регистрацию до наступления этого времени, и использовать те же параметры запроса, включая Call-ID, и увеличить значение CSeq на 3.
Служебные запросы
SendCallOptions(params)
Эта функция посылает абоненту Задачи запрос OPTIONS (если диалог был установлен, и Задача была в состоянии connected) или произвольному клиенту (если Задача в состоянии disconnected).
Значение params интерпретируется аналогично значению destination в StartCall.
Если операция заканчивается неудачно, то функция возвращает строку с кодом ошибки.
Если операция заканчивается успешно, то функция возвращает нулевое значение.
SignalOption(optionName)
SignalOption(optionName,newValue)
Эта функция возвращает текущее значение опции Сигнализации Задачи.
Если указан ненулевой параметр newValue, его значение используется для установки опции.
Значение optionName должно быть строкой - она определяет имя опции. Поддерживаются следующие опции:
«refer»
эта опция используется для указания способа обработки Задачей запросов REFER и INVITE/replaces. Поддерживаемые значения:
«self»
исходящие сигналы аутентифицируются как приходящие от текущего Пользователя; это значение опции используется по умолчанию
«peer»
исходящие сигналы аутентифицируются как приходящие от абонента Задачи (то есть, от отправителя сигнала REFER)
«disabled»
обработка запросов REFER и INVITE/replaces запрещена.
«transferReport»
эта опция определяет, должна ли задача получать оповещения о переводах звонков. Поддерживаемые значения:
«NO»
событие при переводе звонка другому участнику не отправляется; это значение используется по умолчанию
истина ("YES")
Задача получает специальное Событие CallTransferred, когда звонок переводится на другого абонента.
«bridgeBreak»
эта опция указывает способ реакции Задачи на разрыв моста другой задачей. Поддерживаемые значения:
«disconnect»
Задача отсоединяет абонента и переводится в режим disconnected.
«keep»
если Задача не имеет Медиа Канала, он создаётся. Абонент Задачи переключается на этот канал.
«default»
если Задача не имеет Медиа Канала, текущий абонент отсоединяется. Иначе, абонент Задачи переключается на этот канал. Этот метод используется по умолчанию.
«bridgedProvisionRelay»
эта опция определяет, как абоненту доставляются предварительные ответы, генерируемые во время выполнения функции StartBridgedCall. Поддерживаемые значения:
истина ("YES")
предварительные ответы ретранслируются абоненту при помощи функции ProvisionCall, у которой параметр reliably установлен в нулевое значение; таково поведение по умолчанию
«reliably»
предварительные ответы ретранслируются абоненту при помощи функции ProvisionCall, у которой параметр reliably установлен в значение Истина
«NO»
предварительные ответы не ретранслируются абоненту
«bridgedProvisionToTags»
эта опция определяет, как абоненту доставляются предварительные ответы, генерируемые во время выполнения функции StartBridgedCall. Поддерживаемые значения:
«NO»
все предварительные ответы содержат одинаковый To-tag, назначенный этой Задаче; таково поведение по умолчанию.
истина ("YES")
предварительные ответы сохраняют свои оригинальные значения To-tag.
«bridgedProvisionQueue»
эта опция определяет размер очереди FIFO для предварительных ответов. Это очередь используется в тех случаях, когда предварительные ответы из одной задачи принимаются быстрее, чем они могут быть доставлены абоненту. По умолчанию длина очереди равна 10.
«callInfo»
эта опция доступна только для чтения; значение параметра newValue (если он указан) должно быть нулевым.
Функция возвращает информацию о системном объекте Звонка/Диалога: время соединения, используемые прокси и т.д.
SendCallNotify(params)
Эта функция посылает запрос NOTIFY произвольному клиенту (Задача должна быть в состоянии disconnected).
Значением params должен быть словарь со следующими строковыми элементами:
«» (пустая строка), From, To, Call-ID
эти элементы интерпретируются аналогично значению destination в StartCall.
Event
имя названия события
@Event-Params
необязательный словарь с параметрами, которые надо поместить в поле Event запроса.
Subscription-State
необязательная строка, которую надо поместить в поле Subscription-State запроса.
@Content
необязательная строка или блок данных, которые надо отправить в теле запроса.
Content-Type, Content-Subtype
необязательные строки со значениями для заголовка Content-Type.
Если операция заканчивается неудачно, то функция возвращает строку с кодом ошибки.
Если операция заканчивается успешно, то функция возвращает нулевое значение.
Мгновенные сообщения и запросы в стиле протокола XMPP
Задача может получать Мгновенные сообщения и запросы по протоколу XMPP. Они доставляются в Задачу в виде Событий.
IsInstantMessageEvent(input)
Эта функция возвращает истину, если значением input является Событие Мгновенного Сообщения. В противном случае функция возвращает нулевое значение.
Параметром события является словарь. Он содержит те же элементы, что словарь параметра content функции SendInstantMessage, и дополнительные элементы:
From
строка: адрес электронной почты отправителя.
peerName
необязательная строка: настоящее имя отправителя.
fromInstance
необязательная строка: имя ресурса отправителя.
To
строка: адрес электронной почты получателя.
toInstance
необязательная строка: имя ресурса получателя.
authName
необязательная строка: имя аутентификации отправителя.
redirector
необязательная строка: имя Пользователя, перенаправившего сообщение (с помощью Сигнальных Правил или другим способом).
IsXMPPIQEvent(input)
Эта функция возвращает истину, если значением input является Событие с данными XMPP IQ/presence. В противном случае функция возвращает нулевое значение.
Параметром события является словарь. Он содержит те же элементы, что словарь параметра content функции SendXMPPIQ, и дополнительные элементы: From, peerName, fromInstance, To, toInstance, authName, redirector, аналогично Событию с Мгновенным Сообщением.
Поддерживаемые форматы медиа
Поддерживаются следующие форматы аудио файлов:
WAV (данные начинаются с тэга RIFF)
файл должен содержать один кусок (chunk) данных с 8- или 16- битными данными PCM или GSM.
au (данные начинаются с тэга .snd)
файл должен содержать либо 8- или 16- битные данные PCM, либо 8-битные данные mu-Law.
gsm
файл должен содержать поток 33-байтных фреймов в кодировке GSM 06.10.