355 500 произведений, 25 200 авторов.

Электронная библиотека книг » Джим Меггелен » Asterisk™: будущее телефонии Второе издание » Текст книги (страница 19)
Asterisk™: будущее телефонии Второе издание
  • Текст добавлен: 7 октября 2016, 17:17

Текст книги "Asterisk™: будущее телефонии Второе издание"


Автор книги: Джим Меггелен


Соавторы: Джаред Смит,Лейф Мадсен

Жанр:

   

ОС и Сети


сообщить о нарушении

Текущая страница: 19 (всего у книги 41 страниц)

Негарантированное обслуживание

Самый простой и дешевый подход к QoS – не предоставлять качества услуг вообще. Это называется негарантированным обслуживанием. Вероятно, звучит не очень хорошо, но этот метод может очень неплохо работать. Любой вызов VoIP, проходящий по открытой сети Интернет, практически наверняка будет вызовом с негарантированным обслуживанием, поскольку механизмы QoS в этой среде еще не получили широкого распространения.

Эхо

Возможно, вы не осознаете этого, но проблема эха существует в PSTN так же долго, как существуют телефоны. Вероятно, вы не часто сталкивались с ней, потому что телекоммуникационная отрасль потратила огромные суммы денег на разработку дорогих эхоподавляющих устройств. Также, если конечные точки физически располагаются на небольшом расстоянии, например когда вы звоните своему соседу, живущему на одной с вами улице, задержка минимальна и все сигналы возвращаются настолько быстро, что полностью имитируют местный эф– фект1, обычно создаваемый телефоном. То есть суть в том, что при местных звонках эхо присутствует в большинстве случаев, но абонент не может различить его в обычном телефоне, потому что оно возвращается практически мгновенно. Чтобы понять это, представьте следующее: когда вы находитесь в комнате, все сказанное вами отражается от стен и потолка (и, вероятно, пола, если нет ковра) и возвращается к вам, но это не создает никаких проблем, потому что происходит настолько быстро, что вы не улавливаете задержки.

Как говорилось в главе 7, местный эффект – это функция телефона, которая обеспечивает возвращение части звукового сигнала в ухо говорящего, чтобы создать эффект более естественного разговора.

Причина, по которой в телефонной системе VoIP, такой как Asterisk, может появиться эхо, в том, что введение VoIP-телефона приводит к возникновению небольшой задержки. Прохождение пакетов от телефона на сервер (и обратно) занимает несколько миллисекунд. Если вдруг возникает ощутимая задержка, вы можете слышать эхо, которое было там всегда, но никогда не приходило с задержкой.

Почему возникает эхо

Прежде чем приступить к обсуждению мер по борьбе с эхом, давайте рассмотрим, почему эхо возникает в аналоговом мире. Если вы слышите эхо, проблема не в телефоне, а в дальнем конце линии. И наоборот, эхо, слышимое на дальнем конце, формируется на вашей стороне. Эхо может быть обусловлено тем, что местной аналоговой линии связи приходится передавать и получать сигналы по одной и той же паре проводов. Если эта линия не сбалансирована по электрическим параметрам или если к ней подключен телефон низкого качества, получаемые ею сигналы могут отражаться назад в сеть, становясь частью возвращаемых данных. Когда этот отраженный сигнал возвратится к вам, вы услышите слова, которые произнесли несколько мгновений назад. Люди будут различать эхо при задержке, превышающей определенную величину (возможно, от 20 мс для некоторых). При увеличении задержки эхо начнет раздражать.

В дешевом телефоне эхо может формироваться в теле трубки. Вот почему некоторые дешевые IP-телефоны могут создавать эхо, даже если в соединении нет ни одной аналоговой линии[95]95
  На самом деле трубка любого телефона, будь он традиционным или VoIP, является аналоговой линией.


[Закрыть]
. В мире VoIP эхо обычно обусловлено или присутствием аналоговой линии где-то в соединении, или применением дешевого терминала, отражающего часть сигнала (например, обратная связь через устройство hands-free или плохую трубку либо гарнитуру). Чем выше задержка в сети, тем более надоедливым может быть это эхо.

Устранение эха в каналах Zaptel

В конфигурационном файле zconfig.h можно выбрать один из ряда предлагаемых алгоритмов эхоподавления. По умолчанию используется MARK2. Поэкспериментируйте с различными эхокомпенсаторами, чтобы выбрать тот, который лучше всего подходит для вашей среды. Также Asterisk предлагает опцию в файле zconfig.h, которая позволяет сделать эхоподавление более агрессивным. Ее можно активировать, раскомментировав следующую строку: #define AGGRESSIVE_SUPPRESSOR

