Как стать автором
Обновить

Да пребудет с нами VoIP

Время на прочтение5 мин
Количество просмотров12K

Привет, Хабр!

Меня зовут Корнеев Илья, я являюсь разработчиком приложения под OS Android в Московском кредитном банке.

Все мы, наверняка, привыкли к тому, чтобы открыть телефонную книжку своего мобильного устройства и просто позвонить по своим делам или, например, пообщаться с любимыми или друзьями. И операторы сотовой связи идут нам на встречу, давая пакеты минут, которые включены в абонентскую плату. А интернет используется для серфинга, видосиков на youtube и т.п.

Когда же мы уезжаем за границу, все наши пакеты превращаются в тыкву. Но ведь можно найти бесплатный Wi-Fi! Так почему бы не использовать его?

Немного матчасти

  • VoIP (Voice over IP) – технология передачи голосового потока посредством протокола Интернет.

  • SIP (Session Initiation Protocol) - протокол передачи данных, описывающий способ установки и завершения пользовательского интернет-сеанса, включающего обмен мультимедийным содержимым.

  • RTP (Real-time Transport Protocol) - протокол передачи медиаданных в реальном времени.

  • SRTP (Secure Real-time Transport Protocol ) - защищенный RTP протокол. Предназначен для шифрования, установления подлинности сообщения, целостности, защиты от замены данных RTP в однонаправленных и multicast передачах медиа и приложениях.

Давайте разберемся, как это работает

Прежде чем начать звонок, двум абонентам нужно "договориться". Для этого нам понадобится протокол SIP. Протокол SIP имеет клиент-серверную архитектуру. Клиент выдает запросы с указанием того, что он хочет получить от сервера. Сервер принимает и обрабатывает запросы, выдает ответы, содержащие уведомление об успешности выполнения запроса, уведомление об ошибке или информацию, запрошенную клиентом.

Обслуживание вызова распределено между различными элементами сети SIP. Основным функциональным элементом, реализующим функции управления соединением, является абонентский терминал. Остальные элементы сети могут отвечать за маршрутизацию вызовов, а иногда служат для предоставления дополнительных сервисов.

Схема общения по протоколу SIP

Первым делом чтобы получить возможность получать и совершать вызовы необходимо зарегистрироваться в сети. Для этого достаточно выполнить запрос «REGISTER»:

После успешной регистрации набор запросов/ответов выглядит так:

Теперь разберем каждый запрос отдельно.

Первым делом устройство, совершающее вызов, отправляет запрос «INVITE» вызываемому абоненту для того, чтобы пригласить его начать сеанс связи.

Как только вызывающий абонент отправит «INVITE», сразу же запускается таймер ожидания ответных сообщений, чтобы понять, а прошел ли запрос. И ждет он простейший ответ с той стороны в виде сообщения «100 Trying», который остановит таймер.

Далее сторона Б отправляет еще один запрос «180 Ringing», который означает что абонент Б свободен и готов ответить на звонок. Но абонент может быть и занят. В таком случае отправляется другой запрос, о котором мы поговорим чуть позже.

Что ж, звонок мы отправили, пора бы и пообщаться!

Как только абонент Б берет трубку, он отправляет запрос «200 ОК».

Как и абоненту А, абоненту Б тоже необходимо узнать о том, что его ОК дошел и сеанс можно продолжать. Для этого абонент А отправляет сообщение «ACK».

И наконец свершилось! Можно и пообщаться! Да, действительно, первый этап пройден, обе стороны узнали друг о друге, договорились о всех нюансах взаимодействия и начинают второй этап - обмен мультимедиапотоком. Как правило, информация в этом случае передается по протоколу RTP (Realtime Transfer Protocol).

Третьим этапом можно выделить завершение общения. 

Абонент, инициирующий завершение сеанса, отправляет сообщение «BYE». Второй абонент, получив это сообщение, может при необходимости воспроизвести звуковой сигнал, соответствующий занятой линии, или просто завершить сеанс, но так или иначе он обязан отправить инициатору сообщение «200 ОК», чтобы сигнализировать о том, что сообщение было доставлено и подтвердить согласие на освобождение всех задействованных ресурсов.

