Команда Dial()


Назначение

Пытается установить новое исходящее соединение с и связать его с текущим каналом (по которому поступил вызов).

Описание

Dial(type/identifier,timeout,options,URL)
Dial(type1/identifier1&type2/identifier2&type3/identifier3...,timeout,options,URL)
RetryDial(announce[|context][|sleep][|loops]:Technology/resource[&Technology2/resource2...][|timeout][|options][|URL])

Команда пытается "дозвониться" по всем заданным каналам одновременно (каждый определяется параметром type и identifier) . Как только на одном из каналов отвечают на вызов, на всех остальных вызов прекращается. Для вызывающего канала, который инициировал команду Dial, при необходимости устанавливается состояние соединения - Answer и эти два канала связываются друг с другом ("bridged") , позволяя абонентам разговаривать между собой. Когда канал, который вызвал Dial, заканчивает связь, происходит выход из команды.

Команда RetryDial была добавлена в Asterisk v1.2 совместно с флагом 'd'.

Параметры

  • Новое в Asterisk v1.2.0: Если Вы не хотите модифицировать параметры для каждой команды, в которой используется механизм перехода на команду, со смещенным относительно нее, приоритетом, то Вы можете задать параметр "priorityjumping=yes" в секции [general] файла extensions.conf, с помощью которой глобально будет установлено поведение, как в предыдущих версиях. Поскольку мы рассматриваем команду Dial(), то Вы можете управлять данным поведением этой команды, используя параметр 'j' (смотри ниже).
  • Новое в Asterisk v1.2.0: Теперь, в качестве значения Caller*ID для исходящего плеча соединения, используется номер вызываемого екстеншена, а не значение Caller*ID входящего плеча вызова. Вы можете использовать флаг "o", для команды Dial для восстановления старого алгоритма, если пожелаете. Обратите внимание, что если Вам нужен номер вызывающего абонента, получаемый в событии интерфейса управления, то для этого добавлено новое событие, генерируемое этим интерфейсом, с именем "Dial", которое предоставляет нам информацию о входящем и исходящем канале и о номерах вызывающего и вызываемого абонента.

  • type - тип канала. Должно быть значением зарегистрированного в системе типом канала, например, "Zap", "SIP", "IAX2", и т.д.
  • identifier- "номер телефона", который вызывается через этот канал. Формат "номера телефона" зависит от используемого канала и может содержать дополнительные параметры (например, параметры, определяющие тип звонка), которые можно найти в описании модуля канала. Команда Dial просто пересылает этот identifier в модуль канала, а он уже разбирается, что надо с ним делать. Для того чтобы определить нужный формат поля ''identifier' обратитесь к документации по необходимому Вам каналу, там же вы найдете и опции, которые Вы можете применять в этой команде. Если Вам необходимо сделать паузу при наборе номера, то Вы можете вставить символ w в то место, где нужно ее сделать.
  • Если вы определите несколько вызываемых каналов для команды Dial, то запомните, что вызов будет производиться по всем каналам одновременно. Разделяйте описания каналов символом &. Типы каналов могут различаться. Смотри примеры ниже.
  • Параметр timeout необязателен. Если не задан, то команда Dial будет совершать вызов неопределенно долго, и закончит свое выполнение, если только по вызывающему каналу будет разорвана связь или на всех вызываемых каналах будет определено состояние "занято". Если этот параметр задан, то он определяет максимальное время в секундах, указывающий, сколько времени команда Dial будет ждать ответа на вызов.
  • Параметр options также опциональный, это строка, содержащая ни одного или несколько нижеприведенных флагов и параметров:

    • t: Разрешает ответившему пользователю перевести звонок
      • Если Вы установили значение переменной GOTO_ON_BLINDXFR , тогда при переводе вызова, будет совершен переход в указанную в переменной точку плана набора "context|exten|pri" (Для указания символа "|", при установки значения переменной, Вы можете использовать символ ^ , чтобы избежать проблем с экранированием специальных символов), пример: SetVar(GOTO_ON_BLINDXFR=ontransfer^s^1) . Это работает как с параметром "t", так и с параметром "T''.
      • ОБРАТИТЕ ВНИМАНИЕ: переменной с именем: GOTO_ON_TRANSFER нет и не будет ни в какой из версий сервера ASTERISK! Имя переменной - GOTO_ON_BLINDXFR смотри: http://svn.digium.com/view/asterisk?rev=5495&view=rev и http://bugs.digium.com/view.php?id=4056 для подробностей.

    • T: Разрешает звонящему пользователю перевести звонок
    • r: Генерировать сигналы вызова звонящему абоненту (ложный КПВ). Audio потоки не соединяются с вызываемым каналом до тех пор, пока хотя бы на одном из вызываемых каналов не ответят на вызов. Используйте этот параметр с осторожностью и не вставляйте его где попало в эту команду, т.к. при этом состояние вызова будет уже как бы "соединенное", и для вызывающего абонента, если, например, звонок междугородний и тарифицируется, уже будет отсчитываться время разговора и, соответственно, деньги. В реальности, этот параметр почти во всех случаях Вам не понадобиться. Asterisk будет сам генерировать сигналы КПВ в тех случаях, где это необходимо. Использование параметра "r" может быть оправдано в тех случаях, когда нужно оставить сигналы КПВ после команды Dial, в процессе выполнении других команд.
    • R: Указывает состояние вызова "ringing" вызывающему абоненту, когда вызываемый абонент указывает, что у него звонит телефон "ringing", audio потоки не соединяются с вызываемым каналом до момента соединения. Этот параметр доступен только с использованием bristuff от kapejod.
    • m: Проигрывать звонящему абоненту музыку ожидания (Music on Hold) до тех пор, пока на вызов не ответят. Этот параметр абсолютно взаимоисключающий с параметром 'r'. Используйте m(class) для обозначения, из какого подкласса выбрать эту музыку.
    • n: (в Asterisk 1.1 и более поздних версиях) July 2005 bug 752 был включен в CVS (Asterisk 1.1) и значительно расширяет возможности privacy manager'a. Являясь частью патча, для флага 'n' команды Dial было изменено его значение, и теперь он используется, как часть возможностей privacy manager'a, вместо старого 'не переходить по смещению +101'. Теперь для этих целей используется флаг 'j'.
    • o: Восстановить алгоритм работы с CallerId, как в версии v1.0, для Asterisk v1.2.
    • j: Для Asterisk 1.2 и более поздних версий: перейти на команду с приоритетом n+101, если все из вызываемых каналов заняты (как стандартное поведение в Asterisk 1.0.x)
    • M(x): Заставляет выполнить macro (x) в момент ответа на вызов
    • h: Разрешает ответившему пользователю повесить трубку нажатием *
    • H: Разрешает звонящему абоненту повесить трубку нажатием *
    • i: (появилась, начиная с версии 1.4) Asterisk будет игнорировать все попытки вызываемых абонентов перенаправить вызов на другой номер для данной попытки вызова. Очень удобно, когда Вы пытаетесь вызвать группу абонентов, и у одного из них установлена на телефоне переадресация вызовов на голосовую почту или на его сотовый телефон или еще куда, что мешает нормальному функционированию и мешает вызову проходить на другие телефоны группы.
    • C: Заставляет сбросить CDR (Call Detail Record) запись для этого вызова. Имеет такой же эффект, как применение команды NoCDR
    • p: Эта опция включает режим "экранирования" (screening mode). Он в основном базируется на работе PrivacyManager, но без запоминания, как обрабатывать входящие вызовы. В этом режиме ищется файл sounds/priv-callerintros/${IF($[ "${CALLERID(num)}" != "" ]?${CALLERID(num)}:NOCALLERID_${EXTEN}${CUT(CHANNEL,/,1)}=${CUT(CHANNEL,/,2)})}.gsm и, если он не найден, звонящему проигрывается приглашение с просьбой представиться. Далее вызов будет направлен адресату и ему будут проиграны файлы: sounds/priv-callpending, sounds/priv-callerintros/<см. описание выше>, и sounds/screen-callee-options. Если вызываемый абонент нажмет 1, то вызов будет принят, если 2 - команда DIAL закончит свое выполнение и в переменной канала ${DIALSTATUS} будет установлено значение NOANSWER, если 3, выход со значением этой переменной - TORTURE и 4 - со значением DONTCALL. Если не будет выбран ни один из правильных вариантов, команда DIAL закончит свое выполнение со значением в переменной ${DIALSTATUS} равным ANSWER. Проверка уже существующего файла с записанным представлением звонящего абонента может быть совсем не тем, что Вам нужно. Например, когда множество людей использует один и тот же номер для совершения исходящих вызовов, и нет возможности сопоставить этот номер с каким-либо конкретным человеком, но в этом случае файл уже существует и новый файл не будет записан. Так как эти файлы никогда не удаляются, Вы можете сами удалять их командой плана набора: System(rm /var/lib/asterisk/sounds/priv-callerintros/${IF($[ "${CALLERID(num)}" != "" ]?${CALLERID(num)}:NOCALLERID_${EXTEN}${CUT(CHANNEL,/,1)}=${CUT(CHANNEL,/,2)})}.*) , перед тем как вызвать команду Dial или удалять старые записи по крону.
    • P(x): Заставляет использовать PrivacyManager, используя x, как базу данных (x указывать не обязательно)
    • g: Когда вызываемый абонент вешает трубку, продолжить выполнение команд далее по текущему контексту.
    • G: G(context^exten^pri) - Если на вызов ответили, перекидываем обоих абонентов в заданное место плана набора; однако, имеется в виду, что вызывающий (звонящий) абонент будет отправлен к приоритету x, а вызываемый (отвечающий) - к приоритету x+1 (новая опция в версии v1.2)
    • A(x): Заставляет команду проиграть анонс (из файла x.gsm) вызываемой стороне.
    • S(n): Прервать звонок после n секунд, отсчитываемых после поднятия трубки вызываемым абонентом.
    • d: Этот флаг расширяет возможности параметра 'H' и позволяет перехватывать любые dtmf посылки, в процессе ожидания, пока вызываемый абонент ответит на вызов, и возвращает набранное значение. Это позволяет Вам набрать номер екстеншена для выхода пока, вызываемый Вами абонент, еще не ответил на вызов. Смотри описание команды: RetryDial
    • D(digits): Заставляет после снятия трубки на удаленной стороне, отправить строку digits в виде DTMF последовательности, затем соединить голосовые потоки обеих сторон.
    • L( x[:y][:z] ): Ограничить звонок временем в 'x' ms, проиграть предупреждение, когда осталось 'y' ms, повторять предупреждение каждые 'z' ms. Только параметр 'x' является обязательным, 'y' и 'z' не обязательны. Нижеприведенные специальные переменные могут быть опционально, использоваться для ограничения вызовов: (используются в app_dial.c)
      • LIMIT_PLAYAUDIO_CALLER - yes|no (по умолчанию yes) - Проигрывать звуковой файл вызывающему абоненту.
      • LIMIT_PLAYAUDIO_CALLEE - yes|no - Проигрывать звуковой файл звонящему пользователю.
      • LIMIT_TIMEOUT_FILE - Проигрываемый файл, когда время вышло.
      • LIMIT_CONNECT_FILE - Проигрываемый файл в начале вызова.
      • LIMIT_WARNING_FILE - Проигрываемый файл предупреждения, когда задан параметр 'y'. Если значение LIMIT_WARNING_FILE не определено, тогда будет использован специальный звуковой макрос для проговаривания оставшегося времени ("У Вас осталось [XX минут] YY секунд").
    • f: насильно устанавливает callerid, как номер екстеншена, который совершает исходящий вызов или перевод вызова. Например, некоторые АТС не позволяют использовать callerids с другими номерами, кроме тех, что выделены для Вас.
    • w: Разрешает ответившему пользователю начать запись разговора после нажатия *1 или той последовательности, что определена в features.conf (Asterisk > v1.0.x)
    • W: Разрешает "звонящему" абоненту начать запись разговора после нажатия *1 или той последовательности, что определена в features.conf (Asterisk > v1.0.x)
    • k: (появилась, начиная с версии 1.4) Разрешает "ответившему" пользователю произвести парковку вызова, путем отправки DTMF последовательности, заданной для парковки вызовов в файле конфигурации features.conf
    • K: (появилась, начиная с версии 1.4) Разрешает "звонящему" пользователю произвести парковку вызова, путем отправки DTMF последовательности, заданной для парковки вызовов в файле конфигурации features.conf


  • Дополнительный параметр URL будет также отправлен ответившему абоненту после успешного установления соединения, если технология использованного канала поддерживает отправку URL в данном направлении.

