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

Приложения AGI и DeadAGI существуют уже долгое время, и в течении этого времени их поведение менялось, что часто вводило в заблуждение. AGI служит для организации взаимодействия между внешним приложением и активным каналом в asterisk: работы с переменными, проигрывания звуковых файлов, распознавания и записи речи собеседника.

На данный момент существует несколько видов AGI приложений:

  • AGI, позволяет работать приложению с «живым» каналом, проигрывать звуки, получать DTMF, выполнять приложения диал-плана. Приложение запускается на той же машине что и asterisk.
  • DeadAGI, выполнение приложений на «мёртвых» каналах, чтобы выполнить операции, связанные с завершением вызова. Например, записать оставшиеся в переменных данные в БД. Приложение запускается на той же машине что и asterisk.
  • EAGI, то же что и AGI, только через отдельный файловый дескриптор вызванному приложению передаётся звук. Аналогично предыдущим, приложение работает на том же компьютере что и asterisk.
  • FastAGI, выполнение приложений на удалённом сервере. Комманды и ответы пересылаются через TCP соединение.
  • AsyncAGI (появится в 1.6), возможность передавать и получать AGI сообщения через AMI интерфейс.

Речь пойдёт о первых двух, функции которых до крайности похожи. Разница заключается лишь в состоянии канала, на котором запущено приложение. AGI — только для живых каналов, DeadAGI — только для «мертвых».
Как было раньше (в незапамятные времена): В работе AGI была допущена ошибка, в результате которой работа AGI приложения не прекращалась после того как трубка была положена, не отправлялся сигнал SIGHUP. Этим пользовался, к примеру, биллинг A2Billing: все действия выполнялись в одном php приложении, который по завершении разговора записывал все данные в БД (снимал деньги с карточки). Ошибка была замечена и исправлена, что, после обновления, вызвало некорректную работу биллинга.

Как работает в 1.4:

Ситуация не является смертельной. Любое приложение может перехватить и обработать SIGHUP сигнал, инструкция к биллингу была дополнена информацией, как модифицировать приложение, чтобы исправить ситуацию. Более простым способом явилось использование DeadAGI, единственным минусом является то, что приложение выводит предупреждение о том, что оно запущено на действующем канале. Однако параллельное существование AGI и DeadAGI немного путает и смущает, к тому же их поведение несколько отличается как на активных, так и на «мертвых» каналах.

Как будет в 1.6:

В 1.6 код для DeadAGI и AGI был существенно изменён и объединён. Логика работы приложений была объединена и вот полный алгоритм работы

  • Приложение можно запустить в любое время выполнения DialPlan, будь то выполнение диал-плана в процессе обработки вызова или экстенжн h
  • При запуске устанавливается ряд переменных окружения, которые содержат основные пути к файлам установленного asterisk
  • Приложение принимает данные от asterisk через stdin и может передавать команды через stdout. При этом в момент старта приложения в stdin находится масса полезной информации
  • Если трубка положена удалённой стороной, то AGI приложению будет отправлен сигнал SIGHUP. Приложение может обработать полученный сигнал и не завершать свою работу, в php это можно сделать с помощью специального набора функций (посмотрите, установлен ли пакет php5-pntctl). Если сигнал не обработан, то приложение будет немедленно завершено.
  • Переменная AGISIGHUP, установленная перед запуском AGI приложения, управляет отправкой сигнала (значения yes и no). Но, похоже, в текущем trunk она не работает, буду разбираться.
  • Даже после того как трубка положена Asterisk оставляет доступ ко всем переменным, установленным на канале (переменные CDR, номер звонящего и т.п.). И только после завершения приложения все структуры будут разрушены
  • При запуске приложения на «мёртвом» канале это можно узнать, запустив, к примеру, приложение Playback и посмотрев возвращённый результат.
  • По завершению AGI приложения устанавливается переменная AGISTATUS, в которой записана причина завершения работы приложения.
Приложение DeadAGI в версии 1.6 считается устаревшим и будет удалено в последующих релизах. Король умер, да здравствует король!

Похожие сообщения:

Google Bookmarks Digg del.icio.us Technorati Slashdot News2.ru БобрДобр.ru RUmarkz Ваау! Memori.ru rucity.com МоёМесто.ru

автор igorg \\ теги: , , , , ,


3 комментария к “AGI vs. DeadAGI, кто должен умереть?”

  1. 1. Сергей Говорит:

    Пытался прописать в диалплане сразу после Dial вызов DeadAGI (test.agi) — никакого эффекта, после разрыва соединения test.agi выполняться не желает. Если AGI (test.agi) вызвать перед Dial — работает. Вы пробовали реально запустить agi скрипт после Dial? Я это пробовал на Asterisk 1.4 — результат отрицательный.

  2. 2. Сергей Говорит:

    Отвечаю сам себе — все работает, просто для DeadAGI нужно указывать специальный экстеншн h

    exten => h,1,DeadAGI (test.agi)

  3. 3. lilo Говорит:

    Товарищи там перемудрили с этими AGI/DeadAGI. По логике скрипт должен продолжаться в любом случае. То есть вообще в любом.

    Скажем, каким образом понять DIALSTATUS? Если в случае AGI поюзать pcntl_signal (SIGHUP, SIG_IGN); то легче не становится: * перестает воспринимать команды от скрипта. Т.е. dialstatus="". Поэтому нет возможности определить ANSWER/CANCEL. Это печально... С DeadAGI все работает верно, но что-то отпугивает меня это название все равно... )

Написать ответ