Documente online.
Zona de administrare documente. Fisierele tale
Am uitat parola x Creaza cont nou
 HomeExploreaza
upload
Upload




Real-Time Transport Protocol

java


Real-Time Transport Protocol

În continuare ne vom ocupa de protocolul RTP (Real-Time Transport Protocol), protocol folosit la transmiterea si receptionarea stream-urilor media în retea. Suportul pentru acest protocol a fost introdus abia începând cu versiunea 2.0.

8.7.1. Lucrul cu stream-uri media în timp real



8.7.1.1. Stream-urile media

Streamul reprezinta un canal de comunicatie între doua entitati, o entitate care emite si una care receptioneaza. Stream-urile pot fi de doua feluri: de intrare si de iesire.

Stream-urile media se întalnesc peste tot în Internet, numarul de portaluri care ofera transmisii radio si TV fiind într-o continua crestere.

8.7.1.2. Protocoale folosite pentru stream-urile media

Transmiterea datelor media în timp real necesita ca procesul sa se desfasoare într-o retea cu o largime de banda mare. La datele media, pierderea pachetelor este mai acceptabila decât aparitia unor întârzieri mari în transmiterea datelor. Acest lucru este total diferit de accesarea unor date statice, de exemplu un fisier, când cel mai important lucru este ca toate pachetele sa ajunga la destinatie. Din acest motiv protocoalele care se folosesc la transmisia acestor date statice nu se potrivesc prea bine datelor multimedia.

Protocoalele HTTP si FTP sunt bazate pe TCP (Transmission Control Protocol) care este un protocol al stratului transport pentru care este importanta transmiterea si receptionarea datelor fara erori în retea. Când un pachet este pierdut sau receptionat incorect acel pachet se retransmite.

Din aceasta cauza la transmiterea datelor multimedia sunt folosite alte protocoale decât TCP, cel mai frecvent utilizat fiind UDP (User Datagram Protocol). UDP nu garanteaza receptia pachetelor la destinatie: nu este capabil sa compenseze datele pierdute si nici nu cere retransmisia.

Ca si TCP, UDP este un protocol al stratului transport, un protocol la nivelul de jos al retelei, care sta la baza dezvoltatii multor aplicatii.

Standardul Internet folosit la transmiterea datelor audio si video este RTP (Real-Time Transport Protocol).

8.7.1.3. Protocolul RTP

RTP ofera servicii punct-la-punct pentru transmiterea datelor în timp real. RTP este un protocol independent de retea, desi este folosit des peste UDP.

Real-Time Media Framework si Aplicatii

Real-Time Control Protocol (RTCP)

Real-Time Transport Protocol (RTP)

Alte protocoale din straturile Retea si Transport (TCP, ARM, ST-II, etc.)

UDP

IP

Figura 8.19. Arhitectura RTP

RTP poate fi utilizat atât în retele unicast cât si multicast. În retelele unicast copii separate ale datelor sunt trimise de la sursa spre fiecare destinatie. În retelele multicast datele sunt trimise de la sursa o singura data si reteaua este responabila sa trimit&# 333c28d 259; datele spre locatii multiple. Retelele multicast sunt mai eficiente pentru aplicatii multimedia cum ar fi videoconferintele. Standardul IP (Internet Protocol) suporta multicastul.

8.7.1.3.1. Serviciile RTP

RTP permite identificarea tipurilor de date transmise, determina ordinea pachetelor de date care trebuie prezentate si sincronizeaza datele media provenite de la surse diferite.

RTP nu garanteaza ordinea de sosire a pachetelor. Ordonarea acestora si detectarea pachetelor pierdute este în sarcina receptorului. Informatiile folosite pentru aceste operatii se afla în header-ele pachetelor.

Protocolul de control RTCP permite monitorizarea calitatii datelor distribuite si identifica mecanismele necesare transmisiunii RTP.

Daca calitatea serviciilor este esentiala pentru o anumita aplicatie, RTP poate fi folosit peste un protocol care permite servicii orientate pe conexiune.

8.7.1.3.2. Arhitectura RTP

O sesiune RTP este o asociere între un set de aplicatii care comunica folosind protocolul RTP. O sesiune este identificata printr-o adresa a retelei si o pereche de porturi. Un port este folosit pentru datele media iar celalalt este folosit pentru datele de control (RTCP).

