Differences

This shows you the differences between two versions of the page.

Link to this comparison view

eim:laboratoare:laborator09 [2017/05/04 21:13]
andrei.rosucojocaru
eim:laboratoare:laborator09 [2024/03/01 14:44] (current)
dragos.niculescu
Line 23: Line 23:
     - agentul intermediar     - 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);       - 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 ​locație ​și îi trimite (mai departe) cererea de tip ''​INVITE'';​+      - caută agentul utilizator destinație folosind un server ​de localizare ​și îi trimite (mai departe) cererea de tip ''​INVITE'';​
     - agentul utilizator destinație transmite, prin intermediul agentului intermediar,​ un răspuns de tipul ''​180 Ringing'',​ către agentul utilizator sursă;     - agentul utilizator destinație transmite, prin intermediul agentului intermediar,​ un răspuns de tipul ''​180 Ringing'',​ către agentul utilizator sursă;
   - 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 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 prin ''​200 OK''​ de către cealaltă parte.   - tranzacția 3: orice participant poate transmite un mesaj de tipul ''​BYE''​ pentru a termina legătura, fiind necesar ca acesta să fie confirmat prin ''​200 OK''​ de către cealaltă parte.
 +
 +{{ :​eim:​laboratoare:​laborator09:​flux_operational.png?​nolink }}
  
 Se observă faptul că o sesiune de comunicare este împărțită în mai multe **tranzacții** care împreună alcătuiesc un **dialog**. Se observă faptul că o sesiune de comunicare este împărțită în mai multe **tranzacții** care împreună alcătuiesc un **dialog**.
Line 60: Line 62:
 ===== Configurare ===== ===== Configurare =====
  
