Задача: Нужно оформить как законченная заметка, как работать с Call File(ами) подаваемыми домашней АТС с целью автоматического обзвона. Это может быть реклама каких-либо услуг, отчет о проделанном, выполнение заданной команды. Мне это нужно для настройки еще одного способа уведомлений о проблемах в моей инфраструктуре за которую отвечает система мониторинга Zabbix Server 4.4 on Ubuntu 18.04 Server amd64

Что есть в наличии:

  • srv-asterisk (172.33.33.2)
  • Phone 1: Huawei Honor 5C (CSipSimple)
  • Phone 2: ATCOM AT610

Шаг №1: В моей локальной сети поднята АТС на базе Asterisk, в основе этого шага лежит заметка: «Как установить Asterisk 16 Current Version on Ubuntu 18.04»

Шаг №2: Подключен внешний номер на основе транка от сервиса Zadarma, в основе этого шага лежит заметка: «Asterisk с использованием SIP транка от Zadarma»

Мои базовые настройки Asterisk дабы данная заметка смогла выполнить возложенную на нее задачу:

ekzorchik@srv-asterisk:~$ sudo cp /etc/asterisk/sip.conf /etc/asterisk/sip.conf.backup

ekzorchik@srv-asterisk:~$ sudo rm /etc/asterisk/sip.conf

ekzorchik@srv-asterisk:~$ sudo nano /etc/asterisk/sip.conf

[general]

externaddr=172.33.33.2:5060

language=ru ;Локализация звуков

allowguest=no ;Разрешить/Запретить гостевые подключения

srvlookup=yes ;Принимать SIP-вызовы на основании доменных имен

limitopnpeers=yes ;Разрешить/Запретить лимит на кол-во одновременных разговоров

allowoverlap=no ;Разрешить/Запретить набор по одной цифре

useragent=Asterisk ekzorchik ;Значение поля useragent в SIP заголовке

[authentication]

[default-sip](!)

host=dynamic

type=friend

nat=no ;Политика работы через nat

deny=0.0.0.0/0.0.0.0 ;Сети из которых запрещено подключение

permit=0.0.0.0/0.0.0.0 ;Сети из которых разрешено подключение

qualify=yes ;Периодическая проверка доступности клиента

canreinvity=no ;Разрешить/Запретить потоки peer-to-peer в обход сервера

insecure=port,invite ;port (не требовать совпадение порта), invite (не требовать аутентификации)

call-limit=2 ;Лимит входящих вызовов

dtmfmode=auto ;Какую спецификацию использовать при передачи DTMF сигналов

context=phones ;Контекст обработки вызовов

disallow=all ;Запретить использование все кодеков, ниже разрешаем нужные

allow=alaw

allow=ulaw

[2002](default-sip)

callerid="Number 2002" <2002>

username=2002

secret=pbx2002

[2003](default-sip)

callerid="Number 2003" <2003>

username=2003

secret=pbx2003

После не забываем сохранить внесенные изменения.

ekzorchik@srv-asterisk:~$ sudo asterisk -rx "sip reload"

ekzorchik@srv-asterisk:~$ sudo cp /etc/asterisk/extensions.conf /etc/asterisk/extensions.conf.backup

ekzorchik@srv-asterisk:~$ sudo rm /etc/asterisk/extensions.conf

ekzorchik@srv-asterisk:~$ sudo nano /etc/asterisk/extensions.conf

[general]

[globals]

[default]

[handup-sip]

exten = > _X!,1,HangUp()

include => handup-sip

[local]

exten = _2XXX,1,Dial(SIP/${EXTEN})

[phones]

include = local

После не забываем сохранить внесенные изменения.

ekzorchik@srv-asterisk:~$ sudo asterisk -rx "dialplan reload"

Dialplan reloaded.

ekzorchik@srv-asterisk:~$ sudo systemctl restart asterisk && sudo systemctl status asterisk | head -n5

● asterisk.service - LSB: Asterisk PBX

