DIY кнопка вызова. Raspberry Pi, MajorDoMo, Freeswitch и Linphonec

Какое-то время назад у меня была потребность в осуществлении связи с человеком после болезни, который не мог физически пользоваться телефоном. Нужно было простое вызывное устройство, по нажатию кнопки происходил голосовой вызов. Потребность исчезла, однако, побывав сам в больничке, посмотрев на пациентов, подумалось, что такое решение может кому и пригодиться.
Сейчас я вижу личное применение этого устройства в качестве 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
    Редактирование диалплана, вставим символа комментария в эту секцию:

    Редактирование диалплана номеров 1001-1019<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 пытается создать файл базы данных и файл настроек. Однако запуск происходит с ошибками.

    ошибки при запуске Linphonec2019-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
    В секции звука приводим три последние строчки к такому виду:

    Секция звука 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 и установку вызовов за пределами своей локальной сети.

    Оставить комментарий