Так мы обработали основной flow ip-телефонии. Этот flow необходимо расширять и другими типами сообщений для поддержания корректной работы, но для старта достаточно и этого.

Реализация

SIP

Прежде чем начать голосовую передачу, нужно договориться, то есть реализовать протокол SIP. 

SIP очень похож на протокол HTTP, используемый для Web приложений, или на SMTP (обмен почтовыми сообщениями). Сообщения состоят из заголовков и тела сообщения. SIP - это протокол, использующий текстовые сообщения, в которых используется кодировка UTF-8. SIP использует номер порта 5060, как для коммуникации по протоколу UDP, так и для TCP. Подробнее о протоколе можно почитать здесь.

На старте проекта мы не обладали сторонним framework, реализующим протокол SIP. Сначала мы проанализировали формат всех запросов и ответов на примере использования open source softphone - Linphone. С использованием этой утилиты мы получили представление о работе и формате протокола SIP. Например, вот так выглядит запрос «REGISTER»:

/*

REGISTER sip:1.1.1.1 SIP/2.0

Via: SIP/2.0/UDP 1.1.1.1:5555;branch=xxxxx;rport

From: ;tag=xxxxx

To: sip:yyyy@1.1.1.1

CSeq: 20 REGISTER

Call-ID: xxxxx

Max-Forwards: 70

Supported: replaces, outbound

Accept: xxxxx

Contact: ;

Expires: 3600

User-Agent: Unknown (belle-sip/1.5.0)

*/

В качестве канала передачи запросов протокола SIP мы использовали framework OkHttp. Достаточно удобный в применении. Конечно, WebSocket-соединение мы использовали с URI-схемой «wss» (шифрованное соединение) с SSL-pinning (внедрение SSL сертификата, который используется на сервере, в коде мобильного приложения для проверки подлинности сервера).

RTP

Вот теперь можно организовывать передачу медиапотока, то есть реализовать протокол RTP. При использовании протокола RTP открываются два порта для коммуникации. Один - для передачи потока медиаданных (четный номер порта), и второй - для передачи данных сигнализации (обратная связь для QoS и контроль медиапотока) - RTCP. Значения номеров портов жестко не привязаны. С форматом можно познакомиться здесь.

С реализацией протокола RTP нам повезло больше - WebRTC. Это проект с открытым исходным кодом, предназначенный для организации передачи потоковых данных между браузерами или другими поддерживающими его приложениями по технологии точка-точка. Ознакомиться с ним можно здесь: https://webrtc.org/https://webrtc.github.io/webrtc-org/native-code/android/.

NAT

Все бы хорошо, но мы столкнулись с проблемами прохождения NAT. А проблемы заключаются в том что, если один из участников, участвующий в этом сеансе, использует IP-адрес из приватной сети, тогда поток от абонента, находящегося в публичной сети в сторону NAT сервера, не сможет достичь абонента, находящегося во внутренней сети. Плотнее ознакомиться с проблемами NAT можно в этой статье.

Для их решения мы использовали протоколы:

  • TURN (Traversal Using Relay NAT) - протокол, который позволяет узлу за NAT (или брандмауэром) получать входящие данные через TCP или UDP соединения (для общения с нашим TURN-сервером);

  • ICE (Interactive Connectivity Establishment) - протокол, который обеспечивает прохождение трафика через различные устройства NAT (из коробки WebRTC).

Таким образом, донастроив нашу работу с WebRTC на использование этих протоколов, мы получили полноценную передачу голосового потока посредством сети Интернет.

На этом у меня всё. Спасибо за внимание!

Теги:
Хабы:
Всего голосов 7: ↑6 и ↓1+5
Комментарии14

Публикации

Информация

Сайт
mkb.ru
Дата регистрации
Дата основания
Численность
5 001–10 000 человек
Местоположение
Россия
Представитель
Chitanava