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 считается устаревшим и будет удалено в последующих релизах. Король умер, да здравствует король!