Un participant este o masina unica, gazda sau utilizator care participa la o sesiune. Participarea într-o sesiune poate consta într-o receptie pasiva a datelor (receptor), într-o transmisie activa a datelor (transmitator) sau ambele.

Fiecare tip de date este transmis într-o sesiune diferita. Spre exemplu, daca într-o conferinta se transmit atât video cât si audio, o sesiune este folosita la transmiterea datelor video si o sesiune separata este folosita la transmiterea datelor audio. Aceasta permite participantilor la conferinta sa aleaga care tip de date media doresc sa receptioneze - spre exemplu, cineva care are o conexiune la retea cu banda redusa ar putea dori sa receptioneze doar partea audio a conferintei.

Transmisia datelor media într-o sesiune RTP se face sub forma de pachete. O serie de pachete care provin din aceeasi sursa poarta numele de stream RTP. Fiecare pachet are un header (antet) si un payload (datele utile). Figura urmatoare prezinta header-ul unui pachet RTP.

Bit



V

P

X

CC

M

PT

Numarul secventei

Timestamp

Sursa sincronizarii (SSRC)

Sursa continutului (CSRC) (0-15)

Figura 8.20. Header-ul unui pachet RTP

Header-ul unui pachet RTP contine:

Numarul versiunii RTP (V): 2 biti. Versiunea definita de specificatiile curente este 2.

Padding (umplere) (P): 1 bit. Daca bitul este setat, la sfârsitul pachetului exista unul sau mai multi biti care nu fac parte din payload. Ultimul byte din pachet indica numarul de biti de padding. Este folosit de unii algoritmi de criptare.

Extensia (X): 1 bit. Daca bitul este setat, dupa header-ul fix urmeaza o extensie. Acest mecanism de extensie permite implementarilor sa adauge informatii header-ului RTP.

CSRC Count (CC): 4 biti. Semnifica numarul de identificatori CSRC care urmeaza header-ului fix. Daca contorul CSRC este zero, sursa sincronizarii este sursa payload-ului.

Marker (M): 1 bit. Bitul de marker este definit de profilul particular al mediului de transmisie.

Tipul payload-ului (PT): 7 biti. Este un index într-un tabel cu profilele posibile care descrie formatul payload-ului. Maparile pentru payload-urile audio si video sunt specificate în RFC 1890.

Numarul secventei: 16 biti. Un numar unic care identifica pozitia pachetului în secventa de pachete. Se incrementeaza automat cu 1 pentru fiecare pachet trimis.

Timestamp: 32 biti. Mai multe pachete consecutive pot avea acelasi timestamp daca sunt generate logic în acelasi timp - spre exemplu, daca toate fac parte acelasi cadru video.

SSRC: 32 biti. Identifica sursa sincronizarii. Daca CSRC este zero, sursa payload-ului este sursa sincronizarii.

CSRC: 32 biti fiecare. Identifica sursele care contribuie la payload. Pot fi maxim 16 surse.

În afara datelor media, participantii la sesiune primesc pachete de control (RTCP) care sunt trimise periodic de catre sursa. Pachetele RTCP pot contine informatii despre calitatea serviciilor (Quality of Services) pentru participantii la sesiune, informatii despre portul pe care transmite sursa si statistici despre datele transmise pâna în acel moment.

Exista mai multe tipuri de pachete RTCP:

raportul sursei

raportul destinatiei

descrierea sursei

de tip Bye

specifice aplicatiei

Pachetele RTCP sunt stivuibile (stackable) si sunt trimise ca un pachet combinat care contine cel putin doua pachete, un pachet de raport si un pachet cu descrierea sursei.

Toti participantii într-o sesiune transmit pachete RTCP. Un participant care a trimis de curând date emite un raport de tipul raportul sursei. Acesta contine atât informatii despre numarul total de pachete si octeti trimisi, precum si informatii care pot fi folosite la sincronizarea stream-urilor din sesiuni diferite.

Participantii la sesiune transmit periodic pachete de tip raportul destinatiei spre toate sursele de unde primesc pachete cu date. Acesta contine informatii despre numarul de pachete pierdute, numarul maxim al secventelor primite si despre estimarea întarzierilor ce apar la comunicarea între sursa si destinatie.

Primul pachet dintr-un pachet RTCP combinat trebuie sa fie un pachet de raport, chiar daca nu au fost transmise sau receptionate date (în acest caz un raport gol este trimis).