Loaded: loaded (/etc/init.d/asterisk; generated)

Active: active (running) since Wed 2019-11-27 16:47:40 MSK; 12ms ago

Docs: man:systemd-sysv-generator(8)

Process: 787 ExecStop=/etc/init.d/asterisk stop (code=exited, status=0/SUCCESS)

ekzorchik@srv-asterisk:~$

После на смартфоне (у меня Huawei Honor 5C) устанавливаю программу CsipSimple, включаю Wi-Fi дабы оказаться в локальной сети что и мой Asterisk.

На заметку: Аккаунт в приложении CSipSimple успешно зарегистрируется если в настройках программы отмечены галочки: CsipSimple — Настройки — Сеть -

  • (Входящие вызовы) Использовать WiFi
  • (Исходящие вызовы) Использовать WiFi

, далее регистрирую аккаунт на внутренний номер 2002

Аккаунты - Добавить аккаунт - (Выбрать мастера) Advanced

  • Название аккаунта: 2002
  • Сервер: 172.33.33.2:5060
  • Имя пользователя: 2002
  • Пароль: pbx2002

и нажимаю «Сохранить»

См. логи — зарегистрировался ли мой аккаунт: — Ответ да!

-- Registered SIP '2002' at 172.33.33.11:55289

[Nov 27 17:26:06] NOTICE[1282]: chan_sip.c:24889 handle_response_peerpoke: Peer '2002' is now Reachable. (12ms / 2000ms)

[Nov 27 17:26:06] NOTICE[1282]: chan_sip.c:28710 handle_request_subscribe: Received SIP subscribe for peer without mailbox: 2002

srv-bionic*CLI>

А второй телефонный номер заведен на аппарат ATCOM AT610

srv-bionic*CLI> sip show peers

Name/username Host Dyn Forcerport Comedia ACL Port Status Description

2002/2002 172.33.33.11 D No No A 55289 OK (209 ms)

2003/2003 172.33.33.12 D No No A 5060 OK (5 ms)

2 sip peers [Monitored: 2 online, 0 offline Unmonitored: 0 online, 0 offline]

srv-bionic*CLI>

srv-bionic*CLI> sip show users

Username Secret Accountcode Def.Context ACL Forcerport

2003 pbx2003 phones Yes No

2002 pbx2002 phones Yes No

srv-bionic*CLI>

Шаг №3: Что из себя представляет Callфайл? Это инструмент позволяющий связывать Asterisk и любые внешние приложения. Связь обеспечивается посредством обмена данными через текстовые файлы, называемые Call-Файлами.

Call-файлы имеют определенную структуру, которую понимает Asterisk. Получая такой файл, Asterisk ищет в нем необходимые для себя инструкции и переменные, после чего обрабатывает и выполняет его.

Для работы Call-файлов используется директория /var/spool/asterisk/outgoing/

Как только в этой директории появляется Call-файл (права на чтение и запуск должны быть такими же от имени кого работает сам сервис Asterisk), он тут же поступает на обработку Asterisk-ом.

На заметку: Если в файле конфигурации modules.conf установлено: autoload=no, убедитесь, что у Вас загружен модуль pbx_spool.so, иначе работа с .call файлами производиться не будет.

ekzorchik@srv-asterisk:~$ sudo asterisk -rx "module show like pbx_spool.so"

[sudo] password for ekzorchik:

Module Description Use Count Status Support Level

pbx_spool.so Outgoing Spool Support 0 Running core

1 modules loaded

ekzorchik@srv-asterisk:~$ sudo nano /etc/asterisk/modules.conf

[modules]

autoload=yes

На заметку: Сервер Asterisk смотрит на дату создания call файла и если изменить дату создания на дату в будущем, то Asterisk не будет отрабатывать call файл, пока не наступит эта самая дата.

На заметку: Как только call-файл будет обработан он удалится из директории /var/spool/asterisk/outgoing/.

Синтаксис создания Call-файла