Макросы в команде Dial

Появилось в Asterisk 1.2, смотри: bug/patch 2905

Теперь Вы можете использовать аргументы в макросах, используя символ '^'

Dial(Zap/1|60|M(mymacro^cat^dog^bark))

Также, макрос может установить переменную MACRO_RESULT в следующие значения:

ABORT - оба участника соединения прервали связь
BUSY
CONTINUE - Отключить вызываемую сторону и продолжить выполнение команд, следующих за командой Dial
GOTO:^^ - перевод звонка.

Обратите внимание: Если Вы хотите, чтобы оба абонента были соединены по завершению выполнения макроса, вы НЕ ДОЛЖНЫ устанавливать значение переменной MACRO_RESULT. Если значение MACRO_RESULT не определено, то после выполнения всех команд макроса до конца, абоненты будут соединены и смогут разговаривать между собой. Установка этой переменной в значения CONTINUE приводит к тому, что абоненты НЕ соединяются между собой, и выполнение команд продолжиться с приоритета n+1, текущего контекста. Конечно же, установка значения в BUSY или GOTO приведет к соответствующему результату (и, естественно, абоненты не будут соединены).
(Способ управления соединением абонентов немного противоречит здравому смыслу, при котором ожидается, что причиной "соединения обоих абонентов" должна быть установка переменной MACRO_RESULT в такое значение, как "BRIDGE" или "CONNECT", или во что-то подобное. Тут же в качестве такой причины используется ОТСУТСТВИЕ любого значения этой переменной.)