Toate pachetele RTCP combinate trebuie sa includa o descriere a sursei (SDES), element care contine numele canonic (CNAME) care identifica sursa. Alte informatii pot fi incluse în descrierea sursei, cum ar fi numele sursei, adresa de e-mail, numarul de telefon, locatia geografica sau numele aplicatiei.

Când o sursa nu mai este activa, trimite un pachet RTCP Bye. Acesta poate include si motivul pentru care sursa paraseste sesiunea.

Pachetele RTCP APP prevad un mecanism care permite aplicatiilor sa defineasca si sa transmita informatii utilizator prin portul de control RTP.

8.7.1.3.3. Aplicatiile RTP

Aplicatiile RTP sunt clasificate de obicei în cele care primesc date din retea (clienti RTP) si cele care transmit date în retea (servere RTP). Unele aplicatii pot îndeplini ambele functii - spre exemplu aplicatiile de videoconferinta captureaza si transmit date în timp ce receptioneaza date din retea.

8.7.1.3.4. Receptia stream-urilor media din retea

Receptia streamurilor RTP este necesara în cazul câtorva tipuri de aplicatii. Spre exemplu:

aplicatiile de conferinta trebuie sa poate receptiona un stream media dintr-o sesiune RTP si sa o transmita consolei;

un robot telefonic trebuie sa poate receptiona stream-uri media dintr-o sesiune RTP si sa le stocheze într-un fisier;

o aplicatie care înregistreaza o conversatie sau o conferinta trebuie sa poata receptiona stream-uri media dintr-o sesiune, sa le trasnsmita consolei si în acelasi timp sa le stocheze într-un fisier.

8.7.1.3.5. Transmisia stream-urilor media într-o retea

Aplicatiile RTP de tip server transmit stream-uri media stocate sau capturate în retea.

Spre exemplu, într-o aplicatie de conferinta, un stream media poate fi capturat de la o camera video si transmis într-una sau mai multe sesiuni RTP. Stream-urile media trebuie codate în formate media multiple si transmise în mai multe sesiuni RTP pentru realizarea conferintei cu receptoare eterogene. Conferinta multiparty poate fi implementata fara a folosi multicast IP prin folosirea unui sesiuni RTP unicast multiple.

8.7.2. Întelegerea API-ului JMF RTP

JMF permite rularea si transmisia stream-urilor RTP prin API-urile definite în pachetele javax.media.rtp, javax.media.rtp.event si javax.media.rtp.rtcp.

Stream-urile RTP pot fi rulate local, salvate într-un fisier sau ambele.

Figura 8.21. Receptia RTP

Spre exemplu, un API RTP poate fi utilizat pentru a implementa o aplicatie de telefonie care raspunde la apeluri si înregistreaza mesajele, ca si un robot telefonic.



Similar, API-ul RTP se poate folosi pentru a transmite în retea stream-uri media capturate sau stocate local. Aceste stream-uri pot proveni dintr-un fisier sau direct de la un dispozitiv de captura.

Figura 8.22. Transmisia RTP

Spre exemplu, este posibila implementarea unei aplicatii de videoconferinta care captureaza video si audio si le transmite în retea folosind sesiuni RTP diferite pentru fiecare tip de date.

Similar, se poate înregistra o conferinta pentru transmisie ulterioara sau se poate folosi un stream audio înregistrat anterior pentru a rula automat în pauzele ce apar într-o videoconferinta (hold music).

8.7.2.1. Arhitectura RTP

API-urile JMF RTP sunt proiectate pentru a conlucra cu capabilitatile JMF de capturare, procesare si prezentare. Player-ele si Processoarele prezinta si manipuleaza stream-urile RTP ca si pe alt continut media. Se pot transmite stream-uri media care au fost capturate de la un dispozitiv de captura local (folosind o DataSource), sau care au fost stocate într-un fisier (folosind un DataSink).

Aplicatii JAVA, Applet-uri, Bean-uri

API-ul Java Media Framework

API-urile RTP

API-ul Java Media Framework Plug-in

Codec-uri despachetare

Codec-uri împachetare

Figura 8.23. Arhitectura de nivel înalt JMF RTP

8.7.2.1.1. Managerul de sesiune

În JMF, un SessionManager este folosit la coordonarea unei sesiuni RTP. El urmareste participantii la sesiune si stream-urile care sunt transmise.

