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, в которой записана причина завершения работы приложения.

апреля 12, 2009 в 17:45
Пытался прописать в диалплане сразу после Dial вызов DeadAGI (test.agi) — никакого эффекта, после разрыва соединения test.agi выполняться не желает. Если AGI (test.agi) вызвать перед Dial — работает. Вы пробовали реально запустить agi скрипт после Dial? Я это пробовал на Asterisk 1.4 — результат отрицательный.
апреля 12, 2009 в 19:10
Отвечаю сам себе — все работает, просто для DeadAGI нужно указывать специальный экстеншн h
exten => h,1,DeadAGI (test.agi)
февраля 28, 2010 в 22:02
Товарищи там перемудрили с этими AGI/DeadAGI. По логике скрипт должен продолжаться в любом случае. То есть вообще в любом.
Скажем, каким образом понять DIALSTATUS? Если в случае AGI поюзать pcntl_signal (SIGHUP, SIG_IGN); то легче не становится: * перестает воспринимать команды от скрипта. Т.е. dialstatus="". Поэтому нет возможности определить ANSWER/CANCEL. Это печально... С DeadAGI все работает верно, но что-то отпугивает меня это название все равно... )