Пример 1: макрос в команде Dial.

screen-record: Назовите Ваше имя и нажмите решетку.
screen-from: Вам поступил звонок от
screen-accept: Нажмите 1 для принятия вызова или любую другую, чтоб отвергнуть.

exten => 890,1,Wait(0.2)
exten => 890,2,Playback(screen-record)
exten => 890,3,SetVar(SCREEN_FILE=/tmp/${CALLERIDNUM}-${EPOCH})
exten => 890,4,Record(${SCREEN_FILE}.gsm|6|25)
exten => 890,5,Dial(SIP/16|60|gM(screen^${SCREEN_FILE}))
exten => 890,6,Voicemail(10@default)

[macro-screen]
exten => s,1,Wait(0.2)
exten => s,2,Playback(screen-from)
exten => s,3,Playback(${ARG1})
exten => s,4,Read(ACCEPT|screen-accept|1)
exten => s,5,GotoIf($[${ACCEPT} = 1 ] ?7:6)
exten => s,6,SetVar(MACRO_RESULT=CONTINUE)
exten => s,7,System(/bin/rm ${ARG1})

Замечания:
  • Не надо вставлять пробелы между аргументами команды Dial, а то работать не будет.
  • Если заданы параметры t или T , Asterisk остаётся на пути голосового потока данных, если только не определен параметр canreinvite=yes (параметр SIP канала).