Un manager de sesiune este reprezentarea locala a unei entitati distribuite, sesiunea RTP. O alta sarcina a managerului de sesiune este trata canalul de control RTCP si de a suporta RTCP atât pentru transmitator cât si pentru receptor.

Interfata SessionManager defineste metode care care permit aplicatiei sa se initializeze si sa înceapa participarea la o sesiune, sa stearga stream-urile folosite în timpul sesiunii si în final sa închida sesiunea.

Managerul de sesiune mentine statistici despre toate pachetele RTP si RTCP trimise si primite într-o sesiune. Statisticile se pot referi la întreaga sesiune sau doar la un singur stream de date. Mangerul de sesiune permite accesul la statisticile globale de receptie si transmisie:

GlobalReceptionStats: mentine statisticile globale despre receptii;

GlobalTransmissionStats: mentine statisticile cumulative despre transmisii pentru toti transmitatorii locali.

Statisticile despre un anumit participant la sesiune sau despre un stream transmis sunt disponibile prin:

ReceptionStats: mentine statistici despre receptie pentru un anumit participant;

TransmissionStats: mentine statistici despre un anumit stream transmis în retea.

Managerul de sesiune coordoneaza toti participantii la o sesiune. Fiecare participant este reprezentat de o instanta a unei clase care implementeaza interfata Participant. SessionManager creeaza un Participant ori de câte ori soseste un pachet RTCP care contine descrierea unei surse (SDES) cu un nume canonic (CNAME) care nu a mai aparut în aceea sesiune (sau a expirat de la ultima folosire).

Participantii pot fi pasivi (doar trimit pachete de control) sau activi (trimit si unul sau mai multe stream-uri RTP).

Exista exact un participant local care reprezinta un participant local client/server. Un participant local indica faptul ca va trimite mesaje de control RTCP prin începerea unei sesiuni.

Un participant poate controla mai mult de un singur stream, fiecare fiind identificat printr-un SSRC (synchronization source identifier) folosit de sursa stream-ului.

SessionManager-ul mentine un obiect RTPStream pentru fiecare stream de pachete RTP într-o sesiune. Exista doua tipuri de stream-uri RTP:

ReceiveStream reprezinta un stream care a fost primit de la un alt participant la sesiune;

SendStream reprezinta un stream primit de la un Processor sau de la o DataSource.

Un ReceiveStream este construit automat ori de câte ori un manager de sesiune detecteaza o noua sursa de date RTP. Pentru a crea un SendStream, trebuie apelata metoda SessionManager createSendStream.

8.7.2.1.2. Evenimente RTP

Mai multe evenimente specifice RTP-ului sunt definite în javax.media.rtp.event. Aceste evenimente sunt folosite la raportarea starilor sesiunilor RTP si la raportarea starilor stream-urilor.

Figura 8.24. Evenimentele RTP

Pentru a primi notificatii despre evenimentele RTP, trebuie implementat si înregistrat cu manager-ul de sesiune un listener RTP:

SessionListener: primeste notificari despre schimbarile starii sesiunii;

SendStreamListener: primeste notificari despre schimbarile starii unui stream RTP care este transmis;

ReceiveStreamListener: primeste notificari despre schimbarile starii unui stream RTP care este primit;

RemoteListener: primeste notificari despre evenimente sau mesaje de control RTP primite de la un participant la sesiune.

Se poate implementa un SessionListener pentru a primi notificari despre evenimentele care se refera la întreaga sesiune RTP, cum ar fi primirea unor noi participanti.

Exista doua tipuri de evenimente care se refera la sesiune:

NewParticipantEvent: indica faptul ca un nou participant a aderat la sesiune;

LocalColisionEvent: indica faptul ca sursa de sincronizare este deja folosita.

Se poate implementa un SendStreamListener pentru a primi notificari ori de câte ori:

noi stream-uri ce urmeaza a fi transmise sunt create de participantul local;

transferul de date de la DataSource, folosit pentru crearea stram-ului ce urmeaza a fi trimis, a fost initiat sau a fost terminat;

formatul datelor efective se modifica.

Exista cinci tipuri de evenimente asociate cu un SendStream:

NewSendStreamEvent: indica faptul ca un nou stream ce urmeaza a fi trimis a fost creat de participantul local;

ActiveSendStreamEvent: indica faptul ca transferul de date de la DataSource a început;

InactiveSendStreamEvent: indica faptul ca transferul datelor de la DataSource     a încetat;

