Состояния устройств
Из беспорядка найти простоту.
-Альберт Эйнштейн
Часто бывает полезно определить состояние устройств, подключенных к телефонной системе. Например, у администратора может потребоваться возможность видеть статусы каждого в офисе, чтобы определить, может ли кто-нибудь позвонить по телефону. Сам Asterisk нуждается в такой же информации. В качестве другого примера, если вы построили очередь вызовов, как описано в Главе 13, Asterisk должен знать, когда агент доступен, чтобы можно было отправить другой вызов. В этой главе обсуждаются концепции состояния устройств в Asterisk, а также способы использования и доступа к этим устройствам и приложениям.
Состояния устройств
Существует два типа устройств, к которым относятся состояния устройств: реальные устройства и виртуальные. Реальные устройства — это конечные точки телефонии, которые могут совершать или принимать вызовы, такие как SIP-телефоны. Виртуальные устройства включают объекты, которые находятся внутри Asterisk, но предоставляют полезную информацию о состоянии. Таблица 14-1 содержит список доступных виртуальных устройств в Asterisk.
Таблица 14-1. Виртуальные устройства в Asterisk
Виртуальное устройство | Описание |
---|---|
MeetMe:<conferencebridge> | Состояние конференц-моста MeetMe. Статус будет отражать, есть ли в настоящее время участники в конференции. Более подробную информацию об использовании MeetMe() для конференц-связи можно найти в разделе “Конференц-связь с MeetMe()” в Главе 10. |
SLA:<shared line> | Общие сведения о состоянии внешней линии. Это состояние управляется приложениями Trunk() и SLAStation(). Более подробную информацию можно найти в разделе “Общие внешние линии”. |
Custom:<custom name> | Пользовательские состояния устройств. Эти состояния имеют пользовательские имена и изменяются с помощью функции DEVICE_STATE(). Пример использования можно найти в разделе «Использование пользовательских состояний устройств«. |
Park:<exten@context> | Состояние парковочного места. Сведения о состоянии будут отражать, припаркован ли абонент в данный момент на этом дополнительном номере. Более подробную информацию о парковке вызовов в Asterisk можно найти в разделе “Парковочные места” в Главе 11. |
Calendar:<calendar name> | Состояние календаря. Asterisk будет использовать содержимое именованного календаря для установки состояния available или busy. Более подробную информацию об интеграции календаря в Asterisk можно найти в Главе 18. |
Состояние устройства — это простое однозначное сопоставление с устройством. Рисунок 14-1 показывает это сопоставление.
Проверка состояния устройства
Функция диалплана DEVICE_STATE() может использоваться для чтения текущего состояния устройства.
Вот простой пример её использования в диалплане:
exten => 7012,1,Answer()
; *** Эта строка не должна иметь разрывов
same => n,Verbose(3,The state of SIP/0004F2060EB4 is ${DEVICE_STATE(SIP/0004F2060EB4)})
same => n,Hangup()
Если мы вызываем номер 7012 из того же устройства, на котором мы проверяем состояние, на консоли Asterisk появляется следующее подробное сообщение:
— The state of SIP/0004F2060EB4 is INUSE
Глава 20 обсуждает Asterisk Manager Interface (AMI). Действие диспетчера GetVar может использоваться для извлечения значений состояний устройства во внешнюю программу. Вы можете использовать его для получения значения как нормальной переменной, так и функции диалплана, такой как DEVICE_STATE().
Следующий список содержит возможные значения, которые возвращаются из функции DEVICE_STATE():
- UNKNOWN
- NOT_INUSE
- INUSE
- BUSY
- INVALID
- UNAVAILABLE
- RINGING
- RINGINUSE
- ONHOLD
Статусы внутренних номеров
Внутренние номера являются еще одним важным понятием в Asterisk. Статусы внутренних номеров — это то, на что подписываются SIP-устройства для получения информации о присутствии. (SIP-присутствие более подробно обсуждается в разделе «SIP-присутствие«). Состояние внутреннего номера определяется путем проверки состояния одного или нескольких устройств. Список устройств, отображающих состояния внутр.номеров, определен в диалплане Asterisk /etc/asterisk/extensions.conf с использованием специальной директивы hint. На Рисунке 14-2 показано сопоставление между устройствами, состояниями устройств и состояниями внутренних номеров.
Хинты
Чтобы определить хинт (подсказку) состояния номера в диалплане, используется ключевое слово hint вместо приоритета. Вот простой пример диалплана, который относится к Рисунку 14-2:
[default]
exten => 1234,hint,SIP/phoneA&SIP/phoneB&SIP/phoneC
exten => 5555,hint,DAHDI/1
exten => 31337,hint,MeetMe:31337
Обычно хинты просто определяются вместе с остальной частью внутреннего номера. В следующем примере добавляются простые записи номеров для отслеживания событий при вызове каждого из этих номеров:
[default]
exten => 1234,hint,SIP/phoneA&SIP/phoneB&SIP/phoneC
exten => 1234,1,Dial(SIP/phoneA&SIP/phoneB&SIP/phoneC)
exten => 5555,hint,DAHDI/1
exten => 5555,1,Dial(DAHDI/1)
exten => 31337,hint,MeetMe:31337
exten => 31337,1,MeetMe(31337,dM)
В нашем примере мы установили прямую корреляцию между добавочным номером хинта и набираемым добавочным номером, хотя нет необходимости в том, чтобы это было так.
Проверка статуса внутреннего номера
Самый простой способ проверить текущий статус номера — CLI Asterisk. Команда core show hints покажет вам все сконфигурированные хинты. Рассмотрим следующее определение хинта:
[phones]
exten => 7001,hint,SIP/0004F2060EB4
Когда core show hints выполняются в CLI Asterisk, при использовании устройства отображается следующий вывод:
*CLI> core show hints
-= Registered Asterisk Dial Plan Hints =-
7001@phones : SIP/0004F2060EB4 State:InUse Watchers 0
—————-
— 1 hints registered
В дополнение к отображению статуса внутреннего номера, вывод core show hints также обеспечивает количество наблюдателей. Watcher (наблюдатель) — это кто-то в Asterisk, кто подписался на получение обновлений о статусе этого номера. Если SIP-телефон подписывается на состояние номера, счетчик будет увеличен.
Состояние внутренних номеров также можно получить с помощью функции диалплана EXTENSION_STATE(). Эта функция работает так же, как функция DEVICE_STATE(), описанная в предыдущем разделе. В следующем примере показан номер, который будет печатать текущее состояние другого номера в консоли Asterisk:
exten => 7013,1,Answer()
same => n,Verbose(3,The state of 7001@phones is
${EXTENSION_STATE(7001@phones)})
same => n,Hangup()
Когда этот номер вызывается, это подробное сообщение, отображается в консоли Asterisk:
— The state of 7001@phones is INUSE
Следующий список включает возможные значения, которые могут быть возвращены функцией EXTENSION_STATE():
- UNKNOWN
- NOT_INUSE
- INUSE
- BUSY
- UNAVAILABLE
- RINGING
- RINGINUSE
- HOLDINUSE
- ONHOLD
SIP-присутствие
Asterisk предоставляет устройствам возможность подписываться на состояние номеров с использованием SIP-протокола. Эта функция часто упоминается как BLF (Busy Lamp Field).1
Конфигурация Asterisk
Чтобы сделать эту работу, хинты должны быть определены в /etc/asterisk/extensions.conf (см. «Хинты» для большей информации о настройке хинтов в диалплане). Дополнительно, некоторые важные параметры должны быть установлены в файле конфигурации для драйвера канала SIP, тоесть в /etc/asterisk/sip.conf. В следующем списке обсуждаются такие параметры:
callcounter
Включает/отключает счетчики вызовов. Он должен быть включен для Asterisk чтобы иметь возможность получать статус для SIP-устройств. Этот параметр может быть установлен либо в [general], либо или в секциях пиров в sip.conf.
Если вы хотите, чтобы состояния устройств работали на устройствах SIP, то должны, по крайней мере, установить для параметра callcounter значение yes. В противном случае драйвер SIP-канала не будет отслеживать звонки на устройства и с них и не будет предоставлять информацию о состоянии.
busylevel
Устанавливает количество вызовов, которые должны выполняться для Asterisk, чтобы сообщить, что устройство занято. Этот параметр может быть установлен только в секциях пиров в sip.conf. По умолчанию эта опция не установлена. Это означает, что Asterisk сообщит, что устройство используется, но не покажет что занято.
call-limit
Этот параметр устарел в пользу использования функций GROUP() и GROUP_COUNT() в диалплане Asterisk. Вы можете найти более старую документацию, которая предполагает, что этот параметр необходим для работы SIP-присутствия. Это имело место, но этот вариант был заменен опцией callcounter для этой цели.
allowubscribe
Позволяет отключить поддержку подписки. Если этот параметр не установлен, подписки будут включены. Чтобы отключить поддержку подписки полностью, установить allowsubscribe в значение no в секции [general] файла sip.conf.
subscribecontext
Позволяет установить определенный контекст для подписок. Без этой установки будет использоваться контекст, определяемый параметром context. Эта опция может быть задана либо в разделе [general], либо в секциях пиров в sip.conf.
notifyingringing
Контролирует, будет ли отправлено уведомление, когда номер переходит в состояние вызова. Этот параметр имеет значение yes по умолчанию. Он влияет только на подписки, которые используют пакет событий dialog-info. Эта опция может быть установлена только глобально в секции [general] в sip.conf.
notifyhold
Позволяет chan_sip устанавливать состояния SIP-устройств в ONHOLD. По умолчанию установлено значение yes. Эта опция может быть установлена только глобально в секции [general] в sip.conf.
notifycid
Включает/отключает отправку информации CallerID абонента в расширение. Этот параметр применяется к устройствам, которые подписываются на уведомления о состоянии номеров, основанные на dialog-info+xml, таких телефонов как Snom. Отображение CallerID вызывающего абонента может быть полезно, чтобы помочь агенту решить, следует ли выполнять ответ на входящий вызов. Этот параметр установлен в no по умолчанию.
Этот волшебный пикап работает только в том случае, если номер и контекст хинта совпадают с номером и контекстом входящего вызова. Следует отметить, что использование опции subscribecontext обычно ломает эту опцию. Эта опция также может быть установлена в значение ignorecontext. Это позволит обойти проблему контекста, но должно использоваться только в среде, где существует только один экземпляр номера, на который была подписка. В противном случае вы можете случайно ответить на звонки, на которые не собирались отвечать.
Использование пользовательских состояний устройств
Asterisk предоставляет возможность создавать пользовательские состояния устройств, которые позволяют разрабатывать различные интересные пользовательские приложения. Мы начнем с отображения основного синтаксиса для управления пользовательскими состояниями устройств, а затем создадим пример, который их использует.
Состояния пользовательских устройств начинаются с префикса Custom:. Текст, который появляется после префикса, может быть любым, какой хотите. Чтобы установить или прочитать значение настраиваемого состояния устройства, используйте функцию диалплана DEVICE_STATE(). Например, чтобы установить пользовательское состояние устройства:
exten => example,1,Set(DEVICE_STATE(Custom:example) = BUSY)
Аналогично, чтобы прочитать текущее значение состояния пользовательского устройства:
exten => Verbose(1,The state of Custom:example is
${DEVICE_STATE(Custom:examle)})
Пользовательские состояния устройств могут использоваться как способ прямого управления состоянием, отображаемым на устройстве, которое подписано на состояние номера. Просто сопоставьте расширение с пользовательским состоянием устройства, используя хинт в диалплане:
exten => example,hint,Custom:example
Как пример
Для пользовательских состояний устройства существует ряд интересных вариантов использования. В этом разделе мы построим пример, который реализует пользовательскую кнопку «Не беспокоить» (DND) на SIP-телефоне. Этот же подход может быть применен ко многим другим вещам, которые вы хотели бы переключать одним нажатием кнопки. Например, этот подход может использоваться чтобы сообщить участникам вошли они в очередь или нет.
Первая часть примера — это хинт в диалплане. Он необходим, таким образом, BLF может быть настроен на SIP-телефоне для подписки на этот номер. В этом случае телефон должен быть настроен для подписки на состояние DND_7015:
exten => DND_7015,hint,Custom:DND_7015
Далее мы создадим внутр.номер, который будет вызываться когда пользователь нажимает клавишу назначенную на пользовательскую функцию DND. Интересно отметить, что этот номер ничего не делает с аудио. Фактически, пользователь телефона, скорее всего, даже не узнает, что происходит звонок когда он нажимает кнопку. Что касается пользователя, нажатие этой клавиши просто включает или выключает индикацию рядом с кнопкой, которая отражает, включен ли DND. Расширение должно выглядеть так:
exten => DND_7015,1,Answer()
same => n,GotoIf($[«${DEVICE_STATE(Custom:DND_7015)}»=»BUSY»]?
turn_off:turn_on)
same => n(turn_off),Set(DEVICE_STATE(Custom:DND_7015)=NOT_INUSE)
same => n,Hangup()
same => n(turn_on),Set(DEVICE_STATE(Custom:DND_7015)=BUSY)
same => n,Hangup()
В заключительной части этого примера показано, как состояние DND используется в диалплане. Если DND включен, для вызывающего абонента воспроизводится сообщение о том, что агент недоступен. Если он отключен, на SIP-устройство будет сделан вызов:
exten => 7015,1,GotoIf($[«${DEVICE_STATE(Custom:DND_7015)}»=»BUSY»]?busy:available)
same => n(available),Verbose(3,DND is currently off for 7015.)
same => n,Dial(SIP/exampledevice)
same => n,Hangup()
same => n(busy),Verbose(3,DND is on for 7015.)
same => n,Playback(vm-theperson)
same => n,Playback(digits/7&digits/0&digits/1&digits/5)
same => n,Playback(vm-isunavail)
same => n,Playback(vm-goodbye)
same => n,Hangup()
Пример 14-1 показывает полный набор номеров, поскольку они появятся в /etc/asterisk/extensions.conf.
Пример 14-1. Пользовательская функция «Не беспокоить» с использованием пользовательских состояний устройства
;
; Хинт чтобы телефон мог использовать BLF для сигнализации о статусе DND.
;
exten => DND_7015,hint,Custom:DND_7015
;
; Номер для набора при нажатии пользовательской клавиши DND
; на своем телефоне. Это переключит состояние и приведет к включению или
; выключению индикатора на телефоне.
;
exten => DND_7015,1,Answer()
same => n,GotoIf($[«${DEVICE_STATE(Custom:DND_7015)}»=»BUSY»]?turn_off:turn_on)
same => n(turn_off),Set(DEVICE_STATE(Custom:DND_7015)=NOT_INUSE)
same => n,Hangup()
same => n(turn_on),Set(DEVICE_STATE(Custom:DND_7015)=BUSY)
same => n,Hangup()
;
; Пример использования состояния DND.
;
exten => 7015,1,GotoIf($[«${DEVICE_STATE(Custom:DND_7015)}»=»BUSY»]?busy:available)
same => n(available),Verbose(3,DND is currently off for 7015.)
same => n,Dial(SIP/exampledevice)
same => n,Hangup()
same => n(busy),Verbose(3,DND is on for 7015.)
same => n,Playback(vm-theperson)
same => n,Playback(digits/7&digits/0&digits/1&digits/5)
same => n,Playback(vm-isunavail)
same => n,Playback(vm-goodbye)
same => n,Hangup()
Распространение состояний устройств
Asterisk в основном предназначен для работы в одной системе. Однако по мере увеличения требований к масштабируемости для развертываний обычно требуется несколько серверов Asterisk. Поскольку это становится все более распространенным, некоторые функции были добавлены чтобы упростить координацию нескольких серверов Asterisk. Одна из этих функций — поддержка распространения состояний устройств.
Это означает, что если устройство находится в состоянии вызова на одном сервере Asterisk, состояние этого устройства отражается на всех серверах. Чтобы быть более конкретным, способ, которым это работает, заключается в том, что каждый сервер знает состояние каждого устройства с точки зрения каждого сервера. Используя этот набор состояний, каждый сервер будет вычислять какое общее значение состояния устройства должно сообщаться остальной части серверов Asterisk.
Для выполнения распространения состояний устройств необходимо использовать какой-то механизм обмена сообщениями, чтобы серверы взаимодействовали друг с другом. По состоянию на Asterisk 11 поддерживаются два таких механизма: Corosync и XMPP.
Использование Corosync
Corosync предоставляет набор API-интерфейсов, полезных для кластеризованных приложений. Asterisk использует группу коммуникаций Corosync API для распространения событий между кластерами серверов Asterisk.
Corosync построен таким образом, что узлы должны располагаться в одной высокоскоростной локальной сети с низкой латентностью. Если ваше развертывание географически распределено, вы должны использовать поддержку распространения состояния устройства на основе XMPP, о чем говорится в «Использование XMPP«.
Установка
Далее установите Corosync. Самый простой способ установить его — из системы управления пакетами дистрибутива. В RHEL:
$ sudo yum install corosync corosynclib corosynclib-devel
В Ubuntu:
$ sudo apt-get install corosync corosync-dev
Если вы установили Asterisk перед установкой Corosync, вам нужно будет перекомпилировать и переустановить Asterisk, чтобы получить поддержку Corosync. Начните с запуска Asterisk скрипта configure. Скрипт configure отвечает за проверку системы, для выяснения, какие дополнительные зависимости необходимо найти, чтобы система сборки знала, какие модули могут быть собраны:
$ cd /путь/до/asterisk
$ ./configure
После запуска скрипта configure запустите menuselect — инструмент для указания сборки модуля res_corosync (этот модуль может быть найден в разделе Resourse Modules меню menuselect):
$ make menuselect
Наконец, скомпилируйте и установите Asterisk:
$ make
$ sudo make install
Это довольно быстрый и грубый набор инструкций для компиляции и установки Asterisk. Для получения более полного набора инструкций см. Главу 3.
Конфигурация Corosync
Теперь, когда Corosync установлен, его необходимо настроить. Для Corosync есть файл конфигурации, который должен быть установлен. Проверьте, существует ли файл /etc/corosync/corosync.conf. Если нет, то в /etc/corosync должны быть образцы для начала работы.
При написании этого раздела были использованы следующие конфигурации corosync.conf для простой настройки между двумя виртуальными машинами. Эта настройка использует транспорт udpu, что означает выполнение одноадресной рассылки (unicast) между двумя узлами вместо многоадресной рассылки (multicast), которая является традиционным транспортом Corosync:
# Пожалуйста, прочтите страницу руководства corosync.conf.5
compatibility: whitetank
totem {
version: 2
secauth: off
interface {
member {
memberaddr: 192.168.122.250
}
member {
memberaddr: 192.168.122.94
}
ringnumber: 0
bindnetaddr: 192.168.122.0
mcastport: 5405
ttl: 1
}
transport: udpu
}
logging {
fileline: off
to_logfile: yes
to_syslog: yes
debug: on
logfile: /var/log/corosync/corosync.log
debug: off
timestamp: on
logger_subsys {
subsys: AMF
debug: off
}
}
Для подробной документации о параметрах в этом файле конфигурация, см связанной справочной страницы:
$ man corosync.conf
Для Corosync должен быть создан ещё один файл. Corosync необходимо сообщить, что приложениям, запущенным от имени пользователя asteriskpbx разрешено подключаться к нему. Поместите следующее содержимое в новый файл с именем /etc/corosync/uidgid.d/asterisk:
uidgid {
uid: asteriskpbx
gid: asteriskpbx
}
Как только конфигурация завершена, запустите службу Corosync:
$ sudo service corosync start
Если у вас возникли проблемы с синхронизацией узлов друг с другом, проверьте, нет ли правил брандмауэра на узлах, которые блокируют многоадресный трафик, используемый для обмена данными между узлами.
Конфигурация Asterisk
Модуль res_corosync для Asterisk имеет один файл конфигурации /etc/asterisk/res_corosync.conf. В этом файле требуется один короткий раздел чтобы включить распространение состояний устройств в кластере Corosync. Поместите следующее содержимое в файл /etc/asterisk/res_corosync.conf :
[general]
publish_event = device_state
subscribe_event = device_state
Команда CLI Asterisk может использоваться чтобы гарантировать правильность загрузки этой конфигурации:
*CLI> corosync show config
=============================================================
=== res_corosync config =====================================
=============================================================
===
=== ==> Publishing Event Type: device_state
=== ==> Subscribing to Event Type: device_state
=== ==> Publishing Event Type: ping
=== ==> Subscribing to Event Type: ping
===
=============================================================
Другая полезная команда Asterisk CLI, предоставленная модулем res_corosync, используется для перечисления участников кластера Corosync:
*CLI> corosync show members
=============================================================
=== Cluster members =========================================
=============================================================
===
=== Node 1
=== —> Group: asterisk
=== —> Address 1: 192.168.122.94
=== Node 2
=== —> Group: asterisk
=== —> Address 1: 192.168.122.250
===
=============================================================
Тестирование изменения состояний устройств
Теперь, когда вы установили и сконфигурировали распространение состояния устройства с помощью Corosync, есть несколько простых тестов, которые можно выполнить с помощью пользовательских состояний устройств, чтобы обеспечить связь состояний устройств между серверами. Начните с создания тестового хинта в диалплане Asterisk /etc/asterisk/extensions.conf:
[devstate_test]
exten=> foo,hint,Custom:abc
Теперь вы можете настроить пользовательское состояние устройства из командной строки Asterisk с помощью команды CLI dialplan set global, а затем проверить состояние на каждом сервере с помощью команды core show hints. Например, мы можем использовать эту команду для установки состояния на одном сервере:
pbx1*CLI> dialplan set global DEVICE_STATE(Custom:abc) INUSE
— Global variable ‘DEVICE_STATE(Custom:abc)’ set to ‘INUSE’
а затем, проверьте состояние на другом сервере с помощью этой команды:
*CLI> core show hints
-= Registered Asterisk Dial Plan Hints =-
foo@devstatetest : Custom:abc State:InUse Watchers 0
Если вы хотите глубже погрузиться в обработку изменения распределения состояния устройства, могут быть включены некоторые полезные отладочные сообщения. Во-первых, включите отладку на консоли Asterisk в /etc/asterisk/logger.conf. Затем включите отладку в командной строке Asterisk CLI:
*CLI> core set debug 1
Когда вывод debug будет включен, вы увидите сообщения, которые показывают, как Asterisk обрабатывает каждое изменение состояния. Когда состояние устройства изменяется на одном сервере, Asterisk проверяет информацию о состоянии этого устройства на всех серверах и определяет общее состояние устройства. Следующие примеры иллюстрируют:
*CLI> dialplan set global DEVICE_STATE(Custom:abc) NOT_INUSE
— Global variable ‘DEVICE_STATE(Custom:abc)’ set to ‘NOT_INUSE’
[Nov 13 13:27:12] DEBUG[14801]: devicestate.c:652
handle_devstate_change: Processing device state change for ‘Custom:abc’
[Nov 13 13:27:12] DEBUG[14801]: devicestate.c:602
process_collection: Adding per-server state of ‘Not in use’ for ‘Custom:abc’
[Nov 13 13:27:12] DEBUG[14801]: devicestate.c:602
process_collection: Adding per-server state of ‘Not in use’ for ‘Custom:abc’
[Nov 13 13:27:12] DEBUG[14801]: devicestate.c:609
process_collection: Aggregate devstate result is ‘Not in use’ for ‘Custom:abc’
[Nov 13 13:27:12] DEBUG[14801]: devicestate.c:631
process_collection: Aggregate state for device ‘Custom:abc’ has changed to
‘Not in use’
*CLI> dialplan set global DEVICE_STATE(Custom:abc) INUSE
— Global variable ‘DEVICE_STATE(Custom:abc)’ set to ‘INUSE’
[Nov 13 13:29:30] DEBUG[14801]: devicestate.c:652 handle_devstate_change:
Processing device state change for ‘Custom:abc’
[Nov 13 13:29:30] DEBUG[14801]: devicestate.c:602 process_collection:
Adding per-server state of ‘Not in use’ for ‘Custom:abc’
[Nov 13 13:29:30] DEBUG[14801]: devicestate.c:602 process_collection:
Adding per-server state of ‘In use’ for ‘Custom:abc’
[Nov 13 13:29:30] DEBUG[14801]: devicestate.c:609 process_collection:
Aggregate devstate result is ‘In use’ for ‘Custom:abc’
[Nov 13 13:29:30] DEBUG[14801]: devicestate.c:631 process_collection:
Aggregate state for device ‘Custom:abc’ has changed to ‘In use’
Использование XMPP
eXtensible Messaging and Presence Protocol (XMPP) (расширяемый протокол обмена сообщениями о присутствии) ранее (и до сих пор) известный как Jabber, является протоколом связи, стандартизированным Internet Engineering Task Force (IETF). Он чаще всего известен как протокол IM, но его можно использовать и для ряда других интересных приложений. Фонд стандартов XMPP (XSF) работает для стандартизации расширений к протоколу XMPP. Одно из таких расширений, называемое PubSub, обеспечивает механизм публикации/подписки.
Asterisk имеет возможность использовать XMPP PubSub для распространения информации о состоянии устройства. Одна из приятных особенностей использования XMPP заключается в том, что он отлично работает для географически распределенных серверов Asterisk.
Установка
Чтобы распространять состояния устройств с помощью XMPP вам понадобится сервер XMPP, поддерживающий PubSub. Одним из таких серверов, который был успешно протестирован с Asterisk, является Tigase.
На веб-сайте Tigase есть инструкции по установке и настройке сервера Tigase. Мы предлагаем вам следовать этим инструкциям (или инструкциям, предоставленным для любого другого сервера, который вы можете использовать) и вернуться к этой книге, когда вы будете готовы работать с определенными компонентами Asterisk.
На стороне Asterisk вам нужно будет убедиться, что вы установили модуль res_jabber. Вы можете проверить, загружен ли он в CLI Asterisk:
*CLI> module show like jabber
Module Description Use Count
res_jabber.so AJI — Asterisk Jabber Interface 0
1 modules load
Если вы используете пользовательский /etc/asterisk/modules.conf, в котором перечислены только определенные модули для загрузки, вы также можете проверить файловую систему, чтобы узнать, был ли скомпилирован и установлен модуль:
$ cd /usr/lib/asterisk/modules
$ ls -l res_jabber.so
-rwxr-xr-x 1 root root 837436
2010-11-12 15:33 res_jabber.so
Если у вас еще нет res_jabber, вам нужно будет установить iksemel и библиотеки OpenSSL. Затем вам нужно будет пересобрать и переустановить Asterisk. Начните с запуска скрипта Asterisk configure, который отвечает за проверку системы и определение дополнительных зависимостей, чтобы система сборки знала, какие модули могут быть собраны:
$ cd /путь/до/asterisk
$ ./configure
После запуска скрипта configure, запустите menuselect чтобы гарантировать, что Asterisk было сказано собрать модуль res_jabber. Этот модуль можно найти в разделе Resourse Modules меню menuselect:
$ make menuselect
Наконец, скомпилируйте и установите Asterisk:
$ make
$ sudo make install
Это довольно быстрый и грубый набор инструкций для сборки и установки Asterisk. Для получения более полного набора инструкций см. Главу 3.
Создание учетных записей XMPP
К сожалению, Asterisk в настоящее время не может регистрировать новые учетные записи на сервере XMPP. Вам нужно будет создать учетную запись для каждого сервера через какой-либо другой механизм. Метод, который мы использовали во время тестирования заключался в том, чтобы завершить регистрацию аккаунта через клиент XMPP, такой как Pidgin. После завершения регистрации учетной записи клиент XMPP больше не нужен. Для остальных примеров мы будем использовать следующих двух приятелей, которые оба находятся на сервере jabber.shifteight.org:
- [email protected]/astvoip1
- [email protected]/astvoip2
Конфигурация Asterisk
Файл /etc/asterisk/jabber.conf необходимо будет настроить на каждом сервере. Покажем конфигурацию для установки двух серверов здесь, но конфигурация может быть легко расширена на нескольких серверах при необходимости. Пример 14-2. показывает содержимое файла конфигурации для сервера 1, а Пример 14-3 — для сервера 2. Дополнительные сведения о параметрах jabber.conf, связанных с распределением состояний устройств, см. в файле configs/jabber.conf.sample, который включен в исходное дерево Asterisk.
Пример 14-2. jabber.conf для server1
[general]
autoregister = yes
[asterisk]
type = client
serverhost = jabber.shifteight.org
pubsub_node = pubsub.jabber.shifteight.org
username = [email protected]/astvoip1
secret = mypassword
distribute_events = yes
status = доступно
usetls = no
usesasl = yes
buddy = [email protected]/astvoip2
Пример 14-3. jabber.conf для server2
[general]
autoregister = yes
[asterisk]
type = client
serverhost = jabber.shifteight.org
pubsub_node = pubsub.jabber.shifteight.org
username = [email protected]/astvoip2
secret = mypassword
distribute_events = yes
status = доступно
usetls = no
usesasl = yes
buddy = [email protected]/astvoip1
Тестирование
Чтобы все работало правильно, начните с выполнения проверки параметров jabber.conf на каждом сервере. Пара соответствующих команд CLI Asterisk может быть использована. Первая — это jabber show connected, которая проверит, что Asterisk успешно вошел в систему с учетной записью на jabber сервере. Вывод этой команды на первом сервере показывает:
*CLI> jabber show connected
Jabber Users and their status:
User: [email protected]/astvoip1 — Connected
—-
Number of users: 1
Между тем, если jabber show connect выполняется на втором сервере, это покажет:
*CLI> jabber show connected
Jabber Users and their status:
User: [email protected]/astvoip2 — Connected
—-
Number of users: 1
Следующая полезная команда для проверка настройки — это jabber show buddies. Эта команда позволяет проверить, правильно ли указан другой сервер в списке приятелей. Она также позволяет увидеть, доступен ли другой сервер в настоящее время. Если вы запустите эту команду на первом сервере без запущенной Asterisk на втором сервере, вывод будет выглядеть следующим образом:
*CLI> jabber show buddies
Jabber buddy lists
Client: [email protected]/astvoip1
Buddy: [email protected]
Resource: None
Buddy: [email protected]/astvoip2
Resource: None
Затем запустите Asterisk на втором сервере и выполните jabber show buddies на этом сервере. Вывод будет содержать больше информации, так как второй сервер увидит первый сервер онлайн:
*CLI> jabber show buddies
Jabber buddy lists
Client: [email protected]/astvoip2
Buddy: [email protected]
Resource: astvoip1
node: http://www.asterisk.org/xmpp/client/caps
version: asterisk-xmpp
Jingle capable: yes
Status: 1
Priority: 0
Buddy: [email protected]/astvoip1
Resource: None
На данный момент вы должны быть готовы проверить распределение состояний устройств. Процедура такая же, как и для тестирования состояний устройств с помощью Corosync, которые можно найти в «Тестирование изменения состояний устройств«.
Общие внешние линии
В Asterisk, Shared Line Appearances (SLA) (Общие внешние линии — ОВЛ) — иногда также упоминаемые в отрасли как Bridged Line Appearances (BLA) (Общие соединительные линии — ОСЛ) — могут быть использованы. Эта функциональность может использоваться для удовлетворения двух основных потребностей, которые включают эмуляцию простой системы клавиш и создание общих внутренних номеров на УАТС.
Создание системы эмуляции клавиш — это то, для чего в первую очередь предназначались эти приложения. В этой среде у вас есть небольшое количество транков, входящих в УАТС, таких как аналоговые телефонные линии, и каждый телефон имеет специальную кнопку для вызовов на этом транке. Например, вы можете ссылаться на эти транки, например как line1,line2 и line3.
Другой вариант использования — создание общих внутренних номеров вашей УАТС. Этот прецедент является наиболее распространенным в наши дни. Есть множество причин, по которым вы можете это сделать; например, вы можете захотеть, чтобы номер появлялся на телефонах как исполнителя, так и его помощника по административным вопросам. Другим примером может быть, если вы хотите, чтобы так же номер отображался на всех телефонах в той же лаборатории.
Хотя эти варианты использования поддерживаются в определенной степени, существуют ограничения. В Asterisk еще предстоит проделать большую работу, чтобы эти функции работали действительно хорошо для того, что люди хотят с ними делать. Это обсуждается в разделе «Ограничения«.
Установка приложений SLA
Приложения SLA построены на двух ключевых технологиях Asterisk. Первый — это обработка состояний устройств, а второй — конференц-связь. В частности, конференц-связь, используемая этими приложениями, является приложением MeetMe(). Приложения SLA поставляются с тем же модулем, что и приложение MeetMe(), поэтому необходимо установить модуль app_meetme.
Вы можете проверить в CLI Asterisk, чтобы увидеть, имеется ли этот модуль:
pbx*CLI> module show like app_meetme.so
Module Description Use Count
0 modules loaded
В этом случае модуль отсутствует. Наиболее распространенная причина, по которой система Asterisk не будет иметь модуль app_meetme — не был установлен DAHDI. Приложение MeetMe() использует DAHDI для микширования конференций.
Дополнительные сведения о конференц-связи MeetMe() см. в разделе “Конференц-связь с MeetMe()” в Главе 10. Вам потребуется res_timing_dahdi и DAHDI для установки, так как MeetMe() требует его для выполнения микширования. К сожалению, в Asterisk 11, в приложение ConfBridge() еще не добавлена необходимая функциональность для SLA.
После установки DAHDI (см. Главу 3 для информации об установке) повторно запустите скрипт configure, перекомпилируйте с помощью make и переустановите с помощью sudo make install. После того, как модуль был правильно установлен (вы можете использовать module load app_meetme.so из консоли Asterisk), вы должны увидеть его состояние в CLI:
*CLI> module show like app_meetme.so
Module Description Use Count
app_meetme.so MeetMe conference bridge 0
1 modules loaded
Как только модуль app_meetme загружен, вы должны иметь оба приложения SLAStation() и SLATrunk():
*CLI> core show applications like SLA
-= Matching Asterisk Applications =-
SLAStation: Shared Line Appearance Station.
SLATrunk: Shared Line Appearance Trunk.
-= 2 Applications Matching =-
Обзор конфигурации
Для настройки SLA необходимо отредактировать два основных файла конфигурации: /etc/asterisk/extensions.conf и /etc/asterisk/sla.conf. Файл sla.conf используется для определения транков и станций. Станция — это любой SIP-телефон, который будет использовать SLA. Транки — это буквально транки или общие внутренние номера, которые будут отображаться на двух или более станциях. Диалплан Asterisk extensions.conf, обеспечивает некий важный клей, который объединяет конфигурацию SLA. Вложения (includes) диалплана включают некоторые хинты состояний номеров и номера, которые определяют, как вызовы входят и выходят из установки SLA. Следующие несколько разделов содержат подробные примеры конфигурации для нескольких различных случаев использования.
Пример системы клавиш и аналоговых транков
Это использование SLA поставляется с самой простой конфигурацией.2 Этот сценарий обычно использовался для довольно небольшого количества установок, где у вас есть несколько аналоговых линий и SIP-телефонов, у которых есть клавиши линии, непосредственно связанные с аналоговыми линиями. Для целей этого примера мы предположим что имеем две аналоговые линии и четыре SIP-телефона. Каждый SIP-телефон будет иметь кнопку для line1 и кнопку для line2. В этом разделе предполагается, что вы предварительно выполнили некоторые настройки, в том числе:
- Настроенные четыре SIP-телефона. Для получения дополнительной информации о настройке SIP-телефонов см. Главу 5.
- Настроенные две аналоговые линии. Более подробную информацию о настройке аналоговых линий с помощью Asterisk см. в Главе 7.
В этом примере мы будем использовать следующие имена устройств для SIP-телефонов и аналоговых линий. Не забудьте адаптировать примеры в соответствии с вашей конфигурацией:
- SIP/station1
- SIP/station2
- SIP/station3
- SIP/station4
- DAHDI/1
- DAHDI/2
sla.conf
Как упоминалось ранее, sla.conf содержит настройки сопоставления устройств для транков и станций. В этом примере мы начнем с определения двух транков:
[line1]
type = trunk
device = DAHDI/1
[line2]
type = trunk
device = DAHDI/2
Далее мы настроим определение станций. У нас есть четыре SIP-телефона, каждый из которых будет использовать оба транка. Обратите внимание, что имена разделов в sla.conf для станций не должны совпадать с именами SIP-устройств, но это сделано таким образом здесь для удобства:
[station1]
type = station
device = SIP/station1
trunk = line1
trunk = line2
[station2]
type = station
device = SIP/station2
trunk = line1
trunk = line2
[station3]
type = station
device = SIP/station3
trunk = line1
trunk = line2
[station4]
type = station
device = SIP/station4
trunk = line1
trunk = line2
Конфигурация станций немного повторяющаяся. Секции шаблона конфигурационного файла Asterisk пригодятся здесь, чтобы немного уменьшить конфигурацию. Вот конфигурация станций снова, но на этот раз с использованием шаблона:
[station](!)
type = station
trunk = line1
trunk = line2
[station1](station)
device = SIP/station1
[station2](station)
device = SIP/station2
[station3](station)
device = SIP/station3
[station4](station)
device = SIP/station4
После внесения изменений в sla.conf и сохранения их, не забудьте перезагрузить модуль app_meetme чтобы изменения вступили в силу. Вы можете сделать это с помощью module reloadapp_meetme из консоли Asterisk.
extensions.conf
Следующий файл конфигурации, необходимый для этого примера — /etc/asterisk/extensions.conf. Существует три контекста. Во-первых, у нас есть контексты line1 и line2. Когда вызов поступает на одну из аналоговых линий, он входит в одном из этих контекстов в диалплан и выполняет приложение SLATrunk(). Это приложение будет заботиться о вызове всех соответствующих станций:
[line1]
exten => s,1,SLATrunk(line1)
[line2]
exten => s,1,SLATrunk(line2)
Следующий раздел диалплана — контекст sla_stations. Все вызовы от телефонов SIP должны быть переданы этому контексту. Далее SIP-телефоны должны быть настроены так, чтобы как только поднимается трубка, они немедленно делают вызов к номеру station1 (или station2, station3, и т.д. в соответствующих случаях). Если на телефоне нажата клавиша line1, то вызов должен быть отправлен на добавочный номер station 1_line1 (или station 2_line1 и т.д.).
Формат station1_line1 имеет особое значение для приложения SLAStation(). Разделитель подчеркивание (_) определяет, какую станцию и транк использовать для вызова. Помните об этом при именовании станций или транков, так как использование подчеркивания в их именах нарушит функциональность.
Каждый раз, когда поднимается телефонная трубка или нажата клавиша line, сделанный вызов немедленно соединит его с одной из аналоговых линий. Для линии, которая еще не используется, аналоговая линия будет обеспечивать сигнал готовности вызова, и пользователь сможет набрать цифры, чтобы сделать вызов. Если пользователь нажимает клавишу line для линии, которая уже используется, то пользователь будет соединен с существующим вызовом на той линии. Контекст sla_stations выглядит так:
[sla_stations]
exten => station1,1,SLAStation(station1)
exten => station1_line1,hint,SLA:station1_line1
exten => station1_line1,1,SLAStation(station1_line1)
exten => station1_line2,hint,SLA:station1_line2
exten => station1_line2,1,SLAStation(station1_line2)
exten => station2,1,SLAStation(station2)
exten => station2_line1,hint,SLA:station2_line1
exten => station2_line1,1,SLAStation(station2_line1)
exten => station2_line2,hint,SLA:station2_line2
exten => station2_line2,1,SLAStation(station2_line2)
exten => station3,1,SLAStation(station3)
exten => station3_line1,hint,SLA:station3_line1
exten => station3_line1,1,SLAStation(station3_line1)
exten => station3_line2,hint,SLA:station3_line2
exten => station3_line2,1,SLAStation(station3_line2)
exten => station4,1,SLAStation(station4)
exten => station4_line1,hint,SLA:station4_line1
exten => station4_line1,1,SLAStation(station4_line1)
exten => station4_line2,hint,SLA:station4_line2
exten => station4_line2,1,SLAStation(station4_line2)
После внесения изменений обязательно перезагрузите диалплан с помощью dialplan reload.
Дополнительные задачи по настройке телефона
В предыдущем разделе описана схема набора номеров для транков и станций. При настройке телефонов для использования с этой опцией необходимо учитывать некоторые особенности. Во-первых, каждый телефон должен быть настроен на отправку вызова как только снята трубка.
Другим важным пунктом является настройка клавиш линии. Asterisk использует подписки на состояния номеров для управления светодиодами рядом с кнопками линий. Кроме того, каждая кнопка линии должна быть настроена как быстрый набор. Используйте следующий контрольный список для конфигурации клавиш линии (выполнение этих задач будет зависеть от конкретных телефонов, которые вы используете):
- Установите метку клавиши на Line 1 (и т.д.) или как вы считаете нужным.
- Настройте клавиши так, чтобы клавиша Line 1 на station1 подписывалась на состояние station1_line1 и так далее. Это необходимо чтобы Asterisk мог заставить светодиоды отражать состояния линий.
- Убедитесь что если клавиша Line 1 на station1 нажата, вызов направляется в добавочный номер station1_line1 и так далее.
Пример системы клавиш с SIP-транками
Этот пример по функциональности идентичен предыдущему примеру. Разница в том, что вместо использования аналоговых линий в качестве транков мы будем использовать соединение с SIP-провайдером, который будет терминировать вызовы ТфОП. Для получения дополнительной информации о настройке Asterisk для подключения к SIP-провайдеру см. Главу 7.
sla.conf
Файл sla.conf для этого сценария будет немного сложнее.3 Вы можете ожидать, что в линии устройства в конфигурации транка будет указан канал SIP, но вместо этого мы будем использовать локальный канал. Это позволит нам использовать дополнительную логику диалплана для обработки вызовов. Назначение локального канала станет более понятным в следующем разделе, когда обсуждается пример диалплана. Вот конфигурации транка:
[line1]
type = trunk
device = Local/disa@line1_outbound
[line2]
type = trunk
device = Local/disa@line2_outbound
Конфигурация станции идентична последнему примеру, поэтому давайте вернемся к ней:
[station](!)
type = trunk
trunk = line1
trunk = line2
[station1](station)
device = SIP/station1
[station2](station)
device = SIP/station2
[station3](station)
device = SIP/station3
[station4](station)
device = SIP/station4
extensions.conf
Как и в предыдущем примере, вам необходимы контексты line1 и line2 для обработки входящих вызовов на этих транках:
[line1]
exten => s,1,SLATrunk(line1)
;
; Если провайдер указывает ваш номер телефона при отправке вызова, то
; потребуется другое правило в диалплане чтобы соответствовать этому.
;
exten => _X.,1,Goto(s,1)
[line2]
exten => s,1,SLATrunk(line2)
exten => _X.,1,Goto(s,1)
В этом примере так же потребуется контекст sla_stations. Это для всех звонков с телефонов. Это то же самое, что и в последнем примере:
[sla_stations]
exten => station1,1,SLAStation(station1)
exten => station1_line1,hint,SLA:station1_line1
exten => station1_line1,1,SLAStation(station1_line1)
exten => station1_line2,hint,SLA:station1_line2
exten => station1_line2,1,SLAStation(station1_line2)
exten => station2,1,SLAStation(station2)
exten => station2_line1,hint,SLA:station2_line1
exten => station2_line1,1,SLAStation(station2_line1)
exten => station2_line2,hint,SLA:station2_line2
exten => station2_line2,1,SLAStation(station2_line2)
exten => station3,1,SLAStation(station3)
exten => station3_line1,hint,SLA:station3_line1
exten => station3_line1,1,SLAStation(station3_line1)
exten => station3_line2,hint,SLA:station3_line2
exten => station3_line2,1,SLAStation(station3_line2)
exten => station4,1,SLAStation(station4)
exten => station4_line1,hint,SLA:station4_line1
exten => station4_line1,1,SLAStation(station4_line1)
exten => station4_line2,hint,SLA:station4_line2
exten => station4_line2,1,SLAStation(station4_line2)
Последний требуемый кусок диалплана — это реализация контекстов line1_outbound и line2_outbound. Это то, что приложения SLA используют когда хотят отправить вызов SIP-провайдеру. Ключом к этой настройке является использование приложения Read(). В последнем примере телефоны были напрямую подключены к аналоговой линии, что позволяло комутатору предоставлять тональный сигнал вызова, получать цифры и завершать вызов. В этом примере мы используем приложение Read() локально для предоставления тонального сигнала и получения цифр. Обычно Read() воспроизводит звуковой файл, но с помощью параметра i мы можем указать, какую индикацию воспроизводить из файла indications.conf. В этом случае мы будем использовать dial, который воспроизводит сигнал набора. Набранный номер будет сохранен в переменной канала Request и мы прекратим получать цифры либо по истечении времени ожидания, либо после набора максимума из 11 цифр.
После того, как будет набран полный номер, вызов будет продолжен и передан SIP-провайдеру:
[line1_outbound]
exten => disa,1,NoOp()
same => n,Read(Request,dial,11,i)
same => n,Goto(${Request},1)
; Добавьте внутренние номера для любых внешних номеров, набор которых вы
; хотите разрешить.
;
exten => _1NXXNXXXXXX,1,Dial(SIP/${EXTEN}@myprovider)
[line2_outbound]
exten => disa,1,NoOp()
same => n,Read(Request,dial,11,i)
same => n,Goto(${Request},1)
exten => _1NXXNXXXXXX,1,Dial(SIP/${EXTEN}@myprovider)
Пример системы альтернативных клавиш с SIP-транками
Чтобы продемонстрировать некоторую гибкость в отношении конфигурации линии, мы покажем пример реализации функциональности клавиш линии с помощью SIP-транков и станций. Мы будем использовать те же понятия, что и в предыдущих разделах, поэтому может быть полезно ознакомиться с ними, прежде чем продолжить. То, что мы будем создавать, можно охарактеризовать как своего рода гибридную модель, в которой у нас будет одна строка регистрации, которую можно использовать как стандартную строку в вашей системе Asterisk. У неё не будет никаких ограничений по функциональности, включая возможность переадресации звонков. Дополнительные линии, которые мы определили, будут действовать больше как традиционная система SLA, в которой трансферы невозможны, но совместное использование транков будет возможно.
В нашем примере мы будем определять отдельные строки для каждой из наших станций в sla.conf. Этот альтернативный метод позволяет нам подписывать клавиши линий на нашем телефоне на каждую из определенных линий. Во-первых, мы определяем наши транки как и ранее (однако, слегка модифицированные):
[T1] ; Line 1
type=trunk
device=Local/trunk1@sla_trunks/n
[T2] ; Line 2
type=trunk
device=Local/trunk2@sla_trunks/n
Затем нам нужно определить наши линии, которые мы свяжем с телефонами. Чтобы не быть слишком многословным, мы определим линии для двух станций, причем две линии для каждой:
[L1-0000FFFF0005] ; Line 1
type=station
device=SIP/0000FFFF0005
trunk=T1
[L2-0000FFFF0005] ; Line 2
type=station
device=SIP/0000FFFF0005
trunk=T2
[L1-0000FFFF0006] ; Line 1
type=station
device=SIP/0000FFFF0006
trunk=T1
[L2-0000FFFF0006] ; Line 2
type=station
device=SIP/0000FFFF0006
trunk=T2
Как вы можете видеть, с точки зрения Asterisk определены четыре станции. Мы логически разделили каждый из транков на отдельные клавиши линий, на которые можно подписаться с любого устройства. Здесь подразумевается, что нашими станциями являются SIP/0000FFFF0005 и SIP/0000FFFF0006, и каждая из них будет содержать две клавиши линий, которые связаны с транками T1 и T2. После внесения наших изменений в sla.conf мы должны обязательно перезагрузить app_meetme.so с помощью module reload app_meetme.so из консоли Asterisk.
Далее нужно настроить наш диалплан. Мы добавим к существующему контексту LocalSets, так как хотим чтобы телефоны могли нормально выполнять вызовы в дополнение к использованию клавиш линий SLA. В нашем примере мы просто покажем части, относящиеся к SLA:
[LocalSets]
include => SLA_Outbound
exten => L1-0000FFFF0005_T1,hint,SLA:L1-0000FFFF0005_T1
exten => L2-0000FFFF0005_T2,hint,SLA:L2-0000FFFF0005_T2
exten => L1-0000FFFF0006_T1,hint,SLA:L1-0000FFFF0006_T1
exten => L2-0000FFFF0006_T2,hint,SLA:L2-0000FFFF0006_T2
Здесь мы включили новый контекст под названием SLA_Outbound, который будет обрабатывать запросы, сделанные телефоном, когда клавиша линии нажата. Мы также включили наши хинты SLA, которые будут использоваться приложениями абонентской группы SLA для управления подсветкой клавиш линии.
Теперь давайте добавим контекст SLA_Outbound:
[SLA_Outbound]
exten => _LX!,1,NoOp()
same => n,SLAStation(${EXTEN})
same => n,Hangup()
И нам также понадобится контекст sla_trunks, который используется для фактического размещения исходящих звонков. Мы определили, что используется этот контекст в файле sla.conf, когда создавали наши транки.
Причина, по которой мы имеем [n] в сопоставлении с образцом _tru[n]kX, заключается в том, что буква n будет соответствовать не букве, а цифре от 2 до 9. Поскольку мы хотим, чтобы соответствовало слову trunk, мы можем сделать n буквой, заключив её в квадратные скобки. Буква X будет соответствовать цифрам от 0 до 9.
[sla_trunks]
exten => _tru[n]kX,1,NoOp()
same => n,Read(Request,dial,10,i)
same => n,Dial(SIP/my_itsp/${Request})
Последний бит диалплана — нам нужно добавить для входящих вызовов для SLA-транков. Мы можем добавить это следующим образом:
[SLA_Inbound]
exten => _LX!,1,NoOp()
same => n,Set(slaLineId=${EXTEN:1:1})
same => n,SLATrunk(T${slaLineId})
same => n,Hangup()
После внесения изменений в extensions.conf вы должны выполнить dialplan reload из консоли Asterisk.
К этому моменту мы завершили настройку Asterisk для использования SLA, но настройка телефонов — действительно самая сложная часть. Мы не можем углубиться в конфигурацию каждого производителя, но мы можем, по крайней мере, дать вам отправную точку. На телефонах Polycom (протестировано с Soundpoint IP450 и Soundpoint IP650) вы можете использовать конфигурацию оператора для создания клавиш линий, которые соответствуют состоянию созданных нами хинтов SLA. При совершении звонков по этим линиям они используют клавишу первой линии, определенную для телефона, поэтому у вас фактически будут настроены три клавиши линии. Клавиша первой линии будет стандартной, которая может выполнять трансферы и другие стандартные функции. Две другие клавиши линий будут действовать как линии SLA.
Пример конфигурации, который мы использовали в лаборатории, выглядит следующим образом. Это может дать вам достаточно данных для начала работы:
<?xml version=»1.0″ encoding=»UTF-8″ standalone=»yes»?>
<!— Generated reg-basic.cfg Configuration File —>
<polycomConfig xmlns:xsi=»http://www.w3.org/2001/XMLSchema-instance»
xsi:noNamespaceSchemaLocation=»polycomConfig.xsd»>
<call call.callsPerLineKey=»24″>
</call>
<reg reg.1.address=»0000FFFF0005″
reg.1.auth.password=»welcome»
reg.1.auth.userId=»0000FFFF0005″
reg.1.label=»ATDG5″
reg.1.lineKeys=»1″
reg.1.outboundProxy.address=»»>
</reg>
<attendant
attendant.reg=»1″
attendant.behaviors.display.spontaneousCallAppearances.normal=»1″
attendant.behaviors.display.remoteCallerID.normal=»1″
attendant.resourceList.1.address=»L1-0000FFFF0005_T1″
attendant.resourceList.1.label=»L1″
attendant.resourceList.1.type=»normal»
attendant.resourceList.2.address=»L2-0000FFFF0005_T2″
attendant.resourceList.2.label=»L2″
attendant.resourceList.2.type=»normal»
/>
</polycomConfig>
Пример общего внутреннего номера
Предыдущие два примера были для эмуляции малых системных клавиш. Для этого примера мы попробуем что-то совсем другое. Многие поставщики УАТС предлагают возможность совместного использования одного и того же внутреннего номера несколькими телефонами. Это не просто вопрос вызова нескольких телефонов при вызове одного добавочного номера — это более глубокая интеграция. Поведение клавиши линии для общего номера аналогично поведению клавиши линии как системной. Например, вы можете просто приостановить вызов с одного телефона и принять его с другого. Кроме того, если несколько телефонов нажимают клавишу для общего добавочного номера, все они будут соединены в один и тот же вызов. Вот почему эта функциональность часто также упоминается как Bridged Line Appearances (BLA) — внешняя соединительная линия.
В предыдущих двух примерах у нас было два транка и четыре станции. Для этого примера мы собираемся установить один общий номер на двух телефонах. Общий номер будет упоминаться как номер 5001.
sla.conf
Каждое использование приложений SLA требует определения транка и станции. Этот пример, как и предыдущие, будет использовать приложение Read(), и файл sla.conf будет выглядеть очень похоже:
[5001]
type = trunk
device = Local/disa@5001_outbound
[5001-phone1]
device = SIP/5001_phone1
trunk = 5001
[5001-phone2]
device = SIP/5001_phone2
trunk = 5001
extensions.conf
Первая часть требуемого диалплана — это то, что будет выполняться при наборе добавочного номера 5001 на УАТС. Обычно для вызова телефона используется приложение Dial(). В этом случае мы будем использовать приложение SLATrunk(). Это позаботится о том, чтобы звонить на оба телефона и соединять их вместе:
exten => 5001,1,SLATrunk(5001)
Далее нам понадобится контекст, который будет использоваться для исходящих вызовов с этого общего добавочного номера. Здесь предполагается что 5001_phone1 и 5001_phone2 были настроены с параметрами context, установленными на 5001 в sip.conf:
[5001]
;
; Этот номер необходим если вы хотите, чтобы общий номер использовался по
; умолчанию. В этом случае наберите этот добавочный номер,
; когда трубка будет снята.
;
exten => 5001-phone1,1,SLAStation(5001-phone1)
;
; Это добавочный номер, который должен быть набран при нажатии клавиши 5001 на
; 5001_phone1.
;
exten => 5001-phone1_5001,hint,SLA:5001-phone1_5001
exten => 5001-phone1_5001,1,SLAStation(5001-phone1_5001)
exten => 5001-phone2,1,SLAStation(5001-phone2)
exten => 5001-phone2_5001,hint,SLA:5001-phone2_5001
exten => 5001-phone2_5001,1,SLAStation(5001-phone2_5001)
Наконец, нам нужна реализация контекста 5001_outbound. Он будет использоваться для предоставления тонального сигнала и сбора цифр для соединительной линии:
[5001_outbound]
exten => disa,1,Read(Request,dial,,i)
same => n,Goto(${Request},1)
;
; Этот контекст также должен быть в состоянии видеть любые внутренние номера,
; которые вы хотели бы сделать доступными из этого добавочного номера.
;
include => pbx_extensions
Расширенная конфигурация
В файле /etc/asterisk/sla.conf есть несколько необязательных параметров конфигурации, которые не использовались ни в одном из примеров в этой главе. Чтобы дать вам представление о том, какое другое поведение можно настроить, параметры описаны здесь. Этот файл имеет раздел [general], который зарезервирован для глобальных параметров конфигурации. В настоящее время в этом разделе может быть указан только один параметр:
attemptcallerid = yes
Этот параметр указывает, должны ли приложения SLA пытаться передавать информацию о callerID. По умолчанию установлено значение no. Если же включено, отображение телефонов может не соответствовать ожиданиям в некоторых ситуациях.
В определениях транков в предыдущих примерах указаны только тип и устройство. Вот некоторые дополнительные параметры, которые можно указать для транка:
autocontext = line1
Если этот параметр установлен, Asterisk автоматически создаст контекст диалплана используя это имя. Контекст будет содержать добавочный номер s, который выполняет приложение SLATrunk() с соответствующим аргументом для этого транка. По умолчанию все записи диалплана должны быть созданы вручную.
ringtimeout = 20
Этот параметр позволяет указать количество секунд, в течение которых входящий вызов в этом транке будет звонить до того, как приложение SLATrunk() завершит работу и будет считать этот вызов неотвеченным. По умолчанию эта опция не установлена.
barge = no
Параметр barge указывает, разрешено ли другим станциям присоединяться к вызову, который выполняется в этом транке, нажатием той же кнопки линии. Баржинг по транку разрешен по умолчанию.
hold = private
Параметр hold указывает разрешения на удержание для этого транка. Если он установлен на open, любая станция может перевести этот транк в режим ожидания, а любой другой станции разрешено снять его с удержания. Если для этого параметра установлено значение private, только тем станциям, которые перевели транк в режим ожидания, разрешено снимать его с удержания. Значение по умолчанию open.
Когда мы определили станции в предыдущих примерах, мы предоставили только тип, устройство и список транков. Тем не менее, определения станций также принимают некоторые дополнительные параметры конфигурации. Они перечислены здесь:
autocontext = sla_stations
Если этот параметр указан, Asterisk автоматически создаст номера, необходимые для вызовов, поступающих с этой станции, в указанном контексте. Это отключено по умолчанию, что означает, что все номера должны быть указаны вручную.
ringtimeout = 20
Можно указать время ожидания в секундах, в течение которого станция будет звонить, прежде чем вызов будет считаться неотвеченным. Тайм-аут не установлен по умолчанию.
ringdelay = 5
Задержка вызова в секундах может быть указана для станции. Если задержка указана, то станция не начнет звонить в течение этого количества секунд после начала вызова на этом транке. Задержка не установлена по умолчанию.
hold = private
Разрешение на удержание также может быть указано для конкретной станции. Если для этого параметра установлено значение private, любые транки, удерживаемые этой станцией, могут быть получены только этой станцией. По умолчанию установлено open.
trunk = line1,ringtimeout = 20
ringtimeout может быть применен к вызовам, поступающим только из конкретного транка.
trunk = line1,ringdelay = 5
ringdelay также может быть применен к вызовам из конкретного транка.
Ограничения
В то время как Asterisk упрощает многие вещи, SLA не является одной из них. Эта функциональность была предназначена для эмуляции простых функций, но конфигурация, необходимая для ее работы, довольно сложна. Кто-то, кто является новичком в Asterisk и хочет только простую настройку системы клавиш, должен будет изучить много сложных концепций Asterisk и SIP-телефонов, чтобы заставить её работать.
Еще одна особенность, которая все еще нуждается в доработке, прежде чем она будет бесперебойно работать с SLA — это CallerID. На момент написания этой функции у Asterisk не было соответствующей инфраструктуры, чтобы иметь возможность обновлять информацию об CallerID на протяжении всего разговора. В зависимости от того, как реализована эта функциональность, эта инфраструктура необходима для того, чтобы сделать дисплей на телефонах полезным. Он существует начиная с Asterisk 1.8, но приложения SLA еще не были обновлены для его использования. Конечным результатом является то, что у вас может вообще не быть никакой информации о CallerID или вы можете включить ее и понять, что дисплей телефона не всегда будет отображаться правильно, так как изменения происходят во время разговора.
Другое ограничение, наиболее актуальное для использования общих номеров, заключается в том, что трансферы не работают. Основная причина заключается в том, что трансферы обычно предполагают приостановку вызова на короткое время. Удержание вызова обрабатывается особым образом с помощью SLA, так как удерживаемый вызов не контролируется телефоном, который инициировал удержание. Это нарушает обработку трансфера.
Таким образом, SLA не так прост в настройке и имеет ряд существенных ограничений. С учетом сказанного, если то, что существует, соответствует вашим потребностям, обязательно соглашайтесь на это.
Создание службы обратного вызова
После сбоя вызова из-за того, что адресат занят или иным образом недоступен, служба обратного вызова позволяет предоставить вызывающему абоненту возможность автоматического обратного вызова, когда адресат становится доступным. Дополнительные услуги по завершению вызова (Call Completion Supplementary Services — CCSS) позволяют вам запросить Asterisk перезвонить вам после попытки вызова без ответа или занятости. В этом разделе показано, как включить эту функцию для использования между телефонами, подключенными к одной и той же системе Asterisk.
Для этого примера мы включим эту услугу для двух SIP-телефонов. Для этого добавьте вследующее в /etc/asterisk/sip.conf:
[phone1]
…
cc_agent_policy = generic
cc_monitor_policy = generic
[phone2]
…
cc_agent_policy = generic
cc_monitor_policy = generic
Теперь добавьте следующие номера в диалплан:
[phones]
;
; Номера для набора номера телефона менять не нужно.
; Это просто просто примеры набора номера телефона с 20-секундным таймаутом.
;
exten => 7101,1,Dial(SIP/phone1,20)
same => n,Hangup()
exten => 7102,1,Dial(SIP/phone2,20)
same => n,Hangup()
;
; Наберите *30, чтобы запросить услуги завершения вызова для последней
; попытки вызова.
;
exten => *30,1,CallCompletionRequest()
same => n,Hangup()
;
; Для отмены запроса на завершение вызова наберите *31.
;
exten => *31,1,CallCompletionCancel()
same => n,Hangup()
В этом примере мы использовали политики generic для agent и monitor. Этот способ настройки является самым простым для начала работы, но он работает только для вызовов между телефонами, подключенными к одной и той же системе Asterisk. Agent является частью системы, которая действует от имени абонента, запрашивающего услуги завершения вызова. Monitor является частью системы, отвечающий за мониторинг устройства (или устройств) которые были вызваны, чтобы определить когда они становятся доступными.
Используя этот диалплан, давайте рассмотрим пример, где используется CCSS. Мы начнем с того, что 7001 вызовет 7002, но дадим тайм-аут — 20 секунд. В этом случае, вызов не состоялся из-за отсутствия ответа. Теперь абонент 7001 может запросить CCSS, набрав *30. Это называется завершением вызова без ответа (Call Completion No Response — CCNR). Вы можете проверить запрос CCNR в Asterisk CLI:
*CLI> cc report status
1 Call completion transactions
Core ID Caller Status
—————————————————————————-
20 SIP/phone1 CC accepted by callee
|—>7102@phones
|—>SIP/phone2(CCNR)
На данный момент Asterisk использует свою стандартную реализацию generic monitor для ожидания доступности SIP/phone2. В случае CCNR, он определяет доступность, ожидая когда телефон сделает следующий вызов. Когда этот вызов заканчивается, Asterisk инициирует вызов между SIP/phone1 и SIP/phone2 и запрос CCNR будет выполнен.
Другим сценарием является завершение вызова занятым абонентом (Call Completion Busy Subscriber — CCBS). Это тот случай, когда вызываемый абонент уже разговаривает по телефону. Запрос услуг завершения вызова в этом сценарии работает так же, как и раньше. Generic monitor будет определять доступность, ожидая завершения вызова на устройстве.
Asterisk также поддерживает расширение CCSS на нескольких серверах с использованием SIP или ISDN (в частности, ISDN в Европе). Однако настройка и работа специфичных для протокола методов выходит за рамки этого рецепта. Для получения дополнительной информации об использовании CCSS с Asterisk см. примеры файлов конфигурации Asterisk, а также информацию в вики Asterisk.
Вывод
В этой главе обсуждаются многие аспекты обработки состояний устройств в Asterisk. Мы начали с обсуждения основных понятий состояний устройств и состояний внутренних номеров, а затем создали их. Мы рассмотрели, как SIP-телефоны могут подписываться на состояния, инструменты для создания пользовательских состояний и два механизма, которые можно использовать для распространения состояний между несколькими серверами. Наконец, мы рассмотрели одну из функций в Asterisk, как общие внешние линии, которая в значительной степени зависит от инфраструктуры состояний устройств в Asterisk.
1Некоторые также любят называть их «мигающие лампы” или»мигающие огни» для своих телефонов. Гики и их светодиоды…
2Следует признать, что ни одна из конфигураций для SLA не является простой.
3Читайте: взлом
Остались вопросы?
Я - Виталий Шелест, менеджер компании Voxlink. Хотите уточнить детали или готовы оставить заявку? Укажите номер телефона, я перезвоню в течение 3-х секунд.
категории
- DECT
- Linux
- Вспомогательный софт при работе с Asterisk
- Интеграция с CRM и другими системами
- Интеграция с другими АТС
- Использование Elastix
- Использование FreePBX
- Книга
- Мониторинг и траблшутинг
- Настройка Asterisk
- Настройка IP-телефонов
- Настройка VoIP-оборудования
- Новости и Статьи
- Подключение операторов связи
- Разработка под Asterisk
- Установка Asterisk
VoIP оборудование
ближайшие курсы
Новые статьи
10 доводов в пользу Asterisk
Распространяется бесплатно.
Asterisk – программное обеспечение с открытым исходным кодом, распространяется по лицензии GPL. Следовательно, установив один раз Asterisk вам не придется дополнительно платить за новых абонентов, подключение новых транков, расширение функционала и прочие лицензии. Это приближает стоимость владения станцией к нулю.
Безопасен в использовании.
Любое программное обеспечение может стать объектом интереса злоумышленников, в том числе телефонная станция. Однако, сам Asterisk, а также операционная система, на которой он работает, дают множество инструментов защиты от любых атак. При грамотной настройке безопасности у злоумышленников нет никаких шансов попасть на станцию.
Надежен в эксплуатации.
Время работы серверов некоторых наших клиентов исчисляется годами. Это значит, что Asterisk работает несколько лет, ему не требуются никакие перезагрузки или принудительные отключения. А еще это говорит о том, что в районе отличная ситуация с электроэнергией, но это уже не заслуга Asterisk.
Гибкий в настройке.
Зачастую возможности Asterisk ограничивает только фантазия пользователя. Ни один конструктор шаблонов не сравнится с Asterisk по гибкости настройки. Это позволяет решать с помощью Asterisk любые бизнес задачи, даже те, в которых выбор в его пользу не кажется изначально очевидным.
Имеет огромный функционал.
Во многом именно Asterisk показал какой должна быть современная телефонная станция. За многие годы развития функциональность Asterisk расширилась, а все основные возможности по-прежнему доступны бесплатно сразу после установки.
Интегрируется с любыми системами.
То, что Asterisk не умеет сам, он позволяет реализовать за счет интеграции. Это могут быть интеграции с коммерческими телефонными станциями, CRM, ERP системами, биллингом, сервисами колл-трекинга, колл-бэка и модулями статистики и аналитики.
Позволяет телефонизировать офис за считанные часы.
В нашей практике были проекты, реализованные за один рабочий день. Это значит, что утром к нам обращался клиент, а уже через несколько часов он пользовался новой IP-АТС. Безусловно, такая скорость редкость, ведь АТС – инструмент зарабатывания денег для многих компаний и спешка во внедрении не уместна. Но в случае острой необходимости Asterisk готов к быстрому старту.
Отличная масштабируемость.
Очень утомительно постоянно возвращаться к одному и тому же вопросу. Такое часто бывает в случае некачественного исполнения работ или выбора заведомо неподходящего бизнес-решения. С Asterisk точно не будет такой проблемы! Телефонная станция, построенная на Asterisk может быть масштабируема до немыслимых размеров. Главное – правильно подобрать оборудование.
Повышает управляемость бизнеса.
Asterisk дает не просто набор полезных функций, он повышает управляемость организации, качества и комфортности управления, а также увеличивает прозрачность бизнеса для руководства. Достичь этого можно, например, за счет автоматизации отчетов, подключения бота в Telegram, санкционированного доступа к станции из любой точки мира.
Снижает расходы на связь.
Связь между внутренними абонентами IP-АТС бесплатна всегда, независимо от их географического расположения. Также к Asterisk можно подключить любых операторов телефонии, в том числе GSM сим-карты и настроить маршрутизацию вызовов по наиболее выгодному тарифу. Всё это позволяет экономить с первых минут пользования станцией.