Сейчас я вижу личное применение этого устройства в качестве SIP дверного звонка.
Возможно с небольшими переделками, совмещение VoIP телефонии с системой домашней автоматизации. Как варианты использования – SIP дверной звонок, интерком, система голосовой связи (клиент-персонал, директор-секретарь) и т.д.
Всё решение делается на бесплатном и открытом программном обеспечении: операционная система – Raspbian Stretch (Debian 9), Система домашней автоматизации – MajorDoMo, VoIP сервер – Freeswitch, программный клиент IP-телефонии с возможностью работы в терминальном режиме Linphonec.
В этой части, под катом, в основном и пойдет речь про установку консольного SIP клиента Linphonec.
Нам понадобится:
- Raspberry Pi — одноплатный компьютер (у меня модель Raspberry Pi 3B)
- Micro SD карта памяти не менее 16 Гб, USB зарядное устройство, корпус.
- USB звуковая карта (использована одна из самых дешевых, Gembird), микрофон, динамик (наушники).
- Кнопка и пару перемычек BBJ для контактов GPIO.
1. Первый шаг — Установка образа MajorDoMo для RPI
На данный момент актуальная версия образа для Raspberry Pi — v. 3.40. По ссылке небольшое описание образов MajorDoMo и изменений:
Базовые образы MajorDoMo для Raspberry Pi
После установки и при загрузке системы, подключив динамики к 3,5 разъёму – услышим системные сообщения и IP адрес Raspberry.
По умолчанию имя пользователя: pi пароль: raspberry.
2. Устанавливаем FREESWITCH,
Установка VoIP сервера FRESWITCH для Raspberry
После этого переходим к установке необходимых компонентов. Необязательный, но возможно, в последствии полезный шаг.
Установка RPi-Monitor
Установим небольшую, но полезную утилиту RPI монитор, которая показывает ресурсы нашего Raspberry PI.
RPi-Monitor это основанное на веб, программное обеспечение для контроля за платами Raspberry Pi. Данный инструмент может быть полезен, чтобы контролировать использование дискового пространства, нагрузку на процессор, память и сетевой трафик, температуру. RPI-Monitor довольно прост в установке, и наглядно показывает информацию о системе.
Первым делом приведу ссылку на первоисточник:
RPi-Monitor .
Устанавливаем публичный ключ RPi-Monitor и добавляем его в доверенные репозитории:
sudo apt-get install dirmngr
sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 2C0D3C0F
sudo wget http://goo.gl/vewCLL -O /etc/apt/sources.list.d/rpimonitor.list
Далее обновляем систему и устанавливаем сам RPI монитор:
sudo apt-get update
sudo apt-get install rpimonitor
Открываем в браузере IP своего комп с указанием порта :8888, на котором работает монитор и видим состояние RPI.
Установка USB аудиокарты и настройка звука в ОС Raspberry Pi
К сожалению наш мини компьютер Raspberry не имеет своего своего встроенного микрофона и входа для него. Поэтому для подключения микрофона придется использовать внешнюю USB звуковую карту. Подключаем карту в порт USB Raspberry, и выполняем команду (которая показывает устройства звука в системе):
cat /proc/asound/cards
Видим ответ с двумя картами, bcm2835 – встроенная, внешняя определилась как USB Audio Device:
0 [ALSA ]: bcm2835_alsa — bcm2835 ALSA
bcm2835 ALSA
1 [Device ]: USB-Audio — USB Audio Device
GeneralPlus USB Audio Device at usb-3f980000.usb-1.4, full speed
ОС видит нашу звуковую карту, но она ещё не прописана в системе.
Создаем файл:
sudo nano /etc/modprobe.d/alsa-base.conf
Пишем (вставляем) следующую строку:
options snd-usb-audio index=1
Сохраняем (в редакторе Ctrl+X).
Создаем ещё один файл:
sudo nano /etc/asound.conf
Добавляем содержимое:
pcm.!default {
type plug
slave {
pcm "hw:1,0"
}
}
ctl.!default {
type hw
card 1
}
Редактируем следующий конфигурационный файл:
sudo nano /usr/share/alsa/alsa.conf
Меняем звуковую карту по умолчанию с 0 на 1 (USB card), Очевидно, 0 по умолчанию встроенный выход звука миникомпьютера, устанавливаем в 2-х строках следующие параметры:
defaults.ctl.card 1
defaults.pcm.card 1
Изменения вступят в силу, после перезагрузки, перегружаем набрав в консоли:
sudo reboot
Подключаем в внешнюю аудиокарту микрофон и колонки (наушники). После перезагрузки запускаем утилиту настройки звука Alsamixer.
alsamixer
Видим наши устройства, которые мы определили в системе по умолчанию:
Клавишами курсора вправо-влево, выбираем необходимое устройство, вверх-вниз, регулировка, обращаем внимание на символы под выбранным устройством:
xOOx — устройство включено, xMMx – устройство отключено. Как видно на скриншоте, у меня микрофон по умолчанию в системе был выключен.
Чтоб включить/выключить устройство требуется на клавиатуре нажать М.
Выходим из alsamixer (выход ctr+C).
Проверяем звук в системе. Динамики и микрофон подключены к соответствующим выходам USB звуковой карты.
Даем команду:
arecord -D plughw:1,0 -f cd /home/pi/test_record.wav
При этой команде через микрофон записывается звуковой файл в соответствующую директорию (в нашем случае, домашнюю пользователя pi). Остановка записи Ctrl+c.
Проверяем записанный файл:
aplay /home/pi/test_record.wav
Более качественную проверку проведём чуть позже.
Установке консольного VoIP клиента Linphonec
Программ, имеющих возможность работы в ОС без графического интерфейса не так уж и много, я остановился на пакете Linphone.
Пакет довольно большой, имеет много потенциальных возможностей, но нам пока нужна только небольшая утилита Linphonec, умеющая работать в терминале и имеющая функцию автоответа (автоматического поднятия трубки).
Ради нее и будут выполнены последующие действия.
Замечу, при установке из репозитория Raspbian устанавливается довольно старая версия 3.6.1, которая не совсем корректно не работает с звуковой системой ALSA, у меня были пропадания звука, сама программа несколько раз вылетала.
Поэтому буду использовать более актуальную версию.
Для самостоятельной сборки пакета из исходников устанавливаем дополнительные зависимости:
sudo apt-get install cmake automake autoconf libtool intltool yasm libasound2-dev libpulse-dev libv4l-dev nasm git libglew-dev
Переходим в домашнюю директорию:
cd /home/pi/
Скачиваем сам пакет Linphone, скачивание заняло минут 20.
git clone git://git.linphone.org/linphone-desktop.git –recursive
Скомпилировать и собрать пакет Linphone у меня не получилось с первого и даже не со второго раза. Поэтому приведу свой алгоритм действий.
Останавливаем практически все запущенные, но на текущий момент неиспользуемые сервисы, с помощью системы управления службами systemctl.
При сборке возникали ошибки, нашему мини ПК просто не хватает своих ресурсов. Освободим их для установки.
sudo systemctl stop freeswitch.service
sudo systemctl stop majordomo.service
sudo systemctl stop avahi-daemon.socket
sudo systemctl stop avahi-daemon.service
sudo systemctl stop mosquitto.service
sudo systemctl stop mysql
sudo systemctl stop mpd.service
sudo systemctl stop mpd.socket
sudo systemctl stop homebridge.service
sudo systemctl stop nginx.service
sudo systemctl stop bluetooth.target
sudo systemctl stop bluetooth.service
На всякий случай можем сделать, временный (до перезапуска) файл подкачки, (место на жестком диске), которое операционная система использует в случае нехватки оперативной памяти.
Проверить, включен ли в нашей установке Raspbian (Debian) файл подкачки, можно набрав:
sudo swapon --show
Вывод пуст, это означает, что в системе отсутствует файла подкачки.
Добавим 1G swap и создадим файл:
sudo fallocate -l 1G /swapfile
Только пользователь root может читать и писать в файл подкачки, поэтому устанавливаем правильные разрешения:
sudo chmod 600 /swapfile
Используем инструмент mkswap для настройки области подкачки Linux в файле и активируем его, набрав команды:
sudo mkswap /swapfile
sudo swapon /swapfile
Переходим в созданную директорию при скачивании пакета:
cd linphone-desktop
Подготавливаем к установке версию без графического интерфейса:
sudo ./prepare.py no-ui -DENABLE_OPENH264=ON -DENABLE_WEBRTC_AEC=OFF -DENABLE_UNIT_TESTS=OFF -DENABLE_MKV=OFF -DENABLE_FFMPEG=ON -DENABLE_CXX_WRAPPER=OFF -DENABLE_NON_FREE_CODECS=ON -DENABLE_VCARD=OFF -DENABLE_BV16=OFF -DENABLE_V4L=OFF
Выполняем сборку используя атрибут –j4 (т.е. выполняет сборку в 4 потока одновременно.
sudo make -j4
Можем при установке, посмотреть в RPI-Monitor состояние нашего компьютера:
Время сборки у меня составило около 30-40 минут.
Собранные файлы программ появились в директории OUTPUT/no-ui/bin. Для запуска программы перейдём в неё:
cd OUTPUT/no-ui/bin
Проверяем версию программы:
./linphonec -v
Получаем результат: version: 3.12.0
Перегружаем наш Raspberry
При перезапуске исчезает файл подкачки, восстанавливаются все запущенные сервисы прописанные в автозагрузке.
Небольшая первоначальная настройка Freeswitch.
Сервер FREESWITCHу нас устанавливается по умолчанию в директорию /usr/local/freeswitch/. В папке conf хранятся файлы конфигурации. По умолчанию устанавливается тестовая конфигурация vanilla, которая большей частью служит для ознакомления с возможностью VoIP сервера и содержит большое количество примеров, которые явно избыточны для домашнего использования. Приведем сначала к работоспособности VoIP сервера конфигурацию из коробки.
Отредактируем файл конфигурации vars.xml
sudo nano /usr/local/freeswitch/conf/vars.xml
Первым делом изменим пароль по умолчанию 1234 на другое значение, допустим 1111. Если этого не делать, то перед каждым звонком устанавливается пауза до набора номера равная 10 секундам.
По умолчанию, как писал в предыдущей статье, у нас есть 20 абонентских номеров 1001-1020. Диалплан также установлен по умолчанию.
По какой-то причине в эти разы, по сравнению с полугодовой давностью, при включении модуля mod_xml_rpc у меня постоянно падал сервер.
Диалплан FreeSWITCH широко использует регулярные выражения. За обработку вызовов отвечает дефолтный диалплан, за направление на наши локальные номера отвечает следующая секция файла Local_Extension. Закомментируем несколько строк:
sudo nano /usr/local/freeswitch/conf/dialplan/defaults.xml
Редактирование диалплана, вставим символа комментария в эту секцию:
<extension name="Local_Extension">
<condition field="destination_number" expression="^(10[01][0-9])$">
<action application="export" data="dialed_extension=$1"/>
<!-- <action application="bind_meta_app" data="1 b s execute_extension::dx XML features"/>
<action application="bind_meta_app" data="2 b s record_session::$${recordings_dir}/${caller_id_number}.${strftime(%Y-%m-%d-%H-%M-%S)}.wav"/>
<action application="bind_meta_app" data="3 b s execute_extension::cf XML features"/>
<action application="bind_meta_app" data="4 b s execute_extension::att_xfer XML features"/> -->
Небольшое отступление, на мой взгляд, несмотря на работоспособность FS, после наших нескольких изменений, лучше переделать конфигурационные файлы FS под себя, в т.ч. абоненсткие, диалплан и т.д., но в одной статье всего не уместишь, поэтому переходим к нашему терминальному клиенту.
Настройка и запуск терминального клиента Linphonec
Запустим Linphonec в режиме автоответа от текущего пользователя pi:
/home/pi/linphone-desktop/OUTPUT/no-ui/bin/linphonec -a
При первом запуске, Linphonec пытается создать файл базы данных и файл настроек. Однако запуск происходит с ошибками.
2019-08-02 18:02:58:715 mediastreamer-error-Connection to the pulseaudio server failed
2019-08-02 18:02:58:946 belle-sip-error-udp bind() failed for ::0 port 5060: Address already in use
2019-08-02 18:02:58:947 belle-sip-error-TCP bind() failed for ::0 port 5060: Address already in use
2019-08-02 18:02:59:126 liblinphone-fatal-Unable to open linphone database.
Aborted
Первоначально разберемся с последней ошибкой, открытия файла БД.
Файл БД создается в домашней директории по следующему пути: /home/pi/.local/share/linphone
Файл (или директория) в Linux считается скрытым (hidden), если его название начинается с символа точка «.». Например, «.myfile». Обычно такие файлы используются приложениями для хранения настроек, конфигураций и другой информации, которую нужно скрыть от пользователя.
Проверим права на директорию и поменяем их.
sudo ls -al /home/pi/
sudo chmod -R 777 /home/pi/.local/share/
Эта команда даст все права на папку для каждого типа пользователей (владелец, группа и другие).
Создаем директорию для БД нашего софтфона:
mkdir /home/pi/.local/share/linphone
Запускаем программу, программа запустилась, но выдает ошибку:
2019-08-07 11:29:32:780 mediastreamer-error-Connection to the pulseaudio server failed
2019-08-07 11:29:32:866 belle-sip-error-udp bind() failed for ::0 port 5060: Address already in use
2019-08-07 11:29:32:866 belle-sip-error-TCP bind() failed for ::0 port 5060: Address already in use
С первой проблемой создания БД мы разобрались, при первоначальном запуске программа сформировала файл базы данных.
Ошибка, связанная с системой звука Pulseaudio — не мешает функционирования программы, я планирую использовать ALSA, в случае необходимости звуковой сервер всегда можно до установить.
Вторая – порты 5060 заняты. Эти порты обычно используется SIP приложениями. Можем выйти из программы и дать команду:
sudo netstat -tulpn | grep LISTEN
Увидим, что порт 5060 использует наш сервер VoIP FREESWITCH. Что ж, будем использовать свободные порты.
Заходим обратно в программу linphonec. И проводим небольшую настройку.
Первым делом меняем порт для Линфона, затем указываем регистрацию к серверу VoIP, проверяем статус регистрации и смотрим список звуковых карт, используемую карту и настраиваем на внешнюю USB (с индексом в программе Linphone – 2):
ports sip 5062
register sip:1001@192.168.15.13 192.168.15.13 1111
linphonec> help register
status register
soundcard list
soundcard show
soundcard use 2
soundcard show
В команде регистрации используем следующий формат: идентификатор Sip пользователя – по умолчанию у нас 20 абонентов с номерами 1001-1019. Эти номера и есть логины абонентов логин абонента@[Доменное имя] – доменное имя – IP адрес нашего Raspberry. Sip proxy – совпадает с IP адресом RPI, и в конце – пароль пользователя, который мы недавно установили 1111.
Выходим из программы (Ctrl+x), не всегда на лету применяются настройки. После выхода в домашней директории /home/pi появился файл настройки консольного клиента: .linphonerc.
Можем уже вносить изменения, редактируя конфигурационный файл SIP клиента.
По новой запускаем консольного SIP клиента.
Параллельно с текущей SSH сессией, открываем новую, входим в систему, используя свой логин и пароль.
Запускаем alsamixer. В одной сессии у нас Linphonec, в второй утилита настройки звука.
Делаем установку вызова с SIP клиента на смартфоне или пк (как описано в статье про установку FREESWITCH), изменив дефолнтный пароль на свой и набрав номер, в нашем случае 1001. Можем зайти в портал freswitch по адресу IP_Raspberry:8080, просмотреть регистрацию абонентов, состояние звонка и т.д.
С помощью alsamixer настраиваем звук. Изменения звука применяются на лету, без выхода из программ.
К сожалению, из-за использования дешевой аудио карты, приемлемого для себя звука я не добился, в динамиках было слышно эхо. Его можно несколько минимизировать, но полностью убрать – мне не удалось.
Поэтому раз не удалось убрать одним способом, устраним другим.
Закрываем Linphonec, редактируем файл конфигурации:
sudo nano /home/pi/.linphonerc
В секции звука приводим три последние строчки к такому виду:
[sound]
remote_ring=/home/pi/linphone-desktop/OUTPUT/no-ui/share/sounds/linphone/ringback.wav
playback_gain_db=0.000000
mic_gain_db=0.000000
ringer_dev_id=ALSA: bcm2835 ALSA
playback_dev_id=ALSA: bcm2835 ALSA
capture_dev_id=ALSA: USB Audio Device
Таким способом мы заставили устройство звонка и устройство вывода звука работать на встроенном 3,5 jack малинки, а устройство записи — микрофон работать через внешнюю звуковую карту — эхо исчезло.
Переключаем динамики в родной разъём малинки.
Учитываем следующий момент: при загрузке и в некоторых случаях, система умного дома воспроизводит через этот аудиовыход свои системные сообщения.
Отключим их. Переходим по IP_Rasberry на главную страницу, открыв систему домашней автоматизации MajorDoMo.
Входим в панель управления – объект- Computer (раскрываем устройства) – ThisComputer на вкладку Свойства и ставим значения:
ThisComputer.minMsgLevel 100 ThisComputer.volumeLevel 0
Добавляем запись в cron (программа-демон, предназначенная для выполнения заданий в определенное время, или через определенные промежутки времени. Для редактирования заданий используется утилита crontab):
crontab –e
Замечу делаем это из под пользователя pi.
Вставляем в самом конце строку:
@reboot /home/pi/linphone-desktop/OUTPUT/no-ui/bin/linphonec –a
Эта строка запускает при перезагрузке, включении компьютера, программу Linphonec в режиме автоответа.
Обратно вернемся к MajorDoMo:
Перейдем на главную страницу, в раздел сервис:
В меню этого раздела созданы для перезагрузки (выключении) компьютера кнопки.
Дело в том, что для экономии ресурсов SD карты памяти, запись изменений в систему «умного дома» производится через определенное время (15 минут). Поэтому, если нужно перегрузить малину, то лучше это делать правильно. Выполняем перезагрузку системы.
После перезагрузки, заходим на главную страницу MajorDoMo, переходим в панель управления, и как в прошлой статье делаем вызов из консоли используя следующий формат:
GetURL("http://freeswitch:works@192.168.1.103:8080/webapi/originate?user/1001%201003%20XML%20default")
После команды Linphonec автоматически снимает трубку. В динамике RPI идет проигрывание звукового файла, на второй софтфон (ПК/смартфон) поступает вызов. Подняв трубку (нажав в программе кнопку ответа) устанавливается соединение.
На этом, заканчиваю эту часть. Постараюсь, немного позже описать о самой кнопке с использованием GPIO и установку вызовов за пределами своей локальной сети.
Комментарии (8)
zeronice
20.08.2019 11:09вообще если именно под расширение, то пока не стоит задачи маршрутизации звонков и их большого количество — проще взять библиотеку PJSIP и вокруг нее надстроить необходимые обертки. Звонить через внешних провайдеров и соединить пару каналов можно и ей.
Несомненно, FS удобен, но только пока лично Вы поддерживаете это решение. Порог вхождения в FS достаточно высок, а способов выстрелить себе в ногу очень много. Да и память на железке не резиноваяudvnl Автор
20.08.2019 12:18Вы правы.
Но думаю настройка FS по инструкции, для пользователя несомненно легче использования библиотеки PJSIP. По поводу памяти, для вызова одного двух абонентов её много FS не потребляет. Кроме того, если действительно использовать систему домашней автоматизации, то впоследствии можно и разнести серверную часть и клиентскую.
Ryppka
20.08.2019 12:31Материал интересный, но вот это я не понял, что такое:
К сожалению наш мини компьютер Raspberry не имеет своего микрофонного выхода.
. Возможно, я не понимаю, но микрофон — устройство ввода, зачем ему выход?udvnl Автор
20.08.2019 12:37Согласен, конечно же вход, здесь моя опечатка, исправлю. Хотя напишу:
своего встроенного микрофона и входа для него.
dzyk
21.08.2019 07:25Дружище. А не дешевле esp8266 и sim800l?
udvnl Автор
21.08.2019 09:41Да посмотрел, точно дешевле. Если честно такой вариант даже не рассматривал, в связи с отсутствием опыта работы с Arduino. Спасибо за подсказку.
Но есть вопрос функциональнее ли будет это устройство. Возможности Sip протокола и набора ATI команд всё таки разные. А если так сказать у тебя имеется своя SIP АТС, + система автоматизации, то становятся довольно большими. Сейчас задумка на будущее попробовать использовать видеозвонки, подключив USB камеру.
zeronice
FreeSwitch то зачем, если задача дернуть url и набрать конкретный номер? есть множество SIP-клинтов умеющих принимать прямые звонки. Тот же Twinkle вполне умеет даже конфу на трех собрать. Хотя если разговор вести о вызове, например, сотового, тут уже да, софтсвитч как то органичнее смотрится, но все равно походит на стрельбу из пушки по воробьям
udvnl Автор
По поводу SIP клиентов, работающих в терминальном режиме — я б не сказал, что их множество.
По поводу FS, первоначально задача ставилась так — по внешнему воздействию набрать номер, в случае поступления вызова — установить соединение. Я не знаю, может ли Twinkle делать два действия одновременно?
Кроме того, если организовать выход на внешние сети (что через SIP провайдера, что через VoIP шлюз), то навряд ли SIP клиент сможет сделать это.
Ну и возможно запись звонков.переговоров, проигрывание сообщений в качестве оповещения и т.д.
Есть запас для расширения ))