Laborator 10. Gestiunea Apelurilor Multimedia folosind SIP & VoIP
SIP (Session Initiation Protocol)
SIP (Session Initiation Protocol) este un protocol de nivel aplicație, definit de RFC 3261, folosit împreună cu alte protocoale pentru a gestiona sesiunile de comunicație multimedia la nivelul Internetului. Este frecvent folosit în cadrul tehnologiei VoIP, una dintre cele mai ieftine, portabile, flexibile și facile soluții pentru transmiterea de conținut audio și video prin intermediul rețelei de calculatoare. Singura cerință impusă pentru folosirea tehnologiei VoIP este existența unei legături la Internet.
Prin intermediul SIP sunt gestionate sesiuni care reprezintă o legătură punct la punct, un canal de comunicație între două entități. Este inspirat de HTTP și SMTP, de la care a preluat arhitectura client-server, respectiv schemele de codificare ale mesajelor, împărțite în antet și corp. SIP folosește SDP (Session Decription Protocol) pentru a califica o sesiune (unicast sau multicast) și RTP (Real Time Transport Protocol) pentru a transmite conținutul multimedia prin intermediul Internetului.
În cadrul infrastructurii de comunicație, fiecare element este identificat prin intermediul unui URI (Uniform Resource Identifier), având un rol determinat:
- agent utilizator (eng. user agent) reprezintă o entitate care
comunică (telefon mobil, tabletă, calculator): aceasta poate porni
sau opri o sesiune și de asemenea poate opera modificări asupra ei;
poate fi de mai multe tipuri:
- UAC (User Agent Client) - entitatea care trimite cererea și primește răspunsul;
- UAS (User Agent Service) - entutatea care primește cererea și trimite răspunsul;
- agent intermediar (eng. proxy server) reprezintă un element
din cadrul rețelei de calculatoare care retransmite mesajul între
agenți; acesta poate înțelege conținutul mesajului, pe baza căruia
decide pe ce rută să îl ghideze; numărul de astfel de elemente între
doi agenți utilizatori este de maximum 70; poate fi de mai multe
tipuri:
- cu stare (eng. stateful) - reține informații despre mesajele pe care le-a prelucrat și le poate folosi (în situația în care nu se primește nici un răspuns sau în situația în care mesajul ajunge încă o dată sub aceeași formă);
- fără stare (eng. stateless) - nu reține informații despre mesajele pe care le-a prelucrat;
- serverul de înregistrare (eng. registrar server) reține URI-uri despre entități pe care le stochează într-o bază de date și pe care le partajează cu alte servere de înregistrare din cadrul aceluiași domeniu; prin intermediul său, agenții utilizatori se autentifică în cadrul rețelei de calculatoare;
- serverul de redirectare (eng. redirect server) verifică baza de date cu locații, transmițând un răspuns către agentul utilizator;
- serverul de localizare (eng. location server) oferă informații cu privire la plasarea posibilă a agentului utilizator către serverele intermediare sau serverele de redirectare (doar acestea îl pot accesa)
Un flux operațional standard al unei sesiuni SIP implică următoarele operații:
- tranzacția 1:
- un agent utilizator (sursă) trimite o cerere de tip
INVITE
către un agent intermediar în scopul de a contacta un alt agent utilizator (destinație); - agentul intermediar
- trimite înapoi (imediat) un răspuns de tip
100 Trying
către agentul utilizator sursă (pentru ca acesta să nu mai transmită nimic); - caută agentul utilizator destinație folosind un server de
localizare și îi trimite (mai departe) cererea de tip
INVITE
;
- trimite înapoi (imediat) un răspuns de tip
- agentul utilizator destinație transmite, prin intermediul
agentului intermediar, un răspuns de tipul
180 Ringing
, către agentul utilizator sursă;
- un agent utilizator (sursă) trimite o cerere de tip
- tranzacția 2: în momentul în care agentul utilizator destinație este
contactat, acesta transmite, tot prin intermediul agentului
intermediar, un răspuns de tipul
200 OK
, către agentul utilizator sursă și, din acest moment, conexiunea este realizată, transmițându-se pachete RTP în ambele sensuri; - tranzacția 3: orice participant poate transmite un mesaj de tipul
BYE
pentru a termina legătura, fiind necesar ca acesta să fie confirmat prin200 OK
de către cealaltă parte.
Se observă faptul că o sesiune de comunicare este împărțită în mai multe tranzacții care împreună alcătuiesc un dialog.
Mesajele în protocolul SIP sunt de două tipuri:
- cereri au forma
<METODĂ> <URI>
unde metodele pot fi:- de bază
INVITE
reprezintă o cerere pentru deschiderea unei sesiuni cu un agent utilizator, putând conține informații de tip multimedia în corpul său; aceasta este considerată că a fost îndeplinită cu succes dacă s-a primit un cod de răspuns de tipul2xx
sau s-a transmis unACK
; un dialog stabilit între doi agenți utilizatori continuă până în momentul în care se transmite un mesaj de tipulBYE
;BYE
este metoda folosită pentru a închide o sesiune cu un agent utilizator, putând fi trimisă de oricare dintre entitățile din canalul de comunicație, fără a trece prin serverul de înregistrare;REGISTER
indică o cerere de înregistrare a unui agent utilizator către un server de înregistrare; un astfel de mesaj este transmis mai departe până ajunge la o entitate care deține autoritatea de a realiza această operație; o înregistrare poate fi realizată de un agent utilizator în numele altui agent utilizator (eng. third party registration);CANCEL
este operația folosită pentru a închide o sesiune care nu a fost încă deschisă, putând fi transmisă fie de către un agent utilizator fie de către un agent intermediar;ACK
este folosit pentru a confirma o cerere de tipINVITE
;OPTIONS
este utilizat pentru a interoga un agent utilizator sau un server intermediar despre capabilitățile sale și pentru a determina disponibilitatea sa, rezultatul fiind o listă a funcționalităților entității respective;
- extensii:
SUBSCRIBE
,NOTIFY
,REFER
,INFO
,UPDATE
,PRACK
,MESSAGE
;
- de bază
- răspunsuri reprezintă un mesaj generat de un agent utilizator de tip server sau de un server SIP în replică la o cerere provenită de la un agent utilizator de tip client; acesta poate reprezenta inclusiv o confirmare formală pentru a preveni retransmisiile; există mai multe tipuri de coduri de răspuns:
CLASA | TIP | DESCRIERE | ACȚIUNE |
---|---|---|---|
1xx | Provizoriu | Informație | Se precizează starea unui apel înainte ca un rezultat să fie disponibil. |
2xx | Definitiv | Succes | Cererea a fost procesată cu succes. Pentru cereri de tip INVITE se întoarce ACK . Pentru alte tipuri cereri, se oprește retransmiterea acestora. |
3xx | ::: | Redirectare | Se indică faptul că au fost furnizate mai multe locații posibile astfel încât ar trebui interogat un alt server pentru a se putea obține informația necesară. |
4xx | ::: | Eroare la Client | Cererea nu a fost procesată cu succes datorită unei erori la client, fiind necesar ca aceasta să fie reformulată. |
5xx | ::: | Eroare la Server | Cererea nu a fost procesată cu succes datorită unei erori la server, putând fi retransmisă către o altă entitate. |
6xx | ::: | Eroare Globală | Cererea a eșuat și nu există nici o șansă de a fi procesată corect pe o altă entitate, nici măcar dacă este reformulată. |
Exemple:
100 Trying
,180 Ringing
,181 Call is Being Forwarded
,182 Call Queue
,183 Session Progress
;200 OK
,202 Accepted
;300 Multiple Choices
,301 Moved Permanently
,302 Moved Temporarily
,305 Use Proxy
,380 Alternative Service
;400 Bad Request
,401 Unauthorized
,403 Forbidden
,404 Not Found
,405 Method Not Allowed
,406 Not Acceptable
,407 Proxy Authentication Required
,408 Request Timeout
,422 Session Timer Interval Too Small
,423 Interval Too Brief
,480 Temporarily Unavailable
,481 Dialog/Transaction Does Not Exist
,483 Too Many Hops
,486 Busy Here
,487 Request Terminated
;500 Server Internal Error
,501 Not Implemented
,502 Bad Gateway
,503 Service Unavailable
,504 Gateway Timeout
,505 Version Not Supported
,513 Message Too Large
,580 Preconditions Failure
;600 Busy Everywhere
,603 Decline
,604 Does Not Exist Anywhere
,606 Not Acceptable
.
Configurare
Note
În cadrul acestui laborator este necesar un dispozitiv mobil fizic sau un emulator cu acces la microfonul sistemului de operare. De asemenea, pe dispozitivul mobil trebuie să fie instalat Google Play Services întrucât este necesară descărcarea și instalarea unei aplicații Android (de exemplu Linphone, din Playstore) pentru realizarea de apeluri telefonice folosind SIP & VoIP.
Se va utiliza, la alegere, un furnizor (gratuit) de servicii SIP, accesibil ulterior înregistrării (creării unui cont):
- recomandare 1: Linphone
- recomandare 2: PBXES
- recomandare 3: antisip
- sunt mulți alți provideri de SIP care oferă diverse servicii contra cost: numere de telefon stabile în diverse țări, SMS, cutii poștale vocale, rutarea apelurilor de la și căre PSTN prin SIP, etc
- În această secțiune vă veti crea un cont, si veti obtine credențiale de acest tip:
Phone Configuration | SIP account |
---|---|
Address of Record: | eim-lab@sip.linphone.org |
SIP Password: | YoUrPaSs |
Username: | eim-lab |
Domain/Proxy: | sip.linphone.org |
Utilizare pe Dispozitivul Mobil
Adrese SIP pentru Testare
Pot fi folosite următoarele adrese de test:
904@mouselike.org
;thetestcall@sip.linphone.org
;- altele.
Linphone Stack
Stiva SIP face parte din SDK-ul Android începând cu versiunea 2.3 (Gingerbread, API level 9), însă nu dispune încă de toate funcționalitățile (mesagerie instantanee, apeluri video), iar începând cu versiunea 11 a fost dezactivată.
Se preferă însă utilizarea API-urilor Flexisip, care implementează o stivă SIP completă, dispunând și de documentarea metodelor care pot fi utilizate:
Pentru integrarea acestei funcționalități în cadrul unui proiect Android
Studio, este necesat ca inițial să se cloneze depozitul labtasks
corespunzător.
1. În fișierul build.gradle
corespunzător aplicației
siplinphone
se poate include biblioteca linphone fie din maven-ul linphone:
repositories {
maven {
url "https://linphone.org/maven_repository"
}
}
dependencies {
...
implementation 'org.linphone:linphone-sdk-android:5.0+'
...
}
fie ca un fișier .aar inclus direct în proiect în directorul 'libs':
repositories {
flatDir {
dirs("libs")
}
}
dependencies {
...
implementation(name:'linphone-sdk-android-5.3.96', ext:'aar')
...
}
2. În fișierul AndroidManifest.xml
se poate include acest serviciu pentru a preveni
terminarea aplicației în timpul unui apel (nu este obligatoriu ).
<service android:name="org.linphone.core.tools.service.CoreService"
android:foregroundServiceType="phoneCall|camera|microphone"
android:stopWithTask="false" />
Inițial, este necesar să se obțină o referință către obiectul de tip
Core fără de care nu se poate folosi biblioteca linphone.
Acest lucru poate fi realizat prin intermediul obiectului Factory,
obținut după importul 'org.linphone.core.*'.
De regulă, o astfel de operație este realizată pe metoda
onCreate()
a activității principale a aplicației Android.
val factory = Factory.instance()
val core = factory.createCore(null, null, this)
Obiectele Core și Factory furnizezaă furnizează toate metodele care sunt necesare pentru operațiile specifice SIP: autentificare, înregistrare, înregistrarea callback-urilor pentru evenimentele specifice plarsării și primirii apelurilor.
Motorul Linphone trebuie configurat prin specificarea unor parametri, reținuți sub forma unor perechi de tipul (cheie, valoare). O parte dintre aceștia sunt specificați folsoind utilitare din obiectele factory sau core:
Pentru ca serviciul SIP să poată fi accesat, trebuie demarată procedura REGISTER:
val authInfo = Factory.instance().createAuthInfo(username, null, password, null, null, domain, null)
val params = core.createAccountParams()
val identity = Factory.instance().createAddress("sip:$username@$domain")
params.identityAddress = identity
val address = Factory.instance().createAddress("sip:$domain")
address?.transport = transportType
params.serverAddress = address
params.setRegisterEnabled(true)
val account = core.createAccount(params)
core.addAuthInfo(authInfo)
core.addAccount(account)
core.defaultAccount = account
core.addListener(coreListener)
core.start()
Deasemenea, trebuie cerută de la utilizator permisiunea 'RECORD_AUDIO'
if (packageManager.checkPermission(Manifest.permission.RECORD_AUDIO, packageName) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(arrayOf(Manifest.permission.RECORD_AUDIO), 0)
}
Obiectul coreListener
permite suprascrierea unor callback-uri care ne ajută să implementăm funcționalități SIP
Acesta trebuie inițializat înainte de procedura REGISTER, deoarece imediat ce utilizatorul este prezent pe servere poate primi
apeluri saau mesaje. Acesta este derivat din clasa
CoreListenerStub
din care se vor suprascrie cel puțin funcțiile onAccountRegistrationStateChanged
și onCallStateChanged
.
onAccountRegistrationStateChanged
primește un parametru state care poate avea următoarele valori pe care trebuie sa le tratăm:
- RegistrationState.Failed: credențialele nu au fost acceptate, sau serverul SIP nu răspunde
- RegistrationState.Ok: înregistrarea s-a efectuat cu succes
onCallStateChanged
deasemenea primește un parametru state
ce poate avea următoarele valori de tratat:
- Call.State.IncomingReceived: se primește un apel audio
- Call.State.Connected: interlocutorul a răspuns
- Call.State.Released: interlocutorul a închis apelul
- Call.State.Connected: interlocutorul a răspuns la apel
Pentru aceste situații de obicei se activează/dezactivează diverse elemente de interfață care sunt relevante pentru noua stare a apelului.