Реализация SIP-телефонии для мобильных устройств с операционной системой Android

Автор: Пользователь скрыл имя, 25 Февраля 2013 в 05:48, дипломная работа

Описание работы

После появления первого устройства под управлением Android, стало возможным предоставить пользователю возможность использовать Интернет-телефонию так же, как и GSM телефонию. Широкополосный доступ в Интернет, многозадачность операционной системы дали возможность пользователю забыть о проблемах, связанных с Интернет связью. До Android самые удобные приложения Интернет-телефонии предлагала ОС iPhone, но с ее ограниченной многозадачностью невозможно использовать другие приложения вместе с Интернет-телефонией, что означает, например, невозможность читать документы и одновременно принимать звонки.

Содержание

1. Введение 5
1.1. Постановка задачи 5
1.2. Этапы работы 8
1.3. Введение в предметную область 10
1.3.1. Общие сведения о SIP телефонии 10
1.3.2. Принципы SIP протокола 11
1.3.3. Архитектура сети 12
1.3.4. Сообщения протокола SIP 13
1.3.5. Сравнение SIP с H.323 15
1.3.6. Сравнение SIP с Skype 17
2. Описание предлагаемого решения 19
2.1. Выбор платформы решения 19
2.2. Описание использования приложения 20
3. Реализация решения 24
3.1. Реализация низкоуровнего модуля, работающего со звуком напрямую 24
3.1.1. AudioRecordWrapper 26
3.1.2. AudioTrackWrapper 27
3.1.3. QueuedBuffer 28
3.2. Принцип работы “Handover” 29
3.3. Архитектура проекта “MC Client” 31



3.4. Ключевые классы элементов архитектуры. 33
3.4.1. Activity. 33
3.4.2. SipServiceWrapper 35
3.4.3. Service 36
3.4.4. SIPEngine 39
4. Реализация и применение решения 43
5. Сравнительный анализ 45
6. Заключение 47
7. Список литературы 48

Работа содержит 1 файл

Malyshev-Vitalij-544.docx

— 675.71 Кб (Скачать)

putNoOverrun(char data) – очистить буфер и заполнить его данными из data.

 

 

 

 

 

 

 

 

 

 

 

    1.  Принцип работы “Handover”

Еще одной отличительной  особенностью проекта SIP телефонии  “MC Client” является так называемый “Handover”. Во всех конкурентных решениях такая особенность отсутствует. Суть заключается в следующем: когда доступен широкий Интернет канал, - для связи с абонентом использовать SIP телефонию, когда канала достаточной ширины нет в наличии, - использовать GSM связь. Есть 2 типа “Handover”:

  1. Автоматический
    1. Плохое качество SIP звука

Во время SIP звонка сервер периодически пересылает клиенту SIP сообщения, содержащие 2 величины, определяющие качество звука – “Jitter” (нежелательные  фазовые и/или частотные случайные  отклонения передаваемого сигнала) и “Packet Loss” (процент пакетов, которые  не дошли до сервера). Полученные величины сравниваются с величинами, указанными в настройках (изображено на рисунке 12). При превышении их серверу посылается сообщение о совершении Handover, завершается SIP звонок и автоматически принимается GSM звонок от сервера. В итоге для пользователя будет совсем небольшая задержка, и качество связи все время будет на достойном уровне.   

Рисунок 12: Настройки пороговых величин Jitter и Packet                                      Loss. Значения в процентах.

    1. Слабый сигнал Wi-Fi

Во время разговора  с абонентом все время отслеживается  сила сигнала Wi-Fi. Если разговор идет по SIP, и сигнал Wi-Fi стал слабым, то серверу  будет послано сообщение о  “Handover” с SIP на GSM – заканчивается  текущий SIP звонок и автоматически  принимается входящий GSM звонок от сервера. Если разговор идет по GSM, и сигнал стал сильным, то серверу будет послано  сообщение о “Handover” с GSM на SIP – заканчивается текущий GSM звонок и автоматически принимается  входящий SIP звонок от сервера.

  1. Ручной

Во время разговора  пользователь всегда может самостоятельно выбрать опцию “Handover” и переключить  тип сигнала.

 

 

    1. Архитектура проекта “MC Client”

Архитектура проекта изображена на рисунке 13.

Рисунок 13: Ключевые сущности архитектуры

Activity – это визуальный пользовательский интерфейс. Например, это список элементов меню, которые пользователь имеет возможность выбирать. Всегда есть activity переднего плана и activities заднего плана. Когда создается новая activity, она выходит на передний план, смещая на задний план ту, которая раньше была передним планом. При уничтожении activity переднего плана, на передний план выходит первая в очереди заднего плана. Если системе будет не хватать ресурсов, то самые неприоритетные из activity заднего плана (система сама устанавливает приоритеты) будут уничтожены.  Каждая activity живет в собственном процессе.

Service – не имеет визуального пользовательского интерфейса и работает на заднем плане в течение неопределенного времени. Например, сервис может играть музыку, в то время как пользователь может использовать браузер.  Пользователь не видит списка песен и состояния проигрывания, однако музыку он слышит. Каждый сервис живет в собственном процессе.