Channel: <channel> Какой канал использовать для звонка
CallerID: «name» <number> Установить Caller ID Идентификация исходящего вызова
MaxRetries: <number> По умолчанию 0. Если установлено ‘0’, будет совершена одна попытка, если ‘1’ то две
RetryTime: <number> Время в секундах между попытками дозвона, по умолчанию 300 (5 минут).
WaitTime: <number> Сколько секунд ожидаем поднятия трубки, по умолчанию 45.
Context: <context-name> Какой контекст используем из extensions.conf
Extension: <ext> Какой экстеншн используем в выбранном контексте (так же в extensions.conf).
Priority: <priority> С какого приоритета начинаем.
Application: запустить приложение Playback
Data: что запустит приложение Application
AlwaysDelete: Yes/No Удалять файлы по завершении.
Archive: Yes/No Перемещать выполненные файлы в директорию outgoing_done с указанием статуса с которым завершилось задание «Status: value», где возможны значения

Completed — Успешно.

Expired — Просрочено.

Failed — Неудачно.

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

Логика работы Call-файла:

  • Инициируется 'Channel'
  • Вызывается 'Extension' or 'Application' и соединяется с 'Channel'
  • Если 'Channel' не отвечает в течении 'WaitTime', а параметр 'MaxRetries' > 0, совершаются попытки 'MaxRetries' с интервалом 'RetryTime'.

На заметку: Channel: → какой канал использовать, вообще каналы можно посмотреть командой (ekzorchik@srv-asterisk:~$ sudo asterisk -rx "core show channeltypes"), это самое главное указание на какой номер звонить (вызывается)

Задача: Попробовать создать call файл которые должен от номер 2002 позвонить на 2003 и проиграть тестовый аудио файл:

ekzorchik@srv-asterisk:~$ nano zvonok.call

#куда звонить

Channel: SIP/2002

#Кто звонит

Callerid: 2003

Application: Playback

Data: hello

ekzorchik@srv-asterisk:~$ sudo cp zvonok.call /var/spool/asterisk/outgoing/

ekzorchik@srv-asterisk:~$ sudo chown -R asterisk:asterisk /var/spool/asterisk/outgoing/

и в указанное на файле время файл будет обработан Asterisk(ом). По итоге на но мер 2002 через SIP произойдет вызов с номера 2003, затем запуститься приложение Playback внутри которого проиграется текст hello, а так как у меня в sip.conf директива language=ru, то проиграется текст «Здравствуйте«. Работает.

ekzorchik@srv-asterisk:~$ sudo find / -name hello.wav

/var/lib/asterisk/sounds/ru/hello.wav

/var/lib/asterisk/sounds/en/hello.wav

ekzorchik@srv-asterisk:~$

ekzorchik@srv-asterisk:~$ ls -l /var/spool/asterisk/outgoing/

total 0 — воспроизведение файла zvonok.call прошло успешно и он удалился из директории.

Шаг №4: Если нужно чтобы в определенное время совершался звонок на основании call файла, то можно создать задачу в планировщике вида: (Каждое первое число в десять часов ноль минут файл будет копироваться и воспроизводиться)

Синтаксис crontab:

* * * * * выполняемая команда

— — — — —

| | | | |

| | | | —— день недели (0—7) (воскресенье = 0 или 7)

| | | ——- месяц (1—12)

| | ——— день (1—31)

| ———— час (0—23)

————- минута (0—59)

ekzorchik@srv-asterisk:~$ sudo crontab -e

# m h dom mon dow user command

0 10 1 * * /bin/cp /home/ekzorchik/zvonok.call /var/spool/asterisk/outgoing

После не забываем сохранить внесенные изменения.

Шаг №5: Чтобы создать callфайл через bash:

#!/bin/bash

# Call-файл Asterisk

callname=/tmp/alert.call

# Канал для звонка на внешние номера

echo "Channel: SIP/ZADARMA@000500-Out" > $callname