Коды возврата

Если вызываемый канал занят, команда Dial закончит свою работу, вернет код возврата 0 и выполнение команд может быть продолжено в текущем контексте с приоритета со смещениемn+101, если такой есть, где n - это приоритет с которым была задана команда Dial. Это позволяет нам задать различные действия в случае занятости вызываемого абонента, как альтернативу ситуации, когда вызываемый абонент не отвечает.

Если команда Dial не может совершить вызов по каким-либо другим причинам, например, наступление таймаута до того, как на вызов ответили, тогда команда Dial выйдет с кодом возврата 0 и будет выполнена следующая по приоритету (n+1) команда.

Если определен параметр g, и вызываемый абонент положит трубку до того, как это сделает вызывающий пользователь, тогда команда Dial закончит свое выполнение, вернет код возврата и продолжиться выполнение команд с приоритета n+1.

Команда Dial вернет код возврата -1, если канал, по которому поступил вызов, "повесит трубку" или в случае, когда абоненты были соединены и любой из абонентов положит трубку.

Замечание для Asterisk v1.2: Если вам нужно, чтобы при занятости вызываемого абонента производился переход на команду с приоритетом n+101 (как в Asterisk v1.0.x), тогда вам нужно использовать опцию j в команде Dial.

Обратите внимание: Если применен патч от bristuff, то он незначительно меняет алгоритм работы команды dial, заключающийся в том, что производиться переход на команду с приоритетом n+201, если вызываемый абонент недоступен (например, SIP телефон выключен, или он не зарегистрирован на сервере).