LocalPayloadChangeEvent: indica faptul ca formatul stream-ului sau datele utile s-au modificat;



StreamClosedEvent: indica faptul ca stream-ul a fost terminat.

Se poate implementa un ReceiveStreamListener pentru a primi notificari ori de câte ori:

noi stream-uri de receptie sunt primite;

transferul datelor este initiat sau terminat;

transferul datelor expira (times out);

un ReceiveStream neidentificat anterior este asociat cu un Participan;.

este primit un pachet RTCP APP;

formatul datelor utile se modifica.

Aceasta interfata poate fi folosita si pentru a obtine un handler pentru

stream si pentru a accesa DataSource-ul RTP pentru a creea un MediaHandler.

Exista sapte tipuri de evenimente asociate cu un ReceiveStream:

NewReceiveStreamEvent: indica faptul ca managerul de sesiune a creat un nou stream pentru o sursa nou detectata;

ActiveReceiveStreamEvent: indica faptul ca transferul datelor a început;

InactiveReceiveStreamEvent: indica faptul ca transferul datelor a încetat;

TimeoutEvent: indica faptul ca transferul datelor a expirat;

RemotePayloadChangeEvent: indica faptul ca formatul datelor utile din stream-ul receptionat s-a modificat;

StreamMappedEvent: indica faptul ca un stream nidentificat anterior a fost asociat cu un participant la sesiune;

Application Event: indica faptul ca un pachet RTCP APP a fost receptionat;

Pentru a primi notificari despre evenimentele sau mesajele de control RTP primite de la un participant în retea, se foloseste RemoteListener. De obicei RemoteListener este implementat într-o aplicatie folosita la monitorizarea sesiunii - permite primirea de rapoarte RTCP si monitorizarea calitatii receptiei fara a primi date în fiecare stream.

Exista trei tipuri de evenimente asociate cu un participant la distanta:

ReceiverReportEvent: indica faptul ca un raport de receptie RTP a fost primit;

SenderReportEvent: indica faptul ca un raport de transmisie RTP a fost primit;

RemoteCollisionEvent: indica faptul ca doi participanti folosesc o sursa cu acelasi ID pentru sincronizare (SSRC).

8.7.2.1.3. Datele RTP

Stream-urile dintr-o sesiune RTP sunt reprezentate de obiecte RTPStream. Exista doua tipuri ale acestor obiecte: ReceiveStream si SendStream. Fiecare stream RTP are un buffer pentru sursa de date asociata cu el. Pentru ReceiveStreams, aceasta DataSource este întotdeauna PushBufferDataSource.

Managerul de sesiune construieste automat noi stream-uri de receptie în momentul în care detecteaza receptia unor stream-uri de la participantii la sesiune. Noi stream-uri de transmisie se construiesc prin apelarea createSendStream asupra managerului de sesiune.

API-urile JMF RTP sunt proiectate pentru a fi independente de protocolul de transport folosit. Utilizatorul poate crea un handler de date RTP pentru a permite ca comunicarea sa se realizeze folosind un anumit protocol de transport. Handler-ul de date este o DataSource care poate fi folosita ca intrare pentru un Player.

Clasa abstracta RTPPushDataSource defineste elementele de baza ale uni handler de date RTP. Acesta are atât un stream de date de intrare (PushSourceStream) cât si unul de iesire (OutputDataStream). Un handler de date poate fi folosit atât pentru canalul de date cât si pentru cel de control al unei sesiuni RTP. Daca este folosit pentru canalul de date, handler-ul implementeaza interfata DataChannel.

Un RTPSocket este un RTPPushDataSource care are atât canalul de date cât si cel de control. Fiecare canal are un stream de intrare si unui de iesire prin care emite/receptioneaza date în retea. Un RTPSocket poate exporta RTPControls pentru a trimite dinamic managerului de sesiune informatii despre datele utile.

Deoarece un RTPSocket creat de utilizator poate fi folosit la construirea unui Player prin intermediul Manager-ului, JMF defineste numele si locatiile implementarilor RTPSocket:

<protocol package-prefix>.media.protocol.rtpraw.DataSource

Toate tipurile de date RTP folosesc un format specific RTP pentru codare, format definit în clasele AudioFormat si VideoFormat. Spre exemplu, pachetele gsm încapsulate RTP au codarea setata pe AudioFormat.GSM_RTP, în timp ce formatele video codate JPEG au codarea setata pe VideoFormat.JPEG_RTP.