# Канал для звонка на внутренние номера

#echo "Channel: Local/555@from-internal" > $callname

#

echo "Callerid: Zabbix <500>" >> $callname

# Сколько раз звонить в случае не ответа

echo "MaxRetries: 2" >> $callname

# Через сколько времени перезваниваем (сек)

echo "RetryTime: 45" >> $callname

# Сколько ждем ответа (сек)

echo "WaitTime: 60" >> $callname

# Параметры проигрывания сообщения

echo "Application: Playback" >> $callname

echo "Data: test" >> $callname

# Совершение вызова и чистка хвостов

cp $callname /var/spool/asterisk/outgoing/alert.call

rm -f $callname

Шаг №6: Cоздать звуковой файл с определенным содержимым

ekzorchik@srv-asterisk:~$ sudo apt-get -y install sox festival

ekzorchik@srv-asterisk:~$ echo "One Two" | text2wave -o output1.wav

Проверяю информацию по полученному wav файлы и по файлу который использовался в «Шаг №3»

ekzorchik@srv-asterisk:~$ file output1.wav

output1.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, mono 16000 Hz

ekzorchik@srv-asterisk:~$ file /var/lib/asterisk/sounds/en/hello.wav

/var/lib/asterisk/sounds/ru/hello.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, mono 8000 Hz

Так мой сформированный аудио файл нужно привести к виду с которыми работает Asterisk:

ekzorchik@srv-asterisk:~$ sox -v 0.5 output1.wav -t wav -b 16 -r 8000 -c 1 output2.wav

ekzorchik@srv-asterisk:~$ file output2.wav

output2.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, mono 8000 Hz

ekzorchik@srv-asterisk:~$ sudo cp output2.wav /var/lib/asterisk/sounds/en/output2.wav

ekzorchik@srv-asterisk:~$ sudo chown asterisk:asterisk /var/lib/asterisk/sounds/en/output2.wav

Переделываю call-файл zvonok.call:

ekzorchik@srv-asterisk:~$ nano zvonok.call

#куда звонить

Channel: SIP/2002

#Кто звонит

Callerid: 2003

Application: Playback

Data: output2

ekzorchik@srv-asterisk:~$ sudo cp zvonok.call /var/spool/asterisk/outgoing/

и у меня звонит номер 2002 где при поднятии трубки проигрывается по английски: One Two — работает.

Шаг №7: Можно создать callфайл и указать что при вызове использовать определенный контекст из extensions.conf:

ekzorchik@srv-host:~$ nano zvonok.call

Channel: SIP/2002

Callerid: 2003

MaxRetries: 5

RetryTime: 5

WaitTime: 30

Context: from-obzvon

Extension: 102

Archive: Yes

После не забываем сохранить внесенные изменения. Затем описываем поведение контекста from-obzvon в файле extensions.conf:

[from-obzvon]

exten => obzvon,1,Answer()

exten => obzvon,n,Playback(hello-world)

exten => obzvon,n,Wait(3)

exten => obzvon,n,Playback(vm-goodbye)

exten => obzvon,n,Hangup()

Шаг №8: Есть мнение что копировать в каталог на исполнение Вашего callфайл нужно посредством команды mv.

  • Команда cp копирует как-то по-байтно байт за байтом создавая файл в директории назначения
  • Команда mv сначала переносит всю информацию в директорию, а потом публикует файл там.

Это мнение я взял на заметку и применяю.

Итого в этой большой заметке я для себя разъяснил и как я вижу весь процесс подготовки Call-файла с целью автоматической инициализации звонка через Asterisk. Уже обладая этим знаниями я смогу доработать свой мониторинг Zabbix Server 4.4 на уведомление о проблемах критичных сервисов звонком, а может и еще на что сгодится. Заметка не закончена, если у меня что-то заслуживающее внимание появится я ее дополню или сделаю новую но с отсылкой на эту. На этом я прощаюсь, с уважением автор блога Олло Александр aka ekzorchik.