Пример 2: Вызов по нескольким каналам, с задержкой для некоторых екстеншенов


Смысл идеи: Создадим специальные екстеншены, где мы производим задержку, а потом выполняем вызов на необходимые нам номера, например:

exten => _900XXXXX,1,Wait(${EXTEN:4:2})
exten => _900XXXXX,2,Dial(SIP/${EXTEN:5})

В контексте для входящих вызовов, используем канал типа Local для создания нашего вызова:

exten => s,1,Dial(SIP/200&SIP/201&LOCAL/90015300&LOCAL/90015301)

В вышеприведенном примере, екстеншены 200 и 201 будут звонить сразу же при поступлении вызова, а екстеншены 300 и 301 начнут звонить через 15 секунд после его поступления. После части, содержащей номер "900", следующие две цифры используются для определения задержки, перед тем как начать вызывать екстеншен, который задан в трех последних цифрах указанного номера. Эта уловка служит для того, чтобы вместо простого использования двух команд Dial друг за другом, мы обеспечиваем то, что каждый телефон будет вызываться только один раз. Это предотвращает такие нежелательные последствия, как: a) потенциальные проблемы с SIP устройствами, которым нужно некоторое время, чтобы иметь возможность принять следующий вызов, b) предотвращает появление лишних записей "пропущенных звонков" в интерфейсе телефонного аппарата.
Обратите внимание на команду ForkCDR и на ResetCDR, если Вам не нравиться то, что в результате у Вас получиться в записях CDR, при использовании этого примера.


Возвращаемые значения в переменных канала

  • Для соединений через PRI интерфейсы в канале ZAP, так же и для каналов IAX2, код разъединения соединения (hangup code) можно найти в переменной HANGUPCAUSE.
  • Замечание: код разъединения 0 используется, как уведомление, что код возврата не был установлен. Код 16 не является индикатором ошибки, он просто сообщает, что вызов прошел и терминирован нормально.
  • Для всех каналов , переменная DIALSTATUS содержит результат последней попытки вызова, это значение можно использовать для построения логики плана набора
  • Переменные DIALEDTIME и ANSWEREDTIME содержат временные отрезки для билинга (так же как и в CDR записях)

Примеры

exten => 1265,1,Dial(Phone/phone0,15)
exten => s,3,Dial(SIP/oej,20)
exten => _908.,1,Dial(Modem/ttyI0:${EXTEN:1})
exten => 233,1,Dial(SIP/4029&SIP/4027&Zap/4&IAX/jaz,15,tTr)
exten => 500,1,Dial(Zap/2r2,20,crh)
exten => 20,1,Dial(Zap/3/5551234)

Замечания для различных версий

  • Параметры A и S: добавлены в CVS после релиза 0.7.2
  • Параметр D: появился в CVS после May 2004
  • Параметр f: добавлен в CVS с June/July 2004
  • Переменные DIALSTATUS, ANSWEREDTIME и DIALEDTIME: добавлены в CVS head начиная с june 2004

Ссылки по теме:

  • Команда RetryDial
  • Установка переменной ALERT_INFO для смены типа звонка в телефонах Cisco 79xx. Смотри еще и MySQL custom ringtones