Так как activity и сервис живут  в разных процессах, то нельзя напрямую обращаться к сервису из activity (иначе activity будет ждать окончания действий сервиса и не будет реагировать на действия пользователя). Для разрешения указанной ситуации существует специальное понятие ServiceWrapper. Он является посредником между сервисом и activity и связывает их. Происходит это следующим образом: при создании activity требуется создать в ней ServiceWrapper и установить связывание между ServiceWrapper и сервисом (которое является системным, т.е. система берет на себя такое связывание). Потом, все обращения к сервису идут через ServiceWrapper, вызывая его методы. 

Сервис может вызвать  создание новой Activity путем отправления соответствующего Intent сообщения,  которое обрабатывается системой. Сам по себе Intent – это объект, который содержит в себе описание абстрактных операций, которые необходимо выполнить. Таким образом, возможно посылать сообщения, которые потом обрабатываются системой Android, Android смотрит в манифест – файл (в котором описаны настройки приложения), если находит соответствие между activity и intent, то создает данный activity.

SIPEngine – это отдельный модуль, ответственный за передачу звука по протоколу SIP. Часть, основанная на общении с сервером посредством протокола SIP,  основана на Open-Source библиотеке MjSip. В данном модуле есть методы, позволяющие совершать звонки, а также реагировать на сообщения от сервера (такие как, успешный звонок, отвергнутый звонок, таймаут по времени соединения с сервером и т.д.).

Сервис взаимодействует  с SIPEngine тем, что вызывает его методы, связанные со звонком. Т.е. пользователь нажал кнопку позвонить, данное событие поймано в Activity, Activity передает через ServiceWrapper команду к сервису позвонить, а сервис обращается к SIPEngine с просьбой выполнить звонок.

 

 

 

 

 

    1.  Ключевые классы элементов архитектуры.
      1. Activity.

Рассмотрим класс Sipdroid – главное окно(Activity) нашего приложения и его основные методы (все методы можно видеть на рисунке 14).

Рисунок 14:Константы и методы класса Sipdroid

onCreate(Bundle savedInstanceState) – первый метод, который вызывается при создании сущности. В нем происходит обработка функционала и решение о том, что из него показываться в главном окне (есть функционал, доступный в режиме разговора, а есть доступный вне разговора). Также, происходит решение о том, требуется ли показывать пользователю диалог об активации приложения.

 

onDestroy() – последний метод, который вызывается при разрушении сущности. Здесь происходит освобождение всех связанных с Sipdroid сущностей (например, ServiceWrapper).

 

onCreateOptionsMenu(Menu menu) – метод, инициализирующий меню, появляющегося на нажатии на кнопку “Menu”. Из ресурсов приложения (которые хранятся в формате xml) берутся элементы меню “Настройки”, “Спрятать”, “Выйти”.

 

onOptionsItemSelected(MenuItem item) – метод, который вызывается при нажатия на кнопку меню. Определяется нажатый элемент меню и обрабатывается событие, соответствующее данному элементу.

 

closeFromSipServiceListener() – метод, который закрывает сервис. При выходе из приложения необходимо сначала закрыть сервис, получить ответ об успешном закрытии и только после этого закрыть окно приложения, которое показывалось пользователю.

 

reinitializeService() – перезапускает сервис. Отправка через ServiceWrapper (так как сервис и Activity живут в разных процессах, то необходимо пользоваться посредником) сообщения сервису о необходимости перезапуска.

 

isRegistered() – спросить у сервиса через ServiceWrapper, зарегистрирован ли пользователь в данный момент или нет. В зависимости от регистрации пользователя на главном окне показывается различный функционал (например, незарегистрированному пользователю недоступен “Handover”).

 

 

 

 

 

 

 

 

 

      1. SipServiceWrapper

Рисунок 15:Константы и методы класса SipServiceWrapper

Все методы и классы приведены  на рисунке 15. Далее будет приведено  описание основных методов.

 

SipServiceWrapper(Context context, ISipServiceListener listener) – связать через контекст Activity и сервис и зарегистрировать listener в качестве слушателя сообщений от сервиса. В качестве listener чаще всего выступают различные Activity, которым требуется получить от сервиса ответ.

 

SipServiceWrapper(Context context) – тоже самое, что и конструктор, описанный выше, только без регистрации слушателя сообщений от сервиса.

 

unbind() – если есть сервис, и есть слушатель сообщений от него, тогда отсоединить слушателя от сервиса. Вызывается в основном при уничтожении слушателя, чтобы сервис не посылал сообщения уничтоженным Activity.

 

Остальные методы класса просто пересылают сообщения сервису о необходимом функционале.

 

      1. Service

Рисунок 16: Константы и методы класса SipService

Полный перечень методов  класса можно видеть на рисунке 16. Далее  следует описание лишь основных методов.

