Встречайте sip2go!

Если вы когда нибудь пользовались SIP клиентом на смартфоне, вы наверняка знаете все «особенности» этого дела… И первое и, пожалуй, главное, что реально бесит — это постоянная работа в фоновом режиме, без которой не будут работать входящие вызовы. В данной статье я расскажу о «волшебном» софтфоне, который не такой как все… Погнали!

Кому мало интересна моя лирика, можете пропустить кусок и перейти к сути. ;)

С опустошением батареи из-за фонового режима понятно. И некоторые софтфоны предлагают решение: подключить ваш SIP аккаунт через их сервер. Нуу, такое… Во-первых, их серверы, как правило находятся где-то в Европе и гонять через них голос как-то уж совсем не удобно, а ещё и не безопасно и вовсе не всегда возможно. В частности, за пределы Узбекистана SIP трафик просто не выпускают (и не впускают тоже), а потому, манёвр через забугорный сервер становится просто нежизнеспособным.

Есть и другой вариант: взять исходники открытого SIP клиента (к примеру linphone) и вшить туда свой аккаунт firebase.
И тут возникает другой вопрос: А как FCM отправлять то? Я пробовал реализовать это средствами asterisk, но наткнулся на максимально идиотскую проблему. Приходит звонок, запускается скрипт отправки пуша, но печаль в том, что теперь вызов надо каким то образом придержать до момента, пока сип клиент не очухается и подключится к серверу и только потом кидать на него INVITE. На этом моменте я основательно застрял. Далее, я пытался повесить какую то древнюю сип проксю, которая якобы поддерживает отправку пуш, но исходники оной были отчаянно старыми с какими-то стёртыми с лица земли зависимостями и она у меня тупо не собиралась. Я плюнул и решил окончательно забить на это дело, пока однажды…

Разработка

Однажды я продлил свою подписку на Cursor и начал перебирать, чего ж я такого в своей жизни очень хотел бы написать, но не мог, в виду отсутствия модуля программиста в черепной коробке? :) Я вспомнил про те самые танцы с бубном, про то, как я негодовал, что сип не умеет работать как любой мессенджер со звонками. И тут я подумал, а не собрать ли собственный софтфон, который будет работать по близкому к мессенджерам протоколу, избавляясь от всех минусов протокола SIP? Собрав в голове примерный план проекта я потыкал промптом в cursor и вот что получилось.
Адрес сайта проекта s2g.uz.

Шлюз sip2go

Это серверная часть, которая ставится между sip сервером (в моём случае FreePBX) и клиентом (софтфоном). Он подключается к сипу, как обычный эндпоинт или транк и конвертирует SIP в TLS транспорт через вебсокет.

Шлюз берёт на себя контроль над вызовами и отправляет SIP серверу 180 Ringing, пытаясь в это время разбудить своего клиента. Далее, всё как с обычным сипом, только по WSS. Если такого абонента у шлюза нет, вызов просто отклоняется.

Настройка шлюза производится через web интерфейс, пароль от которого задаётся в .env. Там можно добавлять клиентов, генерируя для них специальную ссылку автонастройки или регистрационный QR код. Этои процесс похож на активацию eSIM.

Ещё одной приятной особенностью данного решения является возможность работы с приватным SIP сервером, не выставляя его в мир. Публичный адрес потребуется только самому шлюзу, а ваш сервер будет прикрыт от внешних угроз, как если бы перед ним стоят SBC.

Софтфон sip2go

Клиентское приложение на смартфоне (пока что только Android), которое общается с серверной частью по собственному протоколу. Работает примерно так-же, как большинство софтфонов, но из коробки поддерживает push, умеет восстанавливать связь при переключении сетей или временных сетевых сбоях. Кроме того, приложение умеет записывать разговоры прямо на смартфон. Прослушивать записи можно в истории вызовов.

Быстрая настройка через ссылку или сканирование QR кода сильно облегчает задачу по добавлению сотрудников в телефонную сеть, в сценариях использования для корпоративных целей. К примеру, объяснить бухгалтеру, как настроить SIP клиент — порой, тяжёлая задача. ;)

Нюансик…

Приложение можно скачать с Google Play, но в него уже вшит мой firebase и потому настроить для него прямую отправку Push будет невозможно. Для этого я предусмотрел возможность работы FCM через мой фирменный push relay сервис, но разумеется, не бесплатно. :) В противном случае, придётся самостоятельно собирать приложение и вшивать в него собственные ключи от Firebase. Ленивым погу предложить подписку. ;)