-<note important>​Î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 ([[https://play.google.com/store/apps/details?id=com.csipsimple&​hl=en|CSipSimple]]) pentru realizarea de apeluri telefonice folosind SIP & VoIP.</​note>​+<note important>​Î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 ([[https://github.com/eim-lab/util/blob/​master/​apk/​CSipSimple_v1.02.03.com.apk|CSipSimple]], sau Linphone din Playstore) pentru realizarea de apeluri telefonice folosind SIP & VoIP.</​note>​
  
 Se va utiliza, la alegere, un furnizor (gratuit) de servicii SIP, accesibil ulterior înregistrării (creării unui cont): Se va utiliza, la alegere, un furnizor (gratuit) de servicii SIP, accesibil ulterior înregistrării (creării unui cont):
-  * [[https://​www.onsip.com/|OnSIP]] - are avantajul implementării serviciului ​[[https://webrtc.org|WebRTC]] (proiect open-source - susținut de consorțiul World Wide Web (W3C) - ce pune la dispoziție un API pentru realizarea ​de apeluri ​de voce / multimedia, conversații și partajare ​de fișiere printr-o conexiune punct la punct între dispozitive mobile (IoT) și aplicații de tip navigator)dar dezavantajul limitării numărului de accesări într-o oră; +  * recomandare 1: [[https://​www.linphone.org/freesip/|Linphone]] 
-  * [[https://​www3.pbxes.com/​index_e.php|PBXes]]+  * recomandare 2: [[https://www1.pbxes.com/​index.php|PBXES]] 
 +  * 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 SIPetc  
 +  * În această secțiune vă veti crea un cont, si veti obtine credențiale ​de acest tip  ​
  
-==== OnSIP ==== 
  
-Pentru obținerea unui cont SIP gratuit, folosind serviciul OnSIP, este necesar să se furnizeze o adresă de poștă electronică împreună cu o parolă care va fi utilizată ulterior pentru autentificarea în cadrul contului (în scopuri de administrare a acestuia), urmată de apăsarea butonului //Next//.+^ Phone Configuration ^ SIP account ^  
 +|Address of Record:​|eim-lab@sip.linphone.org | 
 +|SIP Password: | eim |  
 +|Username: |eim-lab | 
 +|Domain/Proxy:​|sip.linphone.org |
  
-{{ :​eim:​laboratoare:​laborator09:​onsip01new.png?​nolink&​500 }} 
  
-Ulterior vor trebui să se precizeze: 
-  * o serie de detalii cu privire la organizația pentru care se creează contul SIP (denumire, număr de angajați). 
  
-{{ :eim:laboratoare:laborator09:onsip02new.png?​nolink&​500 }}+^ Phone Configuration ^ SIP account ^  
 +|Address of Record:|dragosn-200@pbxes.org | 
 +|SIP Password| eim |  
 +|Username|dragosn-200 | 
 +|Domain/​Proxy:|pbxes.org |
  
-  * denumirea unui utilizator împreună cu numărul de telefon (sunt acceptate numai numere de telefon din Statele Unite ale Americii, în acest exemplu a fost utilizat chiar numărul de telefon de suport pentru OnSIP.com) 
  
-{{ :​eim:​laboratoare:​laborator09:​onsip03new.png?​nolink&​500 }} 
  
-Pe baza informațiilor furnizate până în acest punct, se va genera denumirea de domeniu precum și adresa SIP care va fi utilizată pentru apeluri multimedia și mesagerie instantanee folosind VoIP: 
  
-{{ :​eim:​laboratoare:​laborator09:​onsip04new.png?​nolink&​500 }} +==== OnSIP ==== 
- +Serviciul ​[[https://www.onsip.com/getonsip|OnSIP]] nu mai este ușor de folosit pentru ​conturi free din 2021 m
-În urma completării acestor informații,​ se va afișa următorul mesaj: +
- +
-{{ :​eim:​laboratoare:​laborator09:​onsip05new.png?​nolink }} +
- +
-La adresa de poștă furnizată va fi transmisă o legătură Internet, la accesarea căreia utilizatorul va fi redirectat către o pagină în care va putea finaliza procesul de înscriere, prin crearea unui număr de utilizatori asociați contului, pentru care se vor specifica:​ +
-  * un nume asociat contului respectiv;​ +
-  * adresa de poștă electronică;​ +
-  * extensia. +
- +
-{{ :​eim:​laboratoare:​laborator09:​onsip06new.png?​nolink&​500 }} +
- +
-{{ :​eim:​laboratoare:​laborator09:​onsip07new.png?​nolink&​500 }} +
- +
-Conturile care au fost create pentru fiecare dintre utilizatori vor trebui confirmate:​ +
- +
-{{ :​eim:​laboratoare:​laborator09:​onsip08new.png?​nolink&​500 }} +
- +
-În urma realizării cu succes a contului SIP gratuit, acesta va putea fi accesat pe pagina Internet ​[[http://admin.onsip.com|]], prin furnizarea denumirii contului și a parolei specificate anterior: +
- +
-{{ :​eim:​laboratoare:​laborator09:​onsip09new.png?​nolink }} +
- +
-Vor trebui acceptate termenii și condițiile pentru accesarea acestui serviciu SIP gratuit, inclusiv pentru serviciul găzduit E911 (separat):​ +
- +
-{{ :​eim:​laboratoare:​laborator09:​onsip10new.png?​nolink&​500 }} +
- +
-{{ :​eim:​laboratoare:​laborator09:​onsip11new.png?​nolink&​500 }} +
- +
-În secțiunea //​Dashboard//​ unde pot fi vizualizate statistici cu privire la numărul de înregistrări în rețea ale contului SIP, timpul petrecut în convorbiri multimedia VoIP, costurile suplimentare (pentru serviciile plătite), intervalele de timp în care traficul de date a fost cel mai intens. +
- +
-De asemenea, secțiunea //​Users// ​este foarte importantă,​ întrucât acolo sunt furnizate informațiile necesare pentru utilizarea contului SIP din contextul altor dispozitive,​ pentru fiecare cont de utilizator în parte: +
-  * URI-ul SIP (are forma ''<​nume_de_utilizator>​@<​domeniu>''​);​ +
-  * numele de utilizator;​ +
-  * domeniul; +
-  * parola SIP → **atenție!!! această valoare este autogenerată ​și este diferită ​de parola furnizată la înregistrare**;​ +
-  * numele de utilizator furnizat pentru autentificare → **atenție!!! valoarea acestui identificator este diferită de numele de utilizator furnizat la înregistrare (de regulă, acesta este același cu numele de domeniu)**;​ +
-  * proxy-ul ​folosit pentru ​conexiuni ​din afara domeniului ​(''​sip.onsip.com''​). +
- +
-{{ :​eim:​laboratoare:​laborator09:​onsip12new.png?​nolink&​800 }} +
- +
-==== PBXes ==== +
- +
-Pentru obținerea unui cont SIP gratuit, folosind serviciul PBXes, este necesar se accesează legătura Internet //Create Account//​. +
- +
-{{ :​eim:​laboratoare:​laborator09:​pbxes01new.png?​nolink }} +
- +
-Este necesar să se furnizeze mai multe informații,​ legate de: +
-  * limba folosită pentru afișarea interfeței grafice în cadrul paginii Internet; +
-  * contul propriu-zis (denumire - limitată la maximum 15 caractere!!! și parolă - nu sunt permise caracterele speciale);​ +
-  * date personale (nume / prenume, adresă - inclusiv oraș și cod poștal -, zona de timp, data nașterii, numărul de telefon, adresa de poștă electronică);​ +
-  * versiunea aplicației (''​stable''​);​ +
-  * permisiunea de a permite unor moderatori independenți de a inspecta datele de configurare și fișierele de jurnalizare spre a putea oferi suport. +
- +
-{{ :​eim:​laboratoare:​laborator09:​pbxes02new.png?​nolink }} +
- +
-Ulterior înregistrării cu succes, se furnizează adresa care poate fi folosită pentru accesarea serviciilor SIP și VoIP (de regulă, numele de utilizator furnizat în cadrul înregistrării,​ la care se adaugă ''​@pbxes.org''​). +
- +
-{{ :​eim:​laboratoare:​laborator09:​pbxes03new.png?​nolink }} +
- +
-Pentru utilizarea propriu-zisă a serviciului,​ este necesară **definirea unei extensii** (//​Extensions//​ → //Add Extension//​) de tipul SIP: +
- +
-{{ :​eim:​laboratoare:​laborator09:​pbxes04new.png?​nolink }} +
- +
-Este necesar să se furnizeze informații legate de: +
-  * extensia propriu-zisă (număr de extensie și denumire);​ +
-  * date pentru apelul prin Internet (URL, text, GPS - latitudine și longitudine și, opțional, o imagine); +
-  * parola specifică (va fi utilizată în locul parolei furnizată pentru cont). +
- +
-{{ :​eim:​laboratoare:​laborator09:​pbxes05new.png?​nolink }}+
  
 ==== Utilizare pe Dispozitivul Mobil ==== ==== Utilizare pe Dispozitivul Mobil ====
Line 169: Line 106:
  
 | {{ :​eim:​laboratoare:​laborator09:​testcall02new.png?​nolink&​300 }} | {{ :​eim:​laboratoare:​laborator09:​testcall02android5new.png?​nolink&​300 }} | | {{ :​eim:​laboratoare:​laborator09:​testcall02new.png?​nolink&​300 }} | {{ :​eim:​laboratoare:​laborator09:​testcall02android5new.png?​nolink&​300 }} |
-| Android OS < 5 | Android OS >= 5 |+ Android OS < 5   Android OS >= 5  |
  
 <​html>​ <​html>​
Line 213: Line 150:
 Se accesează aplicația //Phone// și din meniul acesteia intrarea //​Settings//​. Se accesează aplicația //Phone// și din meniul acesteia intrarea //​Settings//​.
  
-{{ :​eim:​laboratoare:​laborator09:​androidstack01.png?​nolink&​300 }}+<​html>​ 
 +<​center>​ 
 +</​html>​
  
-Se parcurg următoarele ecrane //Calls// → //Calling Accounts// → //SIP Accounts//:+| {{ :eim:​laboratoare:​laborator09:​androidstack01new.png?​nolink&​300 }} | {{ :​eim:​laboratoare:​laborator09:​androidstack01android5new.png?​nolink&​300 }} | 
 +|  Android OS < 5  |  Android OS >= 5  |
  
-{{ :​eim:​laboratoare:​laborator09:​androidstack02.png?​nolink&​300 }} +<​html>​ 
 +</​center>​ 
 +</​html>​
  
-{{ :eim:​laboratoare:​laborator09:​androidstack03.png?​nolink&​300 }}+În sistemele de operare Android cu versiuni mai mici decât 5, se accesează //Call settings// → //Internet call settings// → //​Accounts//​:
  
-{{ :​eim:​laboratoare:​laborator09:​androidstack04.png?​nolink&​300 }}+{{ :​eim:​laboratoare:​laborator09:​androidstack02new.png?​nolink&​300 }} 
 + 
 +În sistemele de operare Android cu versiuni mai mari sau egale cu 5, se parcurg următoarele ecrane //Calls// → //Calling Accounts// → //SIP Accounts//:​ 
 + 
 +{{ :​eim:​laboratoare:​laborator09:​androidstack02android5new.png?​nolink&​300 }}  
 + 
 +{{ :​eim:​laboratoare:​laborator09:​androidstack03android5new.png?​nolink&​300 }} 
 + 
 +{{ :​eim:​laboratoare:​laborator09:​androidstack04android5new.png?​nolink&​300 }} 
  
 <note important>​Pentru a se putea recepționa apeluri VoIP, este necesar să se selecteze opțiunea //Receive incoming calls//. O astfel de abordare poate conduce însă la un consum de energie mult mai rapid și la epuizarea bateriei.</​note>​ <note important>​Pentru a se putea recepționa apeluri VoIP, este necesar să se selecteze opțiunea //Receive incoming calls//. O astfel de abordare poate conduce însă la un consum de energie mult mai rapid și la epuizarea bateriei.</​note>​
Line 227: Line 177:
 Definirea unui cont de tip SIP se realizează prin accesarea opțiunii //Add Account//: Definirea unui cont de tip SIP se realizează prin accesarea opțiunii //Add Account//:
  
-{{ :​eim:​laboratoare:​laborator09:​androidstack05.png?​nolink&​300 }}+<​html>​ 
 +<​center>​ 
 +</​html>​ 
 + 
 +{{ :​eim:​laboratoare:​laborator09:​androidstack03new.png?​nolink&​300 }} | {{ :​eim:​laboratoare:​laborator09:​androidstack04android5new.png?​nolink&​300 }} | 
 +|  Android OS < 5  |  Android OS >= 5  | 
 + 
 +<​html>​ 
 +</​center>​ 
 +</​html> ​
  
 Informațiile care trebuie specificate sunt: Informațiile care trebuie specificate sunt:
Line 239: Line 198:
   * transmiterea de mesaje de tip keep-alive.   * transmiterea de mesaje de tip keep-alive.
  
-{{ :​eim:​laboratoare:​laborator09:​androidstack06.png?​nolink&​300 }}+<​html>​ 
 +<​center>​ 
 +</​html>​ 
 + 
 +{{ :​eim:​laboratoare:​laborator09:​androidstack04new.png?​nolink&​300 }} | {{ :​eim:​laboratoare:​laborator09:​androidstack06android5new.png?​nolink&​300 }} | 
 +|  Android OS < 5  |  Android OS >= 5  | 
 + 
 +<​html>​ 
 +</​center>​ 
 +</​html> ​
  
 În situația în care contul SIP a fost creat, acesta va fi vizualizat în secțiunea //SIP Accounts// împreună cu starea sa (//​Receiving calls//, //Not receiving calls//). În situația în care contul SIP a fost creat, acesta va fi vizualizat în secțiunea //SIP Accounts// împreună cu starea sa (//​Receiving calls//, //Not receiving calls//).
  
-{{ :​eim:​laboratoare:​laborator09:​androidstack07.png?​nolink&​300 }}+<​html>​ 
 +<​center>​ 
 +</​html>​
  
-De asemenea, în secțiunea //Calling accounts// există posibilitatea de a preciza ce cont este folosit în mod implicit pentru realizarea de apeluri telefoniceSe recomandă selectarea opțiunii //Ask first// astfel încât pentru fiecare contact să se poată preciza mecanismul utilizat pentru plasarea sa.+| {{ :​eim:​laboratoare:​laborator09:​androidstack05new.png?​nolink&​300 }} | {{ :​eim:​laboratoare:​laborator09:​androidstack07android5new.png?​nolink&​300 }} | 
 +|  Android OS < 5  |  Android OS >= 5  |
  
-{{ :​eim:​laboratoare:​laborator09:​androidstack08.png?​nolink&​300 }}+<​html>​ 
 +</​center>​ 
 +</​html>​  
 + 
 +Începând cu versiunea 5 a sistemului de operare Android, în secțiunea //Calling accounts// există posibilitatea de a preciza ce cont este folosit în mod implicit pentru realizarea de apeluri telefonice. Se recomandă selectarea opțiunii //Ask first// astfel încât pentru fiecare contact să se poată preciza mecanismul utilizat pentru plasarea sa. 
 + 
 +{{ :​eim:​laboratoare:​laborator09:​androidstack08android5new.png?​nolink&​300 }}
  
 Prin accesarea unui contact de tip SIP din agenda telefonică,​ se va utiliza contul specific pentru realizarea apelului telefonic. Prin accesarea unui contact de tip SIP din agenda telefonică,​ se va utiliza contul specific pentru realizarea apelului telefonic.
  
-{{ :​eim:​laboratoare:​laborator09:​androidstack09.png?​nolink&​300 }}+<​html>​ 
 +<​center>​ 
 +</​html>​
  
-=== Aplicația CSIPSimple ===+| {{ :​eim:​laboratoare:​laborator09:​androidstack06new.png?​nolink&​300 }} | {{ :​eim:​laboratoare:​laborator09:​androidstack09android5new.png?​nolink&​300 }} | 
 +|  Android OS < 5  |  Android OS >5  |
  
-În cazul în care în aplicația ​//Phone//, opțiunea //Internet Calling// / //SIP Accounts// nu este disponibilă,​ poate fi utilizată aplicația CSipSimple din Play Store. Ulterior descărcării,​ utilizatorului îi sunt solicitate acordarea de permisiuni pentru ca această aplicație să poată fi instalată.+<​html>​ 
 +</center>​ 
 +</html>
  
-{{ :​eim:​laboratoare:​laborator09:​csipsimple01.png?​nolink&​300 }}+=== Aplicația CSIPSimple ===
  
-{{ :eim:​laboratoare:​laborator09:​csipsimple02.png?​nolink&​300 }}+În cazul în care în aplicația //Phone//, opțiunea //Internet Calling// / //SIP Accounts// nu este disponibilă,​ poate fi utilizată aplicația CSipSimple din <​del>​Play Store</​del>​[[https://​github.com/​eim-lab/​util/​blob/​master/​apk/​CSipSimple_v1.02.03.com.apk|github/​eim-lab]]. Ulterior descărcării,​ utilizatorului îi sunt solicitate acordarea de permisiuni pentru ca această aplicație să poată fi instalată.
  
-{{ :​eim:​laboratoare:​laborator09:​csipsimple03.png?​nolink&​300 }}+{{ :​eim:​laboratoare:​laborator09:​csipsimple01new.png?​nolink&​300 }}
  
-{{ :​eim:​laboratoare:​laborator09:​csipsimple04.png?​nolink&​300 }}+{{ :​eim:​laboratoare:​laborator09:​csipsimple02new.png?​nolink&​300 }}
  
-{{ :​eim:​laboratoare:​laborator09:​csipsimple05.png?​nolink&​300 }}+{{ :​eim:​laboratoare:​laborator09:​csipsimple03new.png?​nolink&​300 }}
  
-Aplicația CSipSimple pune la dispoziția utilizatorilor mai multe șabloane pentru definirea unui cont SIP. Se recomandă să se utilizeze //Generic Wizards// → //​Advanced//​ întrucât permite definirea tuturor parametrilor necesari pentru realizarea conexiunii la serverului care găzduiește un astfel de serviciu:+{{ :eim:​laboratoare:​laborator09:​csipsimple04new.png?​nolink&​300 }}
  
-{{ :eim:​laboratoare:​laborator09:​csipsimple06.png?​nolink&​300 }}+Aplicația CSipSimple pune la dispoziția utilizatorilor mai multe șabloane pentru definirea unui cont SIP. Se recomandă să se utilizeze șabloanele corespunzătoare furnizorului de servicii SIP dorit, iar în situația în care acesta nu este disponibil, se poate folosi opțiunea //Generic// care permite configurarea tuturor parametrilor:
  
-{{ :​eim:​laboratoare:​laborator09:​csipsimple07.png?​nolink&​300 }}+{{ :​eim:​laboratoare:​laborator09:​csipsimple05new.png?​nolink&​300 }}
  
-{{ :​eim:​laboratoare:​laborator09:​csipsimple08.png?​nolink&​300 }}+{{ :​eim:​laboratoare:​laborator09:​csipsimple06new.png?​nolink&​300 }}
  
-Pentru **contul de tip ''​getonsip.com''​** se precizează următorii parametri:​ +{{ :​eim:​laboratoare:​laborator09:​csipsimple07new.png?​nolink&​300 }} 
-  * denumirea contului: ''​informaticamobila2016@getonsip.com''​ + 
-  * adresa serverului care pune la dispoziție serviciile SIP: ''​getonsip.com'';​ +Pentru **contul de tip ''​OnSIP''​** se precizează următorii parametri:​ 
-  * numele de utilizator: ''​informaticamobila2016''​ +  * denumirea contului: ''​OnSIP''​ 
-  * identificatorul folosit pentru autentificare,​ de regulă același cu numele de utilizator, prefixat de șirul de caractere ''​getonsip_''​: ''​getonsip_informaticamobila2016'';​+  * numele de utilizator: ''​informaticamobila2017''​ 
 +  * identificatorul folosit pentru autentificare,​ de regulă același cu denumirea domeniului: ''​upb'';​
   * parola (din secțiunea //View Profile//, nu cea folosită la definirea contului);   * parola (din secțiunea //View Profile//, nu cea folosită la definirea contului);
 +  * domeniul: ''​upb.onsip.com''​
  
 <note tip>În situația în care se folosește emulatorul Genymotion, pentru a se evita transcrierea parolelor foarte lungi, se poate realiza operația de tip Copy-Paste din mașina fizică în mașina virtuală folosind operația de tip apăsare cu o durată de timp mai mare (//eng.// long press).</​note>​ <note tip>În situația în care se folosește emulatorul Genymotion, pentru a se evita transcrierea parolelor foarte lungi, se poate realiza operația de tip Copy-Paste din mașina fizică în mașina virtuală folosind operația de tip apăsare cu o durată de timp mai mare (//eng.// long press).</​note>​
  
-  * protocoul folosit (implicit UDP); +{{ :eim:​laboratoare:​laborator09:​csipsimple08new.png?​nolink&​300 }}
-  * proxy-ul folosit pentru conexiuni din afara domeniului''​sip.onsip.com''​+
  
-{{ :​eim:​laboratoare:​laborator09:​csipsimple09.png?​nolink&​300 }}+Contactele de tip SIP sunt vizibile în meniul aplicației CSipSimple astfel încât să poată fi plasate apeluri de tip SIP / VoIP: 
 + 
 +{{ :​eim:​laboratoare:​laborator09:​csipsimple10new.png?​nolink&​300 }} 
 + 
 +Și pentru **contul de tip PBXes** există un șablon predefinit:​ 
 + 
 +{{ :​eim:​laboratoare:​laborator09:​csipsimple11new.png?​nolink&​300 }} 
 + 
 +Trebuie să fie specificați următorii parametrii:​ 
 + 
 +  * denumirea contului: ''​Pbxes.org''​ 
 +  * numele de utilizator (**se utilizează extensia**):​ ''​dragosn-200''​ 
 +  * parola: eim; 
 + 
 +{{ :​eim:​laboratoare:​laborator09:​csipsimple12new.png?​nolink&​300 }}
  
 În secțiunea //​Accounts//,​ contul SIP poate fi în orice  moment activat sau dezactivat. Starea acestuia este vizibilă sub denumirea sa, culoarea folosită fiind sugestivă pentru rezultatul operației de înregistrare:​ În secțiunea //​Accounts//,​ contul SIP poate fi în orice  moment activat sau dezactivat. Starea acestuia este vizibilă sub denumirea sa, culoarea folosită fiind sugestivă pentru rezultatul operației de înregistrare:​
Line 295: Line 292:
     * în facultate, rețelele wireless ''​ACS-UPB-OPEN'',​ ''​eduroam'',​ ''​Java-ED117''​ nu creează probleme; în schimb, rețeaua ''​change''​ blochează anumite porturi ceea ce împiedică comunicația cu serverul SIP.     * în facultate, rețelele wireless ''​ACS-UPB-OPEN'',​ ''​eduroam'',​ ''​Java-ED117''​ nu creează probleme; în schimb, rețeaua ''​change''​ blochează anumite porturi ceea ce împiedică comunicația cu serverul SIP.
  
-{{ :​eim:​laboratoare:​laborator09:​csipsimple10.png?​nolink&​300 }}+{{ :​eim:​laboratoare:​laborator09:​csipsimple13new.png?​nolink&​300 }}
  
-Contactele de tip SIP sunt vizibile în meniul aplicației CSipSimple astfel încât să poată fi plasate apeluri de tip SIP / VoIP:+===== Android NGN Stack =====
  
-{{ :eim:​laboratoare:​laborator09:​csipsimple11.png?​nolink&​300 }}+[[http://​developer.android.com/​guide/​topics/​connectivity/​sip.html|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). Totuși, poate fi utilizat pentru apeluri audio, funcționalitatea fiind disponibilă în //Phone// → //​Settings//​ → //Internet Calling// (începând cu versiunea 5 a sistemului de operare Android, //SIP Accounts//).
  
-{{ :eim:laboratoare:​laborator09:​csipsimple12.png?​nolink&​300 }}+Se preferă însă utilizarea API-ului NGN (New Generation Networking),​ care implementează o stivă SIP completă, dispunând și de documentarea metodelor care pot fi utilizatehttps://​imsdroid.googlecode.com/​svn-history/​r381/​branches/​2.0/​android-ngn-stack-00.pdf.
  
-Pentru ​**contul de tip PBXes** există un șablon predefinit:+Pentru ​integrarea acestei funcționalități în cadrul unui proiect Android Studio, este necesat ca inițial să se cloneze depozitul ''​imsdroid''​ corespunzător [[https://​github.com/​DoubangoTelecom/​imsdroid|contului Github al organizației Doubango Telecom]].
  
-{{ :eim:laboratoare:laborator09:​csipsimple13.png?​nolink&​300 }}+<​code>​ 
 +student@eim-lab:~$ git clone https://​github.com/​DoubangoTelecom/​imsdroid.git 
 +</​code>​
  
-Se recomandă însă să se utilizeze tot un șablon general, astfel încât să poată fi controlați foarte bine toți parametrii:+Din cadrul acestui depozit la distanță, nu se va reține decât proiectul ''​android-ngn-stack'',​ din care vor fi eliminate fișierele corepunzătoare depozitului GitHub.
  
-  * denumirea contului: ''​mobilecomputing''​ +Pentru a integra această funcționalitate în cadrul aplicației Android, proiectul trebuie să fie referit în fișierul ​''​build.gradle''​, după ce este adus în structura ​de directoare sub formă de modulastfel încât acesta să fie compilat în momentul în care se construiește fișierul .apk:
-  * adresa serverului care pune la dispoziție serviciile SIP: ''​pbxes.org''​+
-  * numele ​de utilizator (**se utilizează extensia**):​ ''​mobilecomputing-100''​ +
-  * identificatorul folosit pentru autentificarede regulă același cu numele de utilizator;​ +
-  * parola (**se utilizează extensia**);​ +
-  * protocoul folosit (implicit UDP); +
-  * proxy-ul folosit pentru conexiuni din afara domeniului''​pbxes.org''​+
  
-{{ :​eim:​laboratoare:​laborator09:csipsimple14.png?nolink&​300 ​}}+{{ :​eim:​laboratoare:​laborator07:02volleyandroidstudio.png?nolink }}
  
-===== Android NGN Stack =====+<file build.gradle>​ 
 +dependencies { 
 +  ... 
 +  compile project(':​android-ngn-stack'​) 
 +
 +</​file>​
  
-[[http://​developer.android.com/​guide/​topics/​connectivity/​sip.html|Stiva SIP]] face parte din SDK-ul Android începând cu versiunea 2.3 (GingerbreadAPI level 9), însă nu dispune încă de toate funcționalitățile (mesagerie instantanee,​ apeluri video). Totuși, poate fi utilizat ​pentru apeluri audio, funcționalitatea fiind disponibilă în //Phone// → //​Settings//​ → //Internet Calling// (ulterior //SIP Accounts//​).+Cu toate acestea, proiectul ''​android-ngn-stack''​ nu poate fi folosit ca atarefiind necesar să îi fie aduse o serie de modificări pentru a putea fi utilizat:
  
-Se preferă însă utilizarea API-ului NGN (New Generation Networking)care implementează o stivă SIP completă, dispunând ​și de documentarea metodelor ​care pot fi utilizate: https://imsdroid.googlecode.com/svn-history/r381/branches/2.0/android-ngn-stack-00.pdf.+**1.** În fișierul ''​build.gradle''​ corespunzător proiectului ''​android-ngn-stack''​ trebuie să se utilizeze aceeași versiune pentru SDK-ul de Android și pentru utilitarele de construire a aplicațieiastfel încât să nu fie necesar să fie descărcate mai multe versiuni pe aceeași mașină. Mai mult, dacă se folosește ​versiune de SDK mai mare sau egală cu 23, este necesar să se specifice explicit folosirea bibliotecii Apache HTTP Componentsîntrucât începând de la acest nivel, suportul pentru ea a fost întrerupt. 
 + 
 +<file build.gradle>​ 
 +android { 
 +  compileSdkVersion 25 
 +  buildToolsVersion "​25.0.2"​ 
 +  ... 
 +  useLibrary '​org.apache.http.legacy'​ 
 +
 +</​file>​ 
 + 
 +**2.** În fișierul ''​AndroidManifest.xml''​ corespunzător proiectului ''​android-ngn-stack''​ trebuie să se elimine proprietatea ''​android:​icon''​ din elementul ''<​application>''​ de vreme ce și proiectul principal ​deține o astfel de proprietate,​ generându-se astfel un conflict în momentul în care se construiește aplicația: 
 + 
 +<file xml AndroidManifest.xml>​ 
 +<​manifest ...> 
 +  <​application 
 +    android:​name="​NgnApplication"​ 
 +    android:​label="​@string/​app_name">​ 
 +    <string name="​doubango_revision">​1309</​string>​ 
 +    <service android:​name="​NgnNativeService"/>​ 
 +  </​application>​ 
 +  <!-- ... --> 
 +</​manifest>​ 
 +</​file>​ 
 + 
 +**3.** În clasa ''​NgnEngine.java''​ poate fi necesar să se modifice biblioteca partajată încărcată în momentul în care se detectează că dispozitivul mobil deține [[https://developer.android.com/ndk/​guides/​cpu-arm-neon.html|un procesor cu capabilități SIMD (ARM v7 ARM v8)]]. Acest lucru este în special valabil pentru emulatoare, care publică anumite capabilități pe care nu le implementează însă propriu-zis. Într-o astfel de situație, este necesar să se încarce biblioteca partajată ''​tinyWrap.so''​ în loc de ''​tinyWRAP_neon.so''​. 
 + 
 +<file java NgnEngine.java>​ 
 +private static void initialize2() { 
 +  ​// ... 
 +   
 +  ​// lines 104-116 
 +  boolean haveLibUtils = new File(String.format("​%s/​%s",​ NgnEngine.LIBS_FOLDER,​ "​libutils_armv5te.so"​)).exists();​ 
 +  if (haveLibUtils) { // only "​armeabi-v7a" comes with "​libutils.so" 
 +    System.loadLibrary("​utils_armv5te"​);​ 
 +    Log.d(TAG,"​CPU_Feature="​+AndroidUtils.getCpuFeatures());​ 
 +    if(NgnApplication.isCpuNeon()){ 
 +      Log.d(TAG,"​isCpuNeon()=YES"​);​ 
 +      System.loadLibrary("​tinyWRAP"​);​ 
 +    } 
 +    else{ 
 +      Log.d(TAG,"​isCpuNeon()=NO"​);​ 
 +      System.loadLibrary("​tinyWRAP"​);​ 
 +    } 
 +  } 
 +   
 +  // ... 
 + 
 +
 +</​file>​
  
 Inițial, este necesar să se obțină o referință către obiectul de tip ''​NgnEngine''​. Acest lucru poate fi realizat prin intermediul metodei statice ''​getInstance()''​ (așa cum era de așteptat, ''​NgnEngine''​ este singleton). De regulă, o astfel de operație este realizată pe metoda ''​onCreate()''​ a activității principale a aplicației Android. Inițial, este necesar să se obțină o referință către obiectul de tip ''​NgnEngine''​. Acest lucru poate fi realizat prin intermediul metodei statice ''​getInstance()''​ (așa cum era de așteptat, ''​NgnEngine''​ este singleton). De regulă, o astfel de operație este realizată pe metoda ''​onCreate()''​ a activității principale a aplicației Android.
Line 334: Line 381:
 </​code>​ </​code>​
  
-Motorul NGN trebuie configurat, prin specificarea unor parametri, reținuți sub forma unor perechi de tipul (cheie, valoare). Pentru ca serviciul SIP să poată fi accesat, trebuie ​specificat ​identificatorul utilizatoruluiadresa SIP (sub forma ''​sip:<​username>​@<​domain>''​)parolaadresa proxy-ului la care se realizează conexiunea ​și portul pe care se face acest lucru (frecvent, ​5060)rețeaua din care face parte. Pot fi indicate și utilizarea rețelei 3G (implicit, dezactivată) precum și timpul de așteptare în cazul operației de înregistrare.+Motorul NGN trebuie configurat, prin specificarea unor parametri, reținuți sub forma unor perechi de tipul (cheie, valoare). 
 + 
 +Pentru ca serviciul SIP să poată fi accesat, trebuie ​specificate:​ 
 +  * ''​NgnConfigurationEntry.IDENTITY_IMPI'': ​identificatorul utilizatorului ​folosit pentru autorizare (''​upb''​);​ 
 +  * ''​NgnConfigurationEntry.IDENTITY_IMPU'': ​adresa SIP (sub forma ''​sip:<​username>​@<​domain>''​) ​- ''​informaticamobila2017@upb.onsip.com'';​ 
 +  * ''​NgnConfigurationEntry.IDENTITY_PASSWORD'': ​parola 
 +  * ''​NgnConfigurationEntry.NETWORK_PCSCF_HOST'': ​adresa proxy-ului la care se realizează conexiunea ​(''​sip.onsip.com''​);​ 
 +  * ''​NETWORK_PCSCF_PORT'': ​portul pe care se face acest lucru (5060) 
 +  * ''​NETWORK_REALM'': ​rețeaua din care face parte (''​upb.onsip.com''​) 
 + 
 +Pot fi indicate și utilizarea rețelei 3G (implicit, dezactivată) precum și timpul de așteptare în cazul operației de înregistrare.
  
 <code java> <code java>
Line 410: Line 467:
 <note tip>Este mai puțin frecvent ca operațiile de înregistrare / deînregistrare să se realizeze pe metodele ''​onStart()''​ respectiv ''​onStop()''​ deoarece execuția acestora poate fi destul de îndelungată având un impact negativ asupra responsivității sistemului de operare.</​note>​ <note tip>Este mai puțin frecvent ca operațiile de înregistrare / deînregistrare să se realizeze pe metodele ''​onStart()''​ respectiv ''​onStop()''​ deoarece execuția acestora poate fi destul de îndelungată având un impact negativ asupra responsivității sistemului de operare.</​note>​
  
-Ulterior, se pot deschide sesiuni audio-video (''​NgnAVSession''​) respectiv pentru mesagerie instantanee (''​NgnMessagingSession''​), acestea fiind obiecte partajate ​la nivelul întregii aplicații întrucât furnizează aproximativ toate metodele pentru gestiunea apelurilor telefonice ​sau pentru transmiterea ​de mesaje.+În cazul **operațiilor de înregistrare / deînregistrare**, se poate defini un **ascultător pentru mesaje cu difuzare**, care gestionează acțiunile de tipul ''​NgnRegistrationEventArgs.ACTION_REGISTRATION_EVENT''​. 
 + 
 +Evenimentele ce pot fi tratate de un astfel de obiect sunt legate de: 
 +  * rezultatul operației de înregistrare:​ 
 +    * ''​REGISTRATION_NOK''​ 
 +    * ''​REGISTRATION_OK''​ 
 +    * ''​REGISTRATION_INPROGRESS''​ 
 +  * rezultatul operației de deînregistrare:​ 
 +    * ''​UNREGISTRATION_NOK''​ 
 +    * ''​UNREGISTRATION_OK''​ 
 +    * ''​UNREGISTRATION_INPROGRESS''​ 
 + 
 +Operațiile de înregistrare (activare) respectiv deînregistrare (dezactivare) a acestui ascultător pentru mesaje cu difuzare se face pe metodele ''​onCreate()''​ respectiv ''​onDestroy()''​ ale activității. 
 + 
 +<code java> 
 +public void enableRegistrationBroadcastReceiver() { 
 +  registrationBroadcastReceiver = new RegistrationBroadcastReceiver(registrationStatusTextView);​ 
 +  registrationIntentFilter = new IntentFilter();​ 
 +  registrationIntentFilter.addAction(NgnRegistrationEventArgs.ACTION_REGISTRATION_EVENT);​ 
 +  registerReceiver(registrationBroadcastReceiver,​ registrationIntentFilter);​ 
 +
 +</​code>​ 
 + 
 +<code java> 
 +public void disableRegistrationStateBroadcastReceiver() { 
 +  if (registrationBroadcastReceiver != null) { 
 +    unregisterReceiver(registrationBroadcastReceiver);​ 
 +    registrationBroadcastReceiver = null; 
 +  } 
 +
 +</​code>​ 
 + 
 +Implementarea ascultătorului pentru intenții cu difuzare având asociată acțiunea ''​NgnRegistrationEventArgs.ACTION_REGISTRATION_EVENT''​ presupune realizarea următoarelor operații:​ 
 +  * verificarea acțiunii corespunzătoare intenției, aceasta trebuie să fie de tipul ''​NgnRegistrationEventArgs.ACTION_REGISTRATION_EVENT'';​ 
 +  * se obțin argumentele asociate intenției cu difuzare; acestea au tipul ''​NgnRegistrationEventArgs''​ și pot fi obținute din câmpul ''​extra''​ al intenției, fiind regăsite sub cheia ''​NgnEventArgs.EXTRA_EMBEDDED'':​ 
 +    * se verifică tipul argumentului care reprezintă de fapt răspunsul care a fost obținut pentru operația de înregistrare / deînregistrare - în acest sens se folosește metoda ''​getEventType()''​ a obiectului de tip ''​NgnRegistrationEventArgs'';​ 
 +    * de regulă, tratarea fiecărui caz în parte nu presupune decât jurnalizarea sa și actualizarea corespunzătoare a controalelor din cadrul interfeței grafice. 
 + 
 +<file java RegistrationBroadcastReceiver.java>​ 
 +public class RegistrationBroadcastReceiver extends BroadcastReceiver { 
 + 
 +  @Override 
 +  public void onReceive(Context context, Intent intent) { 
 +    String action = intent.getAction();​ 
 + 
 +    if (NgnRegistrationEventArgs.ACTION_REGISTRATION_EVENT.equals(action)) { 
 + 
 +      NgnRegistrationEventArgs arguments = intent.getParcelableExtra(NgnEventArgs.EXTRA_EMBEDDED);​ 
 + 
 +      if (arguments == null) { 
 +        Log.d(Constants.TAG,​ "​Invalid event arguments"​);​ 
 +        return; 
 +      } 
 + 
 +      switch (arguments.getEventType()) { 
 +        case REGISTRATION_NOK:​ 
 +          Toast.makeText(context,​ "​Failed to register",​ Toast.LENGTH_SHORT).show();​ 
 +          Log.d(Constants.TAG,​ "​Failed to register"​);​ 
 +          break; 
 +        case REGISTRATION_OK:​ 
 +          Log.d(Constants.TAG,​ "You are now registered"​);​ 
 +          break; 
 +        case REGISTRATION_INPROGRESS:​ 
 +          Log.d(Constants.TAG,​ "​Trying to register..."​);​ 
 +          break; 
 +        case UNREGISTRATION_NOK:​ 
 +          Toast.makeText(context,​ "​Failed to unregister",​ Toast.LENGTH_SHORT).show();​ 
 +          Log.d(Constants.TAG,​ "​Failed to unregister"​);​ 
 +          break; 
 +        case UNREGISTRATION_OK:​ 
 +          Log.d(Constants.TAG,​ "You are now unregistered"​);​ 
 +          break; 
 +        case UNREGISTRATION_INPROGRESS:​ 
 +          Log.d(Constants.TAG,​ "​Trying to unregister..."​);​ 
 +          break; 
 +      } 
 +    } 
 +  } 
 +
 +</​file>​ 
 + 
 +Se pot deschide sesiuni audio-video (''​NgnAVSession''​) respectiv pentru mesagerie instantanee (''​NgnMessagingSession''​)
 + 
 +Obiectul de tip ''​NgnAVSession''​ este partajat ​la nivelul întregii aplicații întrucât furnizează aproximativ toate metodele pentru gestiunea apelurilor telefonice, indiferent ​de entitățile implicate.
  
 <code java> <code java>
Line 418: Line 558:
 ); );
 </​code>​ </​code>​
 +
 +Obiectul de tip ''​NgnMessagingSession''​ va fi creat pentru fiecare operație în parte ce implică comunicația dintre două entități, fiind necesar ca aceasta să fie eliberată după ce operația respectivă a fost procesată.
  
 <code java> <code java>
Line 426: Line 568:
 </​code>​ </​code>​
  
-În cazul **operațiilor de înregistrare / deînregistrare**,​ se poate defini un **ascultător pentru mesaje cu difuzare**, care gestionează acțiunile de tipul ''​NgnRegistrationEventArgs.ACTION_REGISTRATION_EVENT''​+<code java> 
- +NgnMessagingSession.releaseSession(instantMessagingSession);​ 
-Evenimentele ce pot fi tratate de un astfel de obiect sunt legate de: +</​code>​
-  * rezultatul operației de înregistrare:​ +
-    * ''​REGISTRATION_NOK''​ +
-    * ''​REGISTRATION_OK''​ +
-    * ''​REGISTRATION_INPROGRESS''​ +
-  * rezultatul operației de deînregistrare:​ +
-    * ''​UNREGISTRATION_NOK''​ +
-    * ''​UNREGISTRATION_OK''​ +
-    * ''​UNREGISTRATION_INPROGRESS''​+
  
 Pentru gestiunea **apelurilor telefonice** se folosesc metodele ''​makeCall()'',​ respectiv ''​hangUpCall()'',​ puse la dispoziție de obiectul ''​INgnAVSession''​. Pentru gestiunea **apelurilor telefonice** se folosesc metodele ''​makeCall()'',​ respectiv ''​hangUpCall()'',​ puse la dispoziție de obiectul ''​INgnAVSession''​.
-  * metoda ''​makeCall()''​ primește ca argument un șir de caractere formatat, reprezentând un URI valid, acesta fiind furnizat prin intermediul metodei statice ''​NgnUriUtils.makeValidSipUri()'';​ de regulă, se respectă formatul protocol:​utilizator@domeniu,​ în cazul de față protocolul fiind sip; metoda furnizează un rezultat de tip adevărat / fals;+  * metoda ''​makeCall()''​ primește ca argument un șir de caractere formatat, reprezentând un URI valid, acesta fiind furnizat prin intermediul metodei statice ''​NgnUriUtils.makeValidSipUri()'';​ de regulă, se respectă formatul ​''​protocol:​utilizator@domeniu''​, în cazul de față protocolul fiind ''​sip''​; metoda furnizează un rezultat de tip adevărat / fals;
   * metoda ''​hangUpCall()''​ nu primește nici un argument și furnizează un rezultat de tip adevărat / fals.   * metoda ''​hangUpCall()''​ nu primește nici un argument și furnizează un rezultat de tip adevărat / fals.
 +
 +<code java>
 +String validUri = NgnUriUtils.makeValidSipUri(SIPAddressEditText.getText().toString());​
 +// ...
 +if (ngnAVSession != null && ngnAVSession.makeCall(validUri)) {
 +  Log.d(Constants.TAG,​ "Call succeeded"​);​
 +} else {
 +  Log.d(Constants.TAG,​ "Call failed"​);​
 +}
 +</​code>​
 +
 +<code java>
 +if (ngnAVSession != null) {
 +  ngnAVSession.hangUpCall();​
 +  Log.d(Constants.TAG,​ "Hang up");
 +}
 +</​code>​
 +
 +De asemenea, interfața ''​INgnAVSession''​ pune la dispoziție și metodele:
 +  * ''​acceptCall()'',​ prin intermediul căreia poate fi acceptat un apel audio-video,​ de îndată ce este detectată o comunicație de acest tip;
 +  * ''​getRemotePartyUri()'',​ prin intermediul căreia poate fi obținută adresa SIP (URI-ul) entității cu care se comunică la un moment dat.
  
 În același scop, se poate defini un ascultător pentru mesaje cu difuzare, care gestionează acțiunile de tipul ''​NgnInviteEventArgs.ACTION_INVITE_EVENT''​. Evenimentele ce pot fi tratate de un astfel de obiect sunt: În același scop, se poate defini un ascultător pentru mesaje cu difuzare, care gestionează acțiunile de tipul ''​NgnInviteEventArgs.ACTION_INVITE_EVENT''​. Evenimentele ce pot fi tratate de un astfel de obiect sunt:
Line 447: Line 602:
   * ''​TERMINATED''​ / ''​TERMINATING''​   * ''​TERMINATED''​ / ''​TERMINATING''​
   * ''​NONE''​   * ''​NONE''​
 +
 +Operațiile de înregistrare (activare) respectiv deînregistrare (dezactivare) a acestui ascultător pentru mesaje cu difuzare se face pe metodele ''​onCreate()''​ respectiv ''​onDestroy()''​ ale activității.
 +
 +<code java>
 +public void enableVoiceCallBroadcastReceiver() {
 +  voiceCallBroadcastReceiver = new VoiceCallBroadcastReceiver(SIPAddressEditText,​ callStatusTextView);​
 +  voiceCallIntentFilter = new IntentFilter();​
 +  voiceCallIntentFilter.addAction(NgnInviteEventArgs.ACTION_INVITE_EVENT);​
 +  registerReceiver(voiceCallBroadcastReceiver,​ voiceCallIntentFilter);​
 +}
 +</​code>​
 +
 +<code java>
 +public void disableVoiceCallBroadcastReceiver() {
 +  if (voiceCallBroadcastReceiver != null) {
 +    unregisterReceiver(voiceCallBroadcastReceiver);​
 +    voiceCallBroadcastReceiver = null;
 +  }
 +}
 +</​code>​
 +
 +Implementarea ascultătorului pentru intenții cu difuzare având asociată acțiunea ''​NgnInviteEventArgs.ACTION_INVITE_EVENT''​ presupune realizarea următoarelor operații:
 +  * verificarea acțiunii corespunzătoare intenției, aceasta trebuie să fie de tipul ''​NgnInviteEventArgs.ACTION_INVITE_EVENT'';​
 +  * se obțin argumentele asociate intenției cu difuzare; acestea au tipul ''​NgnInviteEventArgs''​ și pot fi obținute din câmpul ''​extra''​ al intenției, fiind regăsite sub cheia ''​NgnEventArgs.EXTRA_EMBEDDED'':​
 +    * se obține sesiunea curentă pentru comunicații audio-video,​ folosind metoda statică ''​getSession()''​ a clasei ''​NgnAVSession'',​ ce primește ca argument identificatorul (obținut ca rezultat al metodei getSessionId() al obiectului de tip ''​NgnInviteEventArgs''​);​
 +    * metoda ''​getState()''​ a obiectului de tip ''​NgnAVSession''​ furnizează un obiect de tipul ''​NgnInviteSession.InviteState''​ ce reprezintă de fapt chiar rezultatul operației de comunicație prin intermediul apelurilor audio-video;​
 +    * pe starea ''​INCOMING''​ trebuie să se accepte apelul telefonic, prin intermediul metodei ''​acceptCall()''​ a obiectului ''​NgnAVSession'';​
 +    * pornirea tonului de apel se face doar pe starea ''​INCOMING''​ <code java>
 +ngnEngine.getSoundService().startRingTone();​
 +</​code>​
 +    * oprirea tonului de apel se face pe stările ''​INCALL'',​ ''​TERMINATED'',​ ''​TERMINATING''​ <code java>
 +ngnEngine.getSoundService().stopRingTone();​
 +</​code>​
 +
 +<file java VoiceCallBroadcastReceiver.java>​
 +public class VoiceCallBroadcastReceiver extends BroadcastReceiver {
 +  @Override
 +  public void onReceive(Context context, Intent intent) {
 +    String action = intent.getAction();​
 +
 +    if (NgnInviteEventArgs.ACTION_INVITE_EVENT.equals(action)) {
 +      NgnInviteEventArgs arguments = intent.getParcelableExtra(NgnEventArgs.EXTRA_EMBEDDED);​
 +      if (arguments == null) {
 +        Log.e(Constants.TAG,​ "​Invalid event arguments"​);​
 +        return;
 +      }
 +
 +      final NgnAVSession ngnAVSession = NgnAVSession.getSession(arguments.getSessionId());​
 +      if (ngnAVSession == null) {
 +        Log.e(Constants.TAG,​ "​NgnAVSession could not be fetched for this session"​);​
 +        return;
 +      }
 +
 +      NgnInviteSession.InviteState inviteState = ngnAVSession.getState();​
 +      NgnEngine ngnEngine = NgnEngine.getInstance();​
 +
 +      switch(inviteState) {
 +        case NONE:
 +        default:
 +          Log.i(Constants.TAG,​ "Call state: " + inviteState);​
 +          break;
 +        case INCOMING:
 +          Log.i(Constants.TAG,​ "​Incoming call"​);​
 +          ngnEngine.getSoundService().startRingTone();​
 +          Handler handler = new Handler();
 +          handler.postDelayed(new Runnable() {
 +            @Override
 +            public void run() {
 +              ngnAVSession.acceptCall();​
 +            }
 +          }, Constants.ACCEPT_CALL_DELAY_TIME);​
 +          break;
 +        case INCALL:
 +          Log.i(Constants.TAG,​ "Call started"​);​
 +          Toast.makeText(context,​ "Call connected",​ Toast.LENGTH_SHORT).show();​
 +          ngnEngine.getSoundService().stopRingTone();​
 +          break;
 +        case TERMINATED:
 +        case TERMINATING:​
 +          Log.i(Constants.TAG,​ "Call ended"​);​
 +          Toast.makeText(context,​ "Call disconnected",​ Toast.LENGTH_SHORT).show();​
 +          ngnEngine.getSoundService().stopRingTone();​
 +          ngnEngine.getSoundService().stopRingBackTone();​
 +          break;
 +      }
 +    }
 +  }
 +}
 +</​file>​
  
 Pentru gestiunea **mesajelor ce se doresc a fi transmise instantaneu** se folosește metoda ''​sendTextMessage()'',​ care primește ca argument șirul de caractere care trebuie comunicat. Aceasta furnizează un rezultat de tip adevărat / fals după cum operația a reușit respectiv a eșuat. Pentru gestiunea **mesajelor ce se doresc a fi transmise instantaneu** se folosește metoda ''​sendTextMessage()'',​ care primește ca argument șirul de caractere care trebuie comunicat. Aceasta furnizează un rezultat de tip adevărat / fals după cum operația a reușit respectiv a eșuat.
 +
 +<code java>
 +NgnMessagingSession instantMessagingSession = NgnMessagingSession.createOutgoingSession(
 +  VoiceCallActivity.getInstance().getNgnSipService().getSipStack(),​
 +  remotePartyUri
 +);
 +
 +if (!instantMessagingSession.sendTextMessage(messageEditText.getText().toString())) {
 +  Log.e(Constants.TAG,​ "​Failed to send message"​);​
 +} else {
 +  String conversation = conversationTextView.getText().toString();​
 +  conversationTextView.setText(conversation + "Me: " + messageEditText.getText().toString() + "​\n"​);​
 +  messageEditText.setText(""​);​
 +   ​Log.d(Constants.TAG,​ "​Succeeded to send message"​);​
 +}
 +NgnMessagingSession.releaseSession(instantMessagingSession);​
 +</​code>​
 +
 +<note tip>Așa cum se poate observa, în situația mesageriei instantanee,​ este necesar să se creeze câte o sesiune pentru fiecare mesaj gestionat, întrucât acesta reprezintă de fapt o legătură punct la punct între (cel puțin) două sau mai multe entități.</​note>​
  
 În același scop, se poate defini un ascultător pentru mesaje cu difuzare, care gestionează acțiunile de tipul ''​NgnMessagingEventArgs.ACTION_MESSAGING_EVENT''​. Evenimentele ce pot fi tratate de un astfel de obiect sunt: În același scop, se poate defini un ascultător pentru mesaje cu difuzare, care gestionează acțiunile de tipul ''​NgnMessagingEventArgs.ACTION_MESSAGING_EVENT''​. Evenimentele ce pot fi tratate de un astfel de obiect sunt:
Line 456: Line 719:
   * ''​FAILURE''​   * ''​FAILURE''​
  
-<note tip>În situația mesageriei instantaneeeste necesar ​să se creeze câte o sesiune pentru fiecare mesaj gestionatîntrucât ​acesta ​reprezintă de fapt o legătură punct la punct între ​(cel puțindouă sau mai multe entități.</note>+Operațiile de înregistrare (activare) respectiv deînregistrare (dezactivare) a acestui ascultător pentru mesaje cu difuzare se face pe metodele ''​onCreate()''​ respectiv ''​onDestroy()''​ ale activității. 
 + 
 +<code java> 
 +public void enableInstantMessagingBroadcastReceiver() { 
 +  instantMessagingBroadcastReceiver = new InstantMessagingBroadcastReceiver(conversationTextView);​ 
 +  instantMessagingIntentFilter = new IntentFilter();​ 
 +  instantMessagingIntentFilter.addAction(NgnMessagingEventArgs.ACTION_MESSAGING_EVENT);​ 
 +  registerReceiver(instantMessagingBroadcastReceiver,​ instantMessagingIntentFilter);​ 
 +
 +</​code>​ 
 + 
 +<code java> 
 +public void disableInstantMessagingBroadcastReceiver() { 
 +  if (instantMessagingBroadcastReceiver != null) { 
 +    unregisterReceiver(instantMessagingBroadcastReceiver);​ 
 +    instantMessagingBroadcastReceiver = null; 
 +  } 
 +
 +</​code>​ 
 + 
 +Implementarea ascultătorului pentru intenții cu difuzare având asociată acțiunea ''​NgnMessagingEventArgs.ACTION_MESSAGING_EVENT''​ presupune realizarea următoarelor operații:​ 
 +  * verificarea acțiunii corespunzătoare intențieiaceasta trebuie ​să fie de tipul ''​NgnMessagingEventArgs.ACTION_MESSAGING_EVENT'';​ 
 +  * se obțin argumentele asociate intenției cu difuzare; acestea au tipul ''​NgnMessagingEventArgs''​ și pot fi obținute din câmpul ''​extra''​ al intențieifiind regăsite sub cheia ''​NgnEventArgs.EXTRA_EMBEDDED''; ​acesta ​pune la dispoziție următoarele metode: 
 +    * ''​getEventType()''​ furnizează tipul de eveniment corespunzător rezultatului operației legată de mesajul transmis instaneu; 
 +    * ''​getContentType()''​ reprezintă tipul mesajului; de regulă se procesează mesaje având tipul ''​NgnContentType.T140COMMAND'';​ pentru verificarea tipului de mesaj se utilizează metoda statică ''​equals()''​ a clasei ''​NgnStringUtils'';​ 
 +    * ''​getPayload()''​ întoarce mesajul propriu zis, ca tablou de octeți neinterpretați,​ reconstituirea acestuia realizându-se folosind o anumită schemă de codificare (cel mai frecvent, ''​UTF-8''​). 
 + 
 +<file java InstantMessagingBroadcastReceiver.java>​ 
 +public class InstantMessagingBroadcastReceiver extends BroadcastReceiver { 
 + 
 +  @Override 
 +  public void onReceive(Context context, Intent intent) { 
 +    String action = intent.getAction();​ 
 +    if (NgnMessagingEventArgs.ACTION_MESSAGING_EVENT.equals(action)) { 
 +      NgnMessagingEventArgs arguments = intent.getParcelableExtra(NgnEventArgs.EXTRA_EMBEDDED);​ 
 +      if (arguments == null) { 
 +        Log.e(Constants.TAG,​ "​Invalid messaging event arguments"​);​ 
 +        return; 
 +      } 
 + 
 +      switch (arguments.getEventType()) { 
 +        case INCOMING: 
 +          if (!NgnStringUtils.equals(arguments.getContentType(),​ NgnContentType.T140COMMAND,​ true)) { 
 +            byte[] contentBytes = arguments.getPayload();​ 
 +            if (contentBytes != null && contentBytes.length > 0) { 
 +              try { 
 +                String content = new String(contentBytes,​ "​UTF-8"​);​ 
 +              } catch (UnsupportedEncodingException unsupportedEncodingException) { 
 +                Log.e(Constants.TAG,​ unsupportedEncodingException.toString());​ 
 +                if (Constants.DEBUG) { 
 +                  unsupportedEncodingException.printStackTrace();​ 
 +                } 
 +              } 
 +            } 
 +          } 
 +          break; 
 +        default: 
 +          break; 
 +      } 
 +    } 
 +  } 
 +
 +</file>
  
 ===== Activitate de Laborator ===== ===== Activitate de Laborator =====
Line 466: Line 791:
 </​html>​ </​html>​
  
-{{:​eim:​laboratoare:​laborator09:​activitatedelaborator01.png?​nolink&​300}} {{:​eim:​laboratoare:​laborator09:​activitatedelaborator02.png?​nolink&​300}}+{{:​eim:​laboratoare:​laborator09:​activitate_de_laborator01.png?​nolink&​300}} {{:​eim:​laboratoare:​laborator09:​activitate_de_laborator02.png?​nolink&​300}}
  
 <​html>​ <​html>​
Line 478: Line 803:
 **1.** În contul Github personal, să se creeze un depozit denumit '​Laborator09'​. Inițial, acesta trebuie să fie gol (nu trebuie să bifați nici adăugarea unui fișier ''​README.md'',​ nici a fișierului ''​.gitignore''​ sau a a fișierului ''​LICENSE''​). **1.** În contul Github personal, să se creeze un depozit denumit '​Laborator09'​. Inițial, acesta trebuie să fie gol (nu trebuie să bifați nici adăugarea unui fișier ''​README.md'',​ nici a fișierului ''​.gitignore''​ sau a a fișierului ''​LICENSE''​).
  
-**2.** Să se cloneze în directorul de pe discul local conținutul depozitului la distanță de la [[https://www.github.com/eim2017/​Laborator09|]]. ​+**2.** Să se cloneze în directorul de pe discul local conținutul depozitului la distanță de la [[https://​github.com/​eim-lab/​Laborator09|]]. ​
  
-În urma acestei operații, directorul Laborator09 va trebui să se conțină ​directoarele ​''​labtasks''​ și ''​solutions''​. ​+În urma acestei operații, directorul Laborator09 va trebui să se conțină ​directorul ​''​labtasks''​. ​
  
 <​code>​ <​code>​
-student@eim2017:~$ git clone https://www.github.com/eim2017/​Laborator09.git+student@eim-lab:~$ git clone https://​github.com/​eim-lab/​Laborator09.git
 </​code>​ </​code>​
  
 **3.** Să se încarce conținutul descărcat în cadrul depozitului '​Laborator09'​ de pe contul Github personal. <​code>​ **3.** Să se încarce conținutul descărcat în cadrul depozitului '​Laborator09'​ de pe contul Github personal. <​code>​
-student@eim2017:~$ cd Laborator09 +student@eim-lab:~$ cd Laborator09 
-student@eim2017:​~/​Laborator09$ git remote add Laborator09_perfectstudent https://​github.com/​perfectstudent/​Laborator09 +student@eim-lab:​~/​Laborator09$ git remote add Laborator09_perfectstudent https://​github.com/​perfectstudent/​Laborator09 
-student@eim2017:​~/​Laborator09$ git push Laborator09_perfectstudent master+student@eim-lab:​~/​Laborator09$ git push Laborator09_perfectstudent master
 </​code>​ </​code>​
  
-**4.** Să se importe în mediul integrat de dezvoltare ​Eclipse proiectul ''​android-ngn-stack'',​ care va fi utilizat ca bibliotecă pentru proiectul ''​ngnsip''​. +**4.** Să se importe în mediul integrat de dezvoltare Android ​Studio ​proiectul ''​NgnSip''​.
- +
-Să se importe în mediul integrat de dezvoltare Eclipse proiectul ''​NgnSIP''​ din directorul ''​labtasks''​. Acesta trebuie să refere biblioteca ''​android-ngn-stack'':​ //Project Properties//​ → //Android// → //Library// → //Add//. +
- +
-{{ :​eim:​laboratoare:​laborator09:​eclipse_android_library.png?​nolink&​800 }} +
- +
-<note warning>​Este necesar ca proiectul ''​android-ngn-stack''​ să fie referit ca bibliotecă și compilat ca atare, întrucât dacă se construiește o arhivă .jar pe baza sa, aceasta nu va include și bibliotecile partajate (din subdirectorul ''​libs'',​ având extensia ''​.so''​),​ astfel încât la încercarea de inițializare a stivei NGN vor fi generate excepții de tipul ''​java.lang.UnsatisfiedLinkError'' ​datorate faptului că nu pot fi încărcate bibliotecile partajate folosite.</​note>​+
  
 În interfața ''​Constants.java'',​ să se actualizeaze informațiile specifice contului SIP. În interfața ''​Constants.java'',​ să se actualizeaze informațiile specifice contului SIP.
Line 506: Line 825:
   * numele de utilizator: atributul ''​USERNAME'';​   * numele de utilizator: atributul ''​USERNAME'';​
   * identificatorul utilizatorului:​ atributul ''​IDENTITY_IMPI'';​   * identificatorul utilizatorului:​ atributul ''​IDENTITY_IMPI'';​
-  * parola: atributul ''​IDENTITY_PASSWORD''​.+  * parola: atributul ''​IDENTITY_PASSWORD'';​ 
 +  * domeniul: atributul ''​DOMAIN'';​ 
 +  * rețeaua din care face parte entitatea: ''​NETWORK_REALM''​.
  
-Aceste informații pot fi preluate de la furnizorul de servicii SIP.+Aceste informații pot fi preluate de la furnizorul de servicii SIP [[http://​admin.onsip.com|]],​ secțiunea //Users//, pentru fiecare utilizator în parte, în caseta //Phone Configuration//​.
  
 <file java Constants.java>​ <file java Constants.java>​
Line 515: Line 836:
   final public static String IDENTITY_IMPI = "​...";​   final public static String IDENTITY_IMPI = "​...";​
   final public static String IDENTITY_PASSWORD = "​...";​   final public static String IDENTITY_PASSWORD = "​...";​
 +  final public static String DOMAIN = "​...";​
 +  final public static String NETWORK_REALM = "​...";​
   // ...   // ...
 } }
Line 665: Line 988:
  
 <​code>​ <​code>​
-student@eim2017:/​opt/​android-sdk-linux/​platform-tools$ ./adb -s 192.168.56.101:​5555 shell+student@eim-lab:/​opt/​android-sdk-linux/​platform-tools$ ./adb -s 192.168.56.101:​5555 shell
 </​code>​ </​code>​
  
-În consola sistemului de operare Android, se folosește utilitarul [[http://​www.androidtcpdump.com/​download/4.7.4/​tcpdump|tcpdump]]: ​+În consola sistemului de operare Android, se folosește utilitarul ​''​tcpdump''​ pentru monitorizarea traficului de pachete.  
 + 
 +Binarele pentru acest utilitar, precompilate pentru sisteme de operare Android, folosind arhitecturi ARM, pot fi descărcate ​ de pe [[http://​www.androidtcpdump.com|Android TCP Dump]]. 
 + 
 +În situația în care este necesar ca acest utilitar să fie instalat pe alte arhitecturi (de exemplu, Genymotion folosește ''​x86''​),​ binarul acestuia poate fi obținut folosind utilitarul [[https://github.com/imrivera/​build-android-tcpdump|build-android-tcpdump]] ​care însă are nevoie de NDK precum și de alte programe (''​flex'',​ ''​bison''​). 
 + 
 +Transferul binarului ''​tcpdump''​ de pe mașina fizică pe dispozitivul mobil (rootat) sau pe emulator se face astfel:
  
 <​code>​ <​code>​
-root@android:/./tcpdump ​-s0 -ni eth1 -w /sdcard/DCIM/​sip.pcap '​udp'​+student@eim-lab:/android/​sdk/​platform-tools$ ​./adb -s 192.168.65.101:​5555 push tcpdump ​/data/bin
 </​code>​ </​code>​
  
Line 680: Line 1009:
 </​code>​ </​code>​
 </​note>​ </​note>​
 +
 +Monitorizarea propriu-zisă a pachetelor UDP pe interfața de rețea ''​eth1''​ poate fi realizată prin intermediul următoarei comenzi:
 +
 +<​code>​
 +root@android:/#​ ./tcpdump -s0 -ni eth1 -w /​sdcard/​DCIM/​sip.pcap '​udp'​
 +</​code>​
 +
  
 Se pornește apelul audio și după ce se termină mesajul, se oprește. ​ Se pornește apelul audio și după ce se termină mesajul, se oprește. ​
Line 688: Line 1024:
  
 <​code>​ <​code>​
-student@eim2017:/​opt/​android-sdk-linux/​platform-tools$ ./adb -s 192.168.56.3:5555 pull /​sdcard/​DCIM/​sip.pcap +student@eim-lab:/​opt/​android-sdk-linux/​platform-tools$ ./adb -s 192.168.56.101:5555 pull /​sdcard/​DCIM/​sip.pcap 
-student@eim2017:/​opt/​android-sdk-linux/​platform-tools$ wireshark sip.pcap+student@eim-lab:/​opt/​android-sdk-linux/​platform-tools$ wireshark sip.pcap
 </​code>​ </​code>​
  
Line 799: Line 1135:
  
 **12.** ​ Să se încarce modificările realizate în cadrul depozitului '​Laborator09'​ de pe contul Github personal, folosind un mesaj sugestiv. <​code>​ **12.** ​ Să se încarce modificările realizate în cadrul depozitului '​Laborator09'​ de pe contul Github personal, folosind un mesaj sugestiv. <​code>​
-student@eim2017:​~/​Laborator09$ git add * +student@eim-lab:​~/​Laborator09$ git add * 
-student@eim2017:​~/​Laborator09$ git commit -m "​implemented taks for laboratory 08" +student@eim-lab:​~/​Laborator09$ git commit -m "​implemented taks for laboratory 08" 
-student@eim2017:​~/​Laborator09$ git push Laborator09_perfectstudent master+student@eim-lab:​~/​Laborator09$ git push Laborator09_perfectstudent master
 </​code>​ </​code>​
  
eim/laboratoare/laborator09.1493921625.txt.gz · Last modified: 2017/05/04 21:13 by andrei.rosucojocaru
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0