Заметьте, что агрессивное эхоподавление может создать эффект портативной полудуплексной радиостанции. Оно должно быть активировано, только если все остальные методы снижения эха не обеспечили результата.

Активация эхоподавления для интерфейсов Zaptel осуществляется в файле zapata.conf. В стандартной конфигурации эхоподавление активируется строкой echocancel=yes. echocancelwhenbridged=yes обеспечит эхо– подавление для звонков, проходящих через TDM. Хотя такие звонки не должны требовать эхоподавления, это может улучшить их качество. Если эхоподавление активировано, эхокомпенсатор распознает эхо в линии во время звонка. Поэтому эхо может быть слышимо в начале разговора и со временем уменьшаться. Чтобы избежать этого, можно прибегнуть к методу, называемому тренировкой эхоподавления, при котором в линии в начале звонка на мгновение отключается звук и передается тональный сигнал, по которому может быть определена величина эха. Это позволяет Asterisk быстрее устранять эхо. Тренировка эхоподавления активируется строкой echotraining=yes.

Аппаратное эхоподавление

Программное эхоподавление – не самый эффективный способ борьбы с эхом. Если планируется развертывание системы хорошего качества, потратьте дополнительные средства на платы, снабженные устройствами аппаратного эхоподавления. Такие платы несколько дороже обычных, но они быстро окупятся, поскольку обеспечат снижение нагрузки на ЦП и сберегут ваши нервы благодаря сокращению жалоб пользователей.

Asterisk и VoIP

Для вас не должно быть сюрпризом, что Asterisk любит работать с VoIP. Но для этого ей надо знать, какую функцию выполнять: клиента, сервера или и того и другого. Одна из наиболее сложных и часто сбивающих с толку концепций в Asterisk – схема присваивания имен при аутентификации входящих и исходящих вызовов.

Пользователи, и равноправные участники, и друзья – о, боже!

Соединения, устанавливаемые с нами или нами, определены в файлах iax.conf и sip.conf как user (пользователь) и peer (равноправный участник). Соединения, которые могут выполняться в обоих направлениях, могут быть определены как friend (друг). При определении, в каком направлении происходит аутентификация, всегда важно посмотреть на направление каналов с точки зрения Asterisk, поскольку соединения принимаются и создаются сервером Asterisk.

Соединения user

Соединение, определенное как user, – это любая система/пользователь/конечная точка, которой мы разрешаем соединяться с нами. Помните, что описание user не обеспечивает метода вызова этого пользователя; тип user используется просто для создания канала для входящих звонков[96]96
  В SIP это не всегда так. Если конечная точка является прокси-сервисом SIP (в противоположность агенту пользователя), Asterisk будет выполнять аутентификацию на основании описания peer, сравнивая IP-адрес и порт в поле Contact SIP-заголовка с именем хоста (и портом, если он задан), определенным для этого равноправного участника (если порт не задан, будет использоваться тот, который определен в разделе [general]). Подробнее опция SIP insecure обсуждается в приложении А.обсуждается в приложении А.


[Закрыть]
. В описании user потребуется задать имя контекста для обозначения места диалплана (в файле extensions.conf), где будет начинаться обработка аутентифицированных звонков.

Соединения peer

Соединение типа peer является исходящим. Представим это так: пользователи (users) звонят нам, тогда как мы звоним равноправным участникам (peers). Поскольку равноправные участники не звонят нам, описание peer обычно не требует задания имени контекста. Однако есть одно исключение: если звонки, берущие начало в вашей системе, возвращаются в вашу же систему, входящие звонки (которые берут начало на SIP-прокси, а не на агенте пользователя) будут сопоставляться с описанием peer. Контекст default должен обрабатывать эти входящие звонки соответствующим образом, хотя предпочтительнее, чтобы контексты были определены для каждого peer отдельно[97]97
  Больше информации по этому вопросу можно найти в обсуждении SIP– опции context в приложении А.