AudioFormat defineste patru string-uri standard specifice codarii RTP:

public static final String ULAW_RTP =    "JAUDIO_G711_ULAW/rtp";

public static final String DVI_RTP = "dvi/rtp";

public static final String G723_RTP = "g723/rtp";

public static final String GSM_RTP = "gsm/rtp";

VideoFormat defineste trei string-uri standard specifice codarii RTP:

public static final String JPEG_RTP = "jpeg/rtp";

public static final String H261_RTP = "h261/rtp";

public static final String H263_RTP = "h263/rtp";

8.7.2.1.4. Controlul RTP

API-ul RTP defineste o interfata de control specifica RTP, si anume RTPControl. De obicei, aceasta este implementata de DataSource specifice RTP. Asigura un mecanism care permite realizarea unei mapari între datele utile asociate dinamic si un Format. Pe lânga aceasta, RTPControl mai asigura si metode de accesare a statisticilor despre sesiune si de obtinere a Format-ului curent al datelor utile.

SessionManager-ul extinde interfata Controls, permitând unui manager de sesiune sa exporte Controale aditionale prin metodele getControl si getControls. Spre exemplu, managerul de sesiune poate exporta un BufferControl pentru a permite utilizatorului sa specifice lungimea buffer-ului si pragul (treshold-ul).

8.7.2.2. Receptia

Prezentarea unui stream RTP receptionat este realizata de un Player. Pentru a receptiona si prezenta un singur stream dintr-o sesiune RTP, trebuie folosit un MediaLocator care informeaza sesiune ca trebuie sa construiasca un Player. Un MediaLocator pentru o sesiune RTP este de forma:

rtp://address:port[:ssrc]/content-type/[ttl]

Player-ul este construit si conectat la primul stream din sesiune.

Daca se doreste prezentarea mai multor stream-uri din acea sesiune, trebuie folosit managerul de sesiune. Se pot primi notificari de la acesta ori de câte ori un stream este adaugat sesiunii si se poate construi câte un Player pentru fiecare stream nou. Folosirea unui manager de sesiune permite si monitorizarea directa si controlul sesiunii.

8.7.2.3. Transmisia

Un manager de sesiune mai poate fi folosit si la initializarea si controlul unei sesiuni, pentru a putea transmite date în retea. Datele ce urmeaza a fi transmise sunt primite de la un Processor.

Spre exemplu, pentru a crea un stream pentru a transmite date în direct de la un dispozitiv de captura, trebuie:

creat, initializat si pornit un SessionManeger pentru acea sesiune;

construit un Processor folosind DataSource-ul de captura potrivit;

setat formatul de iesire a datelor din Processor într-un format specific RTP. Un codec de împachetare RTP trebuie sa fie disponibil pentru a formata datele ce urmeaza a fi transmise;

preluate datele de la DataSource-ul de la iesirea Processor-ului;

apelata createSendStream asupra managerului de sesiune si trimisa DataSource-ul spre acesta.

Transmisia este controlata prin metodele SendStream start si stop.

Când este apelat pentru prima data, SessionManager-ul se comporta ca un receptor (trimite rapoarte de receptie RTCP). Când un SendStream este creat, începe sa trimita rapoarte de transmisie RTCP si se comporta ca si un transmitator atâta timp cât unul sau mai multe stream-uri de transmisie exista. Daca toate SendStream-urile sunt închise (nu doar oprite), managerul de sesiune revine la starea de receptor pasiv.

8.7.2.4. Extensibilitatea

Ca si alte parti ale JMF, capabilitatile RTP pot fi modificate si extinse. API-urile RTP suporta un set de baza de formate RTP si tipuri de date. Programatorii avansati si dezvoltatorii de tehnologii pot implementa plug-in-uri JMF pentru a suporta date dinamic si pentru a permite lucrul cu formate RTP aditionale.




Document Info


Accesari: 1653
Apreciat: hand-up

Comenteaza documentul:

Nu esti inregistrat
Trebuie sa fii utilizator inregistrat pentru a putea comenta


Creaza cont nou

A fost util?

Daca documentul a fost util si crezi ca merita
sa adaugi un link catre el la tine in site


in pagina web a site-ului tau.




eCoduri.com - coduri postale, contabile, CAEN sau bancare

Politica de confidentialitate | Termenii si conditii de utilizare




Copyright © Contact (SCRIGROUP Int. 2025 )