Search
Write a publication
Pull to refresh

Asterisk в такси

Я — программист-администратор в службе такси. Мы разрабатываем комплексную систему обработки заказов. Я специализируюсь главным образом на телефонии, в частности Asterisk, сайтах (заказ такси), смс. Могу рассказать про все что касается VoIP — телефонии, сопряжения с телефонными сетями в разных городах, вывода вызовов в сотовую сеть, разработку IVR- меню и сложных телефонных приложений.
Наш комплекс работает в Ижевске (такси 373, udmtaxi.ru), Казани (такси татарстан, taxitatarstan.ru), перми (такси перемен, taxiprm.ru), орле, уфе (такси сатурн), москве (такси цель), и многих других городах, названий служб в которых я просто не помню :)

Диалплан мы пишем в стандартном виде (контексты, экстеншны).
Причины на это две: легаси и нежелание писать сложный код в самом астериске.

Терминология


Диалплан — правила маршрутизации звонков, общая таблица маршрутизации.
Контекст — набор команд по обработке звонков («подпрограмма»)
Экстеншн (extension) — одна команда.

Логическая структура диалплана


Диалплан поделен на несколько файлов:
  1. Для входящих звонков
  2. Статический
  3. Для офисной телефонии
  4. Для сопряжения городов

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

Пример контекста с магией


Логику работы астериска можно показать на примере контекста, который позволяет позвонить по двум номерам и соединить их между собой (использую чтобы бесплатно звонить). Не смотря на то, что в нем мало строчек, он показывает многие возможности стандартного диалплана астериска.

[double_call]
; console dial nomer1-nomer2@double_call
; Звонит на номер1, ждет ответа, звонит на номер2, соединяет

exten => _X.,1,NoOp(****** Dialing ${EXTEN} *****)
exten => _X.,n,Set(party1=${CUT(EXTEN,-,1)})
exten => _X.,n,Set(party2=${CUT(EXTEN,-,2)})
exten => _X.,n,Set(CALLERID(num)=${party1})
exten => _X.,n,Dial(Local/${party1}@my-phones,,G(double_call^000${party2}^1))
exten => _000.,1,Hangup
exten => _000.,2,Dial(Local/${EXTEN:3}@my-phones)


А теперь объясню магию построчно

exten => _X.,1,NoOp(****** Dialing ${EXTEN} *****)


После ключевого слова exten и стрелки идет номер, набранный звонящей стороной.

_ означает шаблон
X — любую цифру
. — сколько угодно цифр
Из-за бага в астериске, написать просто _. нельзя.
NoOp — просто выводит сообщение в лог
${EXTEN} — подстановка номера, набранного человеком (для удобства отладки в консоли)

Set(party1=${CUT(EXTEN,-,1)}) - присвоить переменной кусок набранного номера до знака -
Set(party2=${CUT(EXTEN,-,2)}) - то же самое после знака -


EXTEN в данном случае — переменная содержащая набранный номер и сопоставляемая с _X.

Set(CALLERID(num)=${party1}) — установим наш номер звонящего.
Вообще про callerid можно написать отдельный пост, столько с ним сложностей возникает.

Dial(Local/${party1}@my-phones,,G(double_call^000${party2}^1))

Длинная волшебная строчка. Первый аргумент — куда надо позвонить. Local означает, что звоним куда-то на этом же сервере (не используя SIP и другие протоколы). my-phones — наш контекст, отвечающий за исходящие звонки по любым направлениям.

Второй аргумент — таймаут, пропущен.

Третий аргумент означает, что после совершения вызова надо перейти в контекст double_call на контекст 000${party2} в первый по-порядку экстен, а другая (вызванная) сторона, попадет на экстен номер 2.

Поясню подробнее. Когда совершается вызов, создаются два канала, один для вызывающей стороны, а второй для вызываемая, и соединяются между собой. Когда мы попадаем в экстеншн double_call первый раз, вызывающая сторона — консоль, вызываемая — party1. После установления соединения с party1, мы входим в double_call дважды, с номером 000{party2}. При этом вызывающая сторона (консоль) попадает на строчку
exten => _000.,1,Hangup

а вызываемая — на строчку
exten => _000.,2,Dial(Local/${EXTEN:3}@my-phones).

При этом создается канал, звонящий на номер party2.
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.