loadConfig() – метод преобразует данные из xml файла в объект класса UAConfig, класса представляющего конфигурацию клиента. Загрузка конфигурации происходит при инициализации сервиса. Большинство функционала клиента опирается на введенные пользователем данные, поэтому важно, чтобы во весь период жизни сервиса возможно было обратиться к конфигурации.

 

onStart(Intent intent, int startId) – метод, который вызывается при запуске сервиса. При запуске сервиса, например, необходимо проверить, не ожидает ли пользователя голосовая почта.

 

onCreate() - вызывается при создании экземпляра сервиса. В указанном методе проверяется состояние активации, не изменился ли номер SIM карты пользователя с последнего раза, начинается отслеживание уровня Wi-Fi сигнала и происходит инициализация ключевых переменных.

 

onDestroy() - вызывается при уничтожении экземпляра сервиса. Необходимо остановить все службы, запущенные в onCreate(), а также оповестить всех слушателей о закрытии сервиса, что они могли выполнить необходимые действия.

 

httpsRequestDone(int result) – связано с функцией CallBack. Смысл состоит в следующем – формируется специальный https запрос, который содержит в себе имя пользователя, зашифрованный пароль, имя адресата, и указанный запрос посылается на сервер. Сервер перезванивает адресату, который автоматически берет трубку, и соединяет с пользователем по GSM связи.

 

fireStateChanged(final int state, final String result) – оповещает всех слушателей об изменении состоянии сервиса. Используется, например, когда инициализируется звонок абоненту, чтобы Activity могли перерисовать свое графическое представление.

 

wifiStateChanged(boolean on) – получения события об изменении состояния беспроводной сети. Здесь происходит обработка функционала, связанного с беспроводной сетью, например, “Handover”.

 

showCallTypeSelector(String phone) – показать диалог выбора(Enterprise Call, GSM Call). Когда пользователь нажимает кнопку звонить, данное событие перехватывается вместе с введенным номером, обрабатывается в зависимости от настроек (в настойках, например, можно указать, чтобы звонить всегда по SIP) и предлагается пользователю визуальный выбор типа звонка.

 

У класса есть методы, которые выглядят как onUa*, - это callback методы из SipdroidEngine. Например, когда требуется завершить разговор, сервис обращается к SipdroidEngine  о прекращение звонка, происходит обработка, и сервису возвращается событие о завершении обработки.

 

Остальные методы обращаются к SipdroidEngine за выполнением указанного действия.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

      1. SIPEngine

Рисунок 17: Константы и методы класса SipdroidEngine

Полный список методов  приведен на рисунке 17, далее описаны только ключевые.

 

SipdroidEngine(SipdroidEngineListener a_EngineListener) – конструктор, который инициализирует слушателя (например, сервис), чтобы в дальнейшем оповещать слушателя о всех произошедших событиях.

 

GetState() – получить текущее состояние объекта класса. Например, с его помощью сервис может узнать, произошла ли инициализации объекта класса и, в случае успешного ответа,  продолжить собственную инициализацию.

 

StartEngine(UAConfig config) – получить конфигурацию клиента и подготовить объект класса SipProvider (класс, входящий в библиотеку MjSip) для передачи SIP сообщений серверу. Данный метод вызывается при запуске сервиса.

 

reloadConfig(UAConfig config) – перечитать конфигурацию клиента и выполнить реинициализацию. Необходимо вызывать данный метод при перезагрузке сервиса, так как сервис прочитает новую конфигурацию из файла, и конфигурации сервиса и объекта класса не будут совпадать.

 

getMyNumber() – позволяет получить полное имя клиента из введенных данных в настройках клиента. Согласно протоколу SIP формируется в виде {user_name}@{ip_address}:{port}. Используется, например, при отправке сообщений на сервер о регистрации клиента.

 

register (int expire_time) – отослать запрос на сервер о регистрации. Содержит параметр expire_time, который определяет, через сколько времени при отсутствии сообщений со стороны клиента считать, что клиент неактивен. Регистрация используется при старте системы или при возникновении соединения по Wi-Fi.

 

loopRegister(int expire_time, int renew_time, long keepalive_time) – посылать периодические сообщения о регистрации. Чтобы сервер знал, что клиент активен, необходимо посылать периодически ему сообщения.

 

unregister () – послать сообщение на сервер об окончании активного периода. Используется, например, при закрытии клиента.

 

isRegistered() – вспомогательный метод, который определяет состояние регистрации на текущий момент. Большая часть функционала опирается на данный метод.

 

listen () – перейти в режим прослушивания входящих звонков. Только в данном режиме возможно получать сообщения о звонке от сервера. Используется при инициализации объекта класса и при изменениях состояния звонка – например, когда разговор с текущим абонентом завершен, необходимо перейти в режим ожидании звонков.

 

call (String target_url) – совершить SIP звонок на номер. Здесь происходит обращение библиотеке, ответственной за передачу звука по протоколу RTP. Используется в том случае, когда клиент хочет инициализировать разговор с другим абонентом.

Информация о работе Реализация SIP-телефонии для мобильных устройств с операционной системой Android