[Закрыть]
. Чтобы знать, куда отправлять вызов, необходимо иметь информацию о местонахождении хоста в Интернете (то есть знать его IP-адрес). Местоположение peer может быть определено или статически, или динамически. Динамический peer конфигурируется с помощью строки host=dynamic, размещаемой под заголовком описания. Поскольку IP– адрес динамического peer может меняться постоянно, он должен регистрироваться на сервере Asterisk, чтобы его IP-адрес был известен и звонки могли успешно направляться к нему. Если удаленным концом является другой сервер Asterisk, необходимо использовать выражение register, что обсуждается ниже.

Соединения friend

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

Рис. 8.2. Источник вызова относительно Asterisk для соединений типа user, peer и friend

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

Выражения register

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

Допустим, имеется удаленный равноправный участник сети, предоставляющий вам сервисы DID. Когда кто-то вызывает номер +1-800555-1212, звонок поступает по физической сети PSTN к вашему поставщику сервисов и на его сервер Asterisk, возможно, через Т1-линию. После этого данный вызов направляется по Интернету на ваш сервер Asterisk.

Ваш поставщик услуг будет располагать описанием вашего сервера Asterisk в одном из конфигурационных файлов, sip.conf или iax.conf (в зависимости от того, выполняется ли соединение по протоколу SIP или IAX соответственно). Если вы получаете вызовы только от этого поставщика сервисов, вы определили бы их тип как user (если бы это была другая система Asterisk, вы могли бы быть определены в ней как

peer).

Теперь, допустим, ваш сервер использует ваше домашнее соединение с Интернетом с динамическим IP-адресом. Поставщик услуг имеет статический IP-адрес (или, возможно, полностью определенное доменное имя), которое указано в вашем конфигурационном файле. Поскольку у вас динамический адрес, поставщик сервисов в своем конфигурационном файле указывает host=dynamic. Чтобы знать, куда направлять ваш звонок на номер +1-800-555-1212, поставщику сервисов необходимо знать ваше местонахождение в Интернете. Вот где понадобится выражение register.

Выражение register – это средство аутентификации и сообщения peer своего местонахождения. В разделе [general] своего конфигурационного файла поместите выражение, аналогичное данному:

register => имяпользователя:секрет@мой_удаленнный_равноправный_участник Убедиться в успешности регистрации можно с помощью команд iax2 show registry и sip show registry из консоли Asterisk.

Безопасность VoIP

В данной книге мы можем лишь коснуться сложного и широкого вопроса безопасности VoIP; поэтому, прежде чем углубиться в него, мы хотели бы направить вас к VoIP Security Alliance (http://www.voipsa. org). Этот фантастический ресурс имеет превосходную рассылку, техническую документацию, практические рекомендации и общий перечень всех материалов, касающихся безопасности VoIP. Как и сообщения электронной почты, речевые данные тоже могут быть подвергнуты атакам корыстного или криминального характера. Хорошие парни на VoIPSA делают все, что в их силах, чтобы мы могли справиться с этими проблемами сейчас, до того как они станут эпидемией. Из книг, посвященных этому вопросу, мы рекомендуем самую лучшую – «Hacking Exposed VoIP» (издательство McGraw-Hill Osborne Media) Дэвида Энд– лера (David Endler) и Марка Коллиера (Mark Collier). Те, кто отвечает за развертывание любой системы VoIP, должны знать этот материал.

Спам по сети интернет-телефонии (СПИТ)

Нам не хочется думать об этом, но мы знаем, что он будет. Чтобы предсказать это, достаточно того простого факта, что в этом мире есть люди, в которых отсутствие определенных социальных навыков сочетается с тупой жадностью, и такие парни думают только о том, как наводнить Интернет огромной массой электронной почты. Эти же ребята, недолго думая, начнут делать то же самое с голосовой связью. Мы уже знаем, что значит утопать в звонках систем продаж по телефону; а теперь попытайтесь представить ситуацию, когда рассылка голосового спама не стоит телемаркетинговой фирме практически ни копейки. Никакие меры не остановили спам по электронной почте и, вероятно, не остановят голосовой спам, поэтому борьба с ним будет нашей задачей.

Шифрование звука с помощью безопасного RTP

Если можно перехватывать пакеты, исходящие из системы Asterisk, значит, можно извлекать аудиоданные из RTP-потоков. Эти данные могут поставляться в автономном режиме в систему обработки речи, которая будет слушать ключевые слова, такие как «номер кредитной карты» или «пин», и предоставлять эти данные тому, кто заинтересован в них. Поток также может быть проанализирован на предмет встроенных DTMF-тонов, что представляет опасность, потому что многие сервисы запрашивают ввод пароля и информации кредитной карты через номеронабиратель. Также и в деловой сфере, имея возможность сбора и анализа аудиоданных, можно выведать стратегически важную информацию.

Использование безопасного RTP (Secure RTP, SRTP) может помочь справиться с этой проблемой за счет шифрования RTP-потоков; но Asterisk не поддерживала SRTP на момент написания данной книги. Работы по обеспечению поддержки SRTP ведутся (для готовящейся к выпуску версии есть патч, но на данный момент неизвестно, будет ли он перенесен в более раннюю версию 1.4).

Спуфинг

В традиционной телефонной сети очень сложно действовать от лица кого-либо. Ваша деятельность может быть (и будет) отслежена, и полномочные органы быстро положат конец забавам. В мире IP намного проще сохранять анонимность. Поэтому несложно догадаться, что орды предприимчивых злоумышленников станут охотно звонить в компанию по выдаче кредитных карт или в банк от вашего имени. Если не будет придуман надежный механизм борьбы со спуфинг-мошенничес– твом[98]98
  Спуфинг – мошенничество с использованием реквизитов солидных компаний, направленное на получение конфиденциальной информации с целью хищения денег. Как правило, с помощью компьютерных технологий имитируется реально существующий банковский сайт или он размещается на поддельном сайте; таким образом, вводимые обманутыми пользователями данные поступают на поддельный сайт. - Примеч. науч.ред.


[Закрыть]
, мы быстро поймем, что не можем доверять звонкам по VoIP.

Что можно сделать

Первое, что надо помнить при рассмотрении вопросов безопасности в VoIP-системе, – VoIP основывается на сетевых протоколах, то есть анализ необходимо проводить с данной точки зрения. Мы не хотим

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

Базовая безопасность сети

Самое эффективное, что можно сделать, – обеспечить защищенный доступ к сети телефонной связи. Применение межсетевых экранов и виртуальных локальных сетей (VLAN) – примеры того, как это можно реализовать. По умолчанию сеть телефонной связи должна быть доступной только для того, в чем есть необходимость. Например, если программные телефоны не используются, клиентские ПК не должны иметь доступа к сети телефонной связи.

Разделение речевого трафика и трафика данных. Если нет необходимости в передаче речи и данных по одной сети, возможно, будет выгодно разделить их (это может иметь также и другие преимущества, такие как упрощение конфигурации QoS). Не является чем-то из ряда вон выходящим полная реализация сети телефонной связи в абсолютно изолированной локальной сети, использующей существующую кабельную разводку CAT3 и заканчивающейся недорогими сетевыми коммутаторами. Это также может быть дешевле.

Демилитаризованная зона (DMZ). Размещение системы VoIP в демилитаризованной зоне может обеспечить дополнительный уровень защиты локальной сети, предоставляя при этом возможность соединения для соответствующих приложений. Если система VoIP будет подвергнута несанкционированному доступу, будет намного сложнее использовать ее для распространения атаки на остальную сеть, поскольку она не является доверенной. Но даже если развертывание системы выполняется в демилитаризованной зоне, любой необычный трафик, исходящий из системы, должен находиться под подозрением. Укрепление сервера. Укрепление сервера Asterisk является критически важным. Это обеспечивает не только преимущества по производительности (выполнение второстепенных процессов может съедать ценные ресурсы ЦП и оперативной памяти); устранение всего ненужного сократит шанс того, что уязвимость операционной системы может быть использована для получения доступа и организации атак на другие части вашей сети.

Запуск Asterisk под учетной записью, не принадлежащей администратору, – важнейшая составляющая укрепления системы. Подробнее этот вопрос рассматривается в главе 11.

Шифрование

Даже несмотря на то что Asterisk до сих пор не обеспечивает полной поддержки SRTP, трафик VoIP можно шифровать. Например, между узлами связи может использоваться VPN. В этом случае необходимо исходить из затрат на обеспечение необходимой производительности,

но, как правило, это очень эффективный и относительно простой в реализации способ защиты трафика VoIP.

Физическая безопасность

Нельзя пренебрегать и физической безопасностью. Все оконечное оборудование (такое, как коммутаторы, маршрутизаторы и сама офисная АТС) должно размещаться в безопасном месте с возможностью доступа к нему только людей, имеющих на то специальное разрешение. На стороне пользователя (например, под столом) довольно сложно обеспечить физическую безопасность, но, если сеть отвечает только знакомым устройствам (например, если в DHCP все выдаваемые IP-адреса жестко привязаны к, MAC-адресам устройств, которые известны), риск неавторизованного вторжения можно несколько снизить.

Заключение

Если верить слухам, распространяемым в телекоммуникационной отрасли, можно подумать, что VoIP – это будущее телефонии. Но для Asterisk VoIP из области «это мы уже проходили». Для Asterisk будущее телефонии намного более захватывающее. Но мы обратимся к этому несколько позднее, в главе 15. В следующей главе мы собираемся углубиться в одну более революционную и мощную концепцию Asterisk: AGI (Asterisk Gateway Interface) – шлюзовой интерфейс Asterisk.

9

Шлюзовой интерфейс Asterisk (AGI)

Даже он, кому большинство из того, что другим людям кажется достаточно разумным, представляется довольно бестолковыми, полагал, что это было достаточно разумным.

– Дуглас Адамс «Лосось сомнений»

Шлюзовой интерфейс Asterisk, или AGI, предоставляет стандартный интерфейс, посредством которого внешние программы могут управлять диалпланом Asterisk. Как правило, сценарии AGI используются для реализации расширенной логики, соединения с реляционными базами данных (такими, как PostgreSQL или MySQL) и доступа к другим внешним ресурсам. Передача управления диалпланом внешнему сценарию AGI позволяет Asterisk без труда реализовывать задачи, выполнение которых в противном случае было бы сложным или невозможным. В данной главе рассматриваются основы использования AGI. Она не научит вас программировать, напротив, здесь предполагается, что читатель уже является достаточно квалифицированным разработчиком, чтобы понимать, как создаются AGI-программы. Если вы не знаете, как писать компьютерные программы, вероятно, эта глава не для вас. Пропустите ее и переходите к следующей.

По ходу данной главы будет написана AGI-программа с использованием разных языков программирования: Perl, PHP и Python. Однако обратите внимание, что, поскольку Asterisk предоставляет стандартный интерфейс для AGI-сценариев, эти сценарии могут быть написаны практически на любом современном языке программирования. Мы решили остановиться на Perl, PHP и Python, потому что эти языки чаще всего используются для программирования AGI.

Основы обмена информацией с AGI

AGI не реализует API для программирования. AGI-сценарии взаимодействуют с Asterisk по каналам связи (посредством описателей файла, выражаясь на языке программистов), которые известны как STDIN, STDOUT и STDERR. Большинство программистов знают эти каналы, но все– таки, на случай если вы не знакомы с ними, они будут рассмотрены здесь.

Что такое STDIN, STDOUT и STDERR

STDIN, STDOUT и STDERR – это каналы, по которым программы в UNIX-по– добных средах обмениваются информацией с внешними программами. STDIN, или стандартный ввод, – это информация, передаваемая в программу или с клавиатуры, или из другой программы. В нашем случае данные, поступающие от самой Asterisk, приходят в описатель файла STDIN. STDOUT, или стандартный вывод, – это описатель файла, применяемый сценарием AGI для передачи информации в Asterisk. И наконец, сценарий AGI может использовать описатель файла STDERR (стандартная ошибка) для записи сообщений об ошибке в консоль Asterisk. Подытожим эти три концепции обмена информацией:

• Сценарий AGI читает из STDIN для получения информации от Asterisk.

• Сценарий AGI записывает данные в STDOUT для отправки информации в Asterisk.

• Сценарий AGI может записывать данные в STDERR для отправки отладочной информации в консоль Asterisk.

На данный момент запись в STDERR из сценария AGI обеспечивает запись данных только в первую консоль Asterisk – точнее, в первую консоль Asterisk, запущенную с параметром -с. Это довольно неудачно, и мы надеемся, что данный недостаток будет вскоре устранен разработчиками Asterisk. Если для запуска Asterisk используется программа safe_ asterisk (скорее всего, вы так и поступаете), она запускает удаленную консоль на TTY9. (Проверьте, получите ли вы интерфейс командной строки Asterisk, нажав сочетание клавиш Ctrl+Alt+F9.) Это означает, что вся отладочная информация AGI будет выводиться только в той удаленной консоли. Вероятно, вы захотите деактивировать эту консоль в safe_asterisk, чтобы получить возможность видеть отладочную информацию в другой консоли. (Также, вероятно, эту консоль необходимо отключить из соображений безопасности: вам не нужно, чтобы каждый, подошедший к вашему серверу Asterisk, имел доступ к консоли без всякой аутентификации.)

Стандартная схема обмена информацией с AGI

Обмен информацией между Asterisk и сценарием AGI идет по заранее установленной схеме. Перечислим все этапы и затем последовательно рассмотрим один из примеров сценария AGI, поставляемого с Asterisk. Когда сценарий AGI запускается, Asterisk передает в него список переменных и их значений. Эти переменные могут выглядеть примерно так:


agi_request:test.py
agi_channel:Zap/1-1
agi_languageen
agi_callerid
agi_context:default
agi_extensior: 123

agi_priority: 2

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

На этом этапе сценарий AGI посылает команды в Asterisk, выполняя запись в STDOUT. На каждую команду, передаваемую сценарием, Asterisk возвращает ответ, который сценарий AGI должен прочитать. Эти действия (отправка команд в Asterisk и чтение ответов) могут продолжаться в течение всего времени выполнения сценария AGI. Наверное, вас интересует, какие команды можно использовать в сценарии AGI. Хороший вопрос. Очень скоро мы рассмотрим основные ко– манды[99]99
  Чтобы получить список доступных команд AGI, введите show agi в интерфейсе командной строки Asterisk. Также за справкой по командам AGI можно обратиться к приложению C.


[Закрыть]
.

Вызов сценария AGI из диалплана

Чтобы сценарий AGI работал правильно, он должен быть исполняемым файлом. Для использования сценария AGI в диалплане просто вызывается приложение AGI() с указанием имени сценария AGI в качестве аргумента:

exten => 123,1,Answer() exten => 123,2,AGI(agi-test.agi)

Сценарии AGI часто располагаются в папке AGI (которая обычно находится в папке /var/lib/asterisk/agi-bin), но можно указать и полный путь к сценарию AGI.

В этой главе сначала мы рассмотрим сценарий agi-test.agi, поставляемый с Asterisk (который написан на Perl), затем напишем AGI-про– грамму на PHP для получения сводки погоды и напоследок создадим математическую игру в виде AGI-программы на Python.

AGI(), EAGI(), DeadAGI() и FastAGI()

Кроме приложения AGI(), существует еще несколько AGI-при– ложений, подходящих для разных ситуаций. Хотя они не будут рассмотрены в данной главе, поняв азы работы со сценариями AGI, разобраться с ними будет довольно просто.

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

Приложение DeadAGI() также очень похоже на AGI(), но выполняется корректно для «мертвого» канала (то есть канала, который был отключен). Отсюда следует, что обычное приложение AGI() не работает для отключенных каналов.

Приложение FastAGI() позволяет вызывать сценарий AGI по сети, таким образом, множество серверов Asterisk могут использовать сценарии AGI, хранящиеся централизованно.

Написание сценариев AGI на Perl

Asterisk поставляется с образцом сценария AGI под названием agi-test. agi. На примере этого файла рассмотрим основные концепции программирования AGI. Этот конкретный сценарий написан на Perl, но AGI– программы могут быть реализованы практически на любом языке программирования. Чтобы доказать это, в данной главе будут представлены AGI-программы на нескольких других языках программирования. Итак, приступим! Будем рассматривать каждый раздел кода по очереди и описывать, что он делает: #!/usr/bin/perl

Эта строка сообщает системе, что данный сценарий написан на Perl, таким образом, для его выполнения должен использоваться интерпретатор Perl. Опытным создателям сценариев для Linux или UNIX эта строка должна быть хорошо знакома. Конечно, здесь предполагается, что исполняемый файл Perl располагается в папке /usr/bin/. Если необходимо, измените строку соответственно местоположению своего интерпретатора Perl. use strict;

Строка use strict указывает Perl строго придерживаться правил программирования и не допускать возможных ошибок при написании программы, таких как, например, необъявленные переменные. Хотя она не является обязательной, но активация этой функциональности поможет избежать обычных ошибок при программировании. $|=1;

Данная строка указывает интерпретатору Perl не буферизировать вывод. Иначе говоря, любые данные должны записываться немедленно, а не накапливаться и выводиться блоками. К этому вопросу мы будем многократно возвращаться по ходу главы.

# Задаем некоторые переменные

my %AGI; my $tests = 0; my $fail = 0; my $pass = 0;

При написании сценариев AGI должен использоваться только небуферизированный вывод. В противном случае AGI может работать не так, как от него требуется. Например, Asterisk может ожидать вывода программы, тогда как программа полагает, что уже отправила вывод в Asterisk, и ожидает ответа.

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

while() { chomp;

last unless length($_);

if (/~agi_(w+):s+(.*)$/) {

$AGI{$1} = $2;

}

i

Как говорилось ранее, Asterisk передает группу переменных в программу AGI при запуске. Этот цикл просто принимает все эти переменные и сохраняет их в хеше AGI. Позже они могут использоваться в программе или просто игнорироваться, но они обязательно должны быть прочитаны из STDIN, прежде чем будет продолжено выполнение логики программы.

print STDERR "AGI Environment Dump:n";

foreach my $i (sort keys %AGI) {

print STDERR " – $i = $AGI{$i}n";

}

Данный цикл просто записывает каждое из значений, сохраненных в хеше AGI, в STDERR. Это полезно для отладки сценария AGI, поскольку STDERR выводится в консоли Asterisk[100]100
  На самом деле в консоли Asterisk, вызванной первой (то есть это первый экземпляр Asterisk, вызванный опцией -с). Если для запуска Asterisk использовался сценарий safe_asterisk, первая консоль Asterisk будет выполняться на TTY9, а это означает, что вы не сможете просматривать ошибки AGI удаленно.


[Закрыть]
.

sub checkresult { my ($res) = my $retval;

$tests++;

chomp $res;

if ($res =~ /"200/) {

$res =~ /result=(-?d+)/; if (!length($1)) {

print STDERR "FAIL ($res)n"; $fail++; } else {

print STDERR "PASS ($1)n"; $pass++;

}

} else {

print STDERR "FAIL (unexpected result '$res')n"; $fail++;

}

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

Теперь, когда подготовительные этапы пройдены, можно перейти к основной логике сценария AGI:

print STDERR "1. Testing 'sendfile'..."; print "STREAM FILE beep ""n"; my $result = ; &checkresult($result);

Первый тест показывает, как использовать команду STREAM FILE. Команда STREAM FILE указывает Asterisk воспроизвести звуковой файл вызывающему абоненту, точно так же как это делает приложение Backg round(). В данном случае Asterisk должна воспроизвести файл beep.gsm[101]101
  Asterisk автоматически выбирает лучший формат исходя из затрат на преобразование и доступности, поэтому расширение файла в данной функции никогда не указывается.


[Закрыть]
. Обратите внимание, второй аргумент заменяется парой двойных кавычек, экранированных обратным слэшем. Без обозначения второго аргумента двойными кавычками эта команда не будет работать правильно.

В команды AGI должны передаваться все необходимые аргументы. Если требуется пропустить необходимый аргумент, должны быть указаны пустые кавычки (правильно экранированные, соответственно синтаксису конкретного языка программирования), как показано выше. Если необходимое количество аргументов не будет передано, сценарий AGI не станет работать.

Также необходимо убедиться, что вы не забыли передать символы перевода строки (символы n в конце выражения print) в конце команды.

После передачи команды STREAM FILE этот тест читает результат из STDIN и вызывает подпрограмму checkresult, чтобы выяснить, смогла ли Asterisk воспроизвести файл. Команда STREAM FILE принимает три аргумента, два из которых являются обязательными:

• Имя звукового файла для воспроизведения.

• Коды, которые могут прерывать воспроизведение.

• Место начала воспроизведения звукового файла, заданное номером музыкального фрагмента (необязательный).

Одним словом, этот тест указал Asterisk воспроизвести файл beep.gsm и затем проверил результат, чтобы убедиться, что Asterisk успешно выполнила команду.

print STDERR "2. Testing 'sendtext'..."; print "SEND TEXT "hello world"n"; my $result = ; &checkresult($result);

Этот тест демонстрирует, как вызывать команду SEND TEXT, которая является аналогом приложения SendText(). Эта команда будет посылать заданный текст вызывающему абоненту, если используемый им тип канала поддерживает передачу текста.

Команда SEND TEXT принимает один аргумент: текст, который должен быть отправлен в канал. Если текст содержит пробелы (как в предыдущем фрагменте кода), аргумент должен быть заключен в кавычки, чтобы Asterisk понимала, что вся строка является одним аргументом команды. Опять же, обратите внимание, что кавычки экранированы, поскольку они должны быть переданы в Asterisk, а не использоваться для ограничения строки в Perl.


    Ваша оценка произведения:

Популярные книги за неделю