RTSP - UniNa STiDuE

Transcript

RTSP - UniNa STiDuE
4.1 Introduzione al protocollo RTSP
Il Real Time Streaming Protocol (RTSP) [Schulzrinne e altri, 98] è un protocollo di livello
applicazione, che fornisce un framework estensibile utile per implementare il controllo del trasporto
di dati multimediali isocroni.
Il protocollo RTSP inizializza e controlla flussi singoli o multipli di media continui sincronizzati nel
tempo. Esso non trasporta i dati costituenti questi flussi, anche se è possibile realizzare una
trasmissione interlacciata dei flussi di controllo con quelli dei dati. RTSP funziona come “un
controllo remoto su rete” per server multimediali.
L’insieme dei flussi da controllare sono specificati tramite una descrizione della presentazione.
La nozione di connessione RTSP non esiste: invece un server crea un identificatore univoco per
ogni sessione. Una sessione RTSP non è legata in alcun modo ad una connessione di trasporto come
una su TCP. Durante una sessione RTSP, un client RTSP, per trasmettere le sue richieste, può
utilizzare una connessione diversa per ognuna di esse. In alternativa è possibile usare un protocollo
di trasporto non orientato alla connessione come l’UDP.
I flussi controllati da RTSP possono usare il protocollo RTP, ma il funzionamento di RTSP non
dipende dallo specifico meccanismo di trasporto utilizzato per i dati multimediali. RTSP è stato
progettato in modo che fosse simile al protocollo HTTP/1.1 in sintassi ed operazioni, affinchè fosse
possibile aggiungere i meccanismi di estensione dell’HTTP anche all’RTSP. Però RTSP differisce
dall’HTTP per molti aspetti importanti:
• RTSP introduce un certo numero di metodi nuovi e utilizza differenti identificatori di
protocollo.
• Un sever RTSP ha la necessità di mantenere delle informazioni di stato, in contrapposizione al
funzionamento di HTTP che è privo di un concetto di stato.
• Sia il client che il server RTSP possono inviare richieste.
• I dati sono trasportati fuori banda da un protocollo differente.
• RTSP usa per definizione lo standard ISO 10646 (UTF-8) invece che l’ ISO 8859-1, in modo da
essere consistente con le nuove caratteristiche di internazionalizzazione che si stanno
introducendo nell’HTTP.
• L’ URI (Universal Resource Identifier) delle richieste è sempre assoluto. Mentre l’HTTP/1.1
pone nelle richieste solo un percorso assoluto, e inserisce il nome dell’host in un campo
intestazione separato.
L’URI assoluto permette di implementare in modo semplice il “virtual hosting”, con cui si
possono mantenere su un singolo host con un unico indirizo IP diverse strutture di documenti.
Il protocollo supporta le seguenti operazioni:
•
Prelevamento di sessioni multimediali da un media-server.
Il client può richiedere la descrizione di una presentazione multimediale tramite HTTP, SDP o
altri metodi. Se la presentazione è trasmessa in multicast , la sua descrizione contiene l’indirizzo
e le porte usate per trasmettere i flussi real-time. Mentre se la trasmissione è unicast, deve essere
il client a fornire al server l’indirizzo e le porte a cui trasmettere i flussi real-time.
• Invito di un media-server in una conferenza.
Un media-server può essere “invitato” ad unirsi in una conferenza esistente, o per effetuare il
playback di qualche media all’interno della conferenza, oppure per registrare tutti o un
sottinsieme dei media esistenti nella conferenza.
Le richieste RTSP possono essere gestite dai proxy, tunnel e cache come avviene per l’HTTP/1.1
[Fielding e altri, 97].
4.1.1 Terminologia
Di seguito è riportata la definizione della terminologia utilizzata nell’ambito di questo lavoro, in
tutto quello che si riferisce a RTSP.
Controllo Aggregato: il controllo contemporaneo di flussi multipli. Ad esempio per un flusso
audio ed uno video logicamente correlati, un client RTSP può inviare al server una singola richiesta
di “play” o “pause”, che avrà effetto su entrambi.
Conferenza: una presentazione multimediale con più partecipanti (>= 1).
Client: l’applicazione client che effettua le richieste ad uno o più server di sessioni multimediali.
Connessione: un circuito virtuale, strato di trasporto, stabilito tra due applicazioni comunicanti.
Media continui: dati caratterizzati da relazioni temporali (audio, video, ecc…).
Entità: l’informazione trasferita come “payload” in una richiesta o una risposta RTSP. Una entità è
costituita da metainformazioni nella forma di intestazioni-entità, e contenuti nella forma di corpoentità.
Media Server: l’applicazione server che provvede alla riproduzione e alla registrazione di uno o
più flussi multimediali. All’interno di una presentazione, differenti flussi possono aver origine da
diversi media server.
(Media) stream: una singola istanza di media (audio, video, WB, ecc…). Quando si usa RTP, uno
stream è costituito da tutti i pacchetti RTP ed RTCP creati da una sorgente in una sessione RTP.
Questo è equivalente alla definizione di uno stream DSM-CC1.
Messaggio: l’unità base di una comunicazione RTSP costituito da una sequenza strutturata di ottetti
conforme alla sintassi RTSP, trasmessa tramite un protocollo orientato o non orientato alla
connessione.
Partecipanti: sono i membri di una conferenza. Un partcipante può essere anche una macchina (ad
es. un media server di registrazione o riproduzione).
Presentazione: un insieme di uno o più stream presentati al client come un tutt’uno, usando una
descrizione della presentazione. In molti casi, ma non sempre, questo implica il controllo aggregato
degli stream.
Descrizione della presentazione: contiene le informazioni riguardanti uno o più stream della
presentazione, come l’insieme delle codifiche, gli indirizzi di rete, i contenuti. Altri protocolli dell’
IETF, come l’SDP, usano il termine “sessione” per indicare una presentazione “live”.
Risposta: un messaggio risposta di RTSP.
Richiesta: un messaggio richiesta di RTSP.
Sessione RTSP: una transazione RTSP completa, per ottenere, ad esempio, la visione completa di
un filmato.
1
Vedi Appendice A.
4.2 Implementazione di RTSP
Il linguaggio utilizzato per implementare RTSP è Java. Trattandosi di un linguaggio ad oggetti, è
stato naturale implementare le varie parti che costituiscono RTSP tramite un mappaggio uno ad uno
su opportune classi di Java. Quindi sono state realizzate una classe RtspClient, che implementa un
client RTSP e che fa parte del package rtsp.client, e una classe RtspServer, che implementa un
server RTSP e che fa parte del package rtsp.server. Mentre il sottosistema di parsing dei messaggi
RTSP è realizzato in maniera simile ad un riconoscitore di linguaggi LL1, utilizzando un approccio
Top-Down.
L’insieme di classi che compongono il sottosistema di parsing, sono raggruppate in un package di
Java chiamato rtsp.common. I servizi offerti da questo package sono utilizzati sia dal server che
dal client.
4.2.1 Parametri del Protocollo.
RTSP URL
Per riferire le risorse di rete sono utilizzati gli schemi “rtsp” ed “rtspu”. La sintassi per gli URL è:
Per ora i fragment ed i query identifiers dell’ abs_path non hanno per l’RTSP un
rtsp_URL = ( "rtsp:" | "rtspu:" ) "//" host [ ":" port ] [abs_path ]
host
=
<A legal Internet host domain name of IP address
(in dotted decimal form), as defined by Section 2.1
of RFC 1123 \cite{rfc1123}>
port
=
*DIGIT
abs_path is defined in RFC 2068/Par.3.2.1
significato definito (a differenza dell’HTTP), quindi in questa implementazione non sono utilizzati.
Lo schema rtsp richiede che i comandi vengano trasmessi su un protocollo affidabile (per Internet
si usa il TCP), mentre lo schema rtspu identifica un protocollo non affidabile (per Internet si usa
l’UDP). Si è scelto di implementare il trasporto dei messaggi RTSP solo su TCP, in quanto si è
ritenuto necessario utilizzare un protocollo di trasporto affidabile per il trasporto dei messaggi di un
protocollo di controllo come RTSP.
Se non viene specificata la porta, si assume che essa sia la 554.
Una presentazione o uno stream è identificato tramite una stringa di testo, che ha il formato di un
URL. Questi URL possono riferirsi ad un singolo stream, oppure ad un aggregato di stream.
Un esempio di URL di RTSP è:
rtsp://lis3.deis.unical.it:554/Lecture1/Video
con cui si identifica lo stream audio all’interno della presentazione “Lecture1”, che può essere
controllata tramite richieste RTSP inviate su di una connessione TCP alla porta 554 dell’host
lis3.deis.unical.it.
Le componenti di un percorso (path) sono opache per il client, e non implicano una struttura
particolare del “file system” del server.
La classe RtspURL si occupa di implementare il parsing degli URL utilizzati in RTSP.
Timestamp relativi in SMPTE
smpte-range
smpte-type
=
=
smpte-time
=
smpte-type "=" smpte-time
"smpte" | "smpte-30-drop"
; other
1*2DIGIT ":" 1*2DIGIT ":"
[ "." 1*2DIGIT ]
"-" [ smpte-time ]
| "smpte-25"
timecodes may be added
1*2DIGIT [ ":" 1*2DIGIT ]
Esprimono il tempo relativo all’inizio di un stream (videoclip). La sintassi è la seguente:
L’ smpte-time ha il formato: ore:minuti:secondi:frame.subframe. Il formato “smpte-30-drop”
ha un “frame rate” di 29.97 frame/secondo.
Anche se in questa implementazione non viene utilizzato, è stata realizzata la classe Smpte che si
occupa del parsing di questo tipo di parametro.
Normal Play Time (NPT)
Indica la posizione assoluta nello stream relativamente all’inizio della presentazione. Questo tipo di
timestamp è costituito da una parte sinistra esprimibile o in secondi oppure in ore,minuti e secondi.
La parte destra è misurata in frazioni di secondo. L’inizio di una presentazione corrisponde ad un
npt pari a 0.0; non sono definiti valori negativi. La costante speciale now è utilizzati solo per eventi
“live”.
NPT è definito come nel DSM-CC2: Intuitivamente l’NPT è l’orologio che l’utente umano associa
al programma. E’ visualizzato come su un VCR. L’NPT avanza normalmente in modo play
(scala=1), avanza velocemente nel modo “fast forward”, decrementa quando si effettua il play
inverso, è fisso in modo pausa.
npt-range
npt-time
npt-sec
npt-hhmmss
npt-hh
npt-mm
npt-ss
=
=
=
=
=
=
=
( npt-time "-" [ npt-time ] ) | ( "-" npt-time )
"now" | npt-sec | npt-hhmmss
1*DIGIT [ "." *DIGIT ]
npt-hh ":" npt-mm ":" npt-ss [ "." *DIGIT ]
1*DIGIT
; any positive number
1*2DIGIT
; 0-59
1*2DIGIT
; 0-59
La sintassi è la seguente:
Esempi:
npt=123.45-125
npt=12:05:35.3npt=nowIl Parsing degli NPT avviene nella classe omonima Npt.
Tempo Assoluto
Il tempo assoluto è espresso nel formato ISO 8601, usando UTC (GMT). Si possono indicare anche
le frazioni di secondo.
La sintassi è la seguente:
utc-range
utc-time
2 utc-date
vedi
Appendice A.
utc-time
=
=
=
=
"clock" "=" utc-time "-" [ utc-time ]
utc-date "T" utc-time "Z"
8DIGIT
; < YYYYMMDD >
6DIGIT [ "." fraction ]
; < HHMMSS.fraction >
Esempio: la data “8 Novembre 1998 ore 14:37:20 ed un quarto di secondo in UTC si esprime:
19981108T143720.25Z
Il parsing di questo tipo di parametro avviene nella classe Utc.
4.2.2 Il sottosistema di parsing dei messaggi.
Il messaggio RTSP, nella sua forma più generica, rappresentato dalla classe RtspMessage, ha la
forma seguente:
INTESTAZIONE
CORPO
Esistono fondamentalmente due tipi di messaggi: richiesta RTSP ed risposta RTSP.
Il protocollo RTSP è di tipo testuale: i messaggi sono delle stringhe di testo, di lunghezza variabile,
organizzate per righe, separate dalla combinazione dei caratteri di terminazione CRLF (ASCII 13 e
10), anche se il parser RTSP deve essere capace di distinguere tra due righe separate dal solo
carattere CR oppure LF.
Ogni riga è divisa in due parti fondamentali: un’intestazione (header) di riga, ed un corpo di riga. In
alcuni header i corpi di riga sono a loro volta costituita da diversi sottocampi.
Nel protocollo RTSP sono definiti vari header di riga, e la maggior parte sono raggruppati nelle
seguenti categorie:
General Header;
Entity Header;
Request Header;
Response Header.
Quindi nell’implementazione sono state realizzate le classi GeneralHeader, EntityHeader,
RequestHeader e ResponseHeader, ognuna delle quali si occupa di effettuare il parsing degli
header relativi, rappresentati come variabili stringa, alle quali i parser assegnano come valore il
relativo corpo di riga.
Tutte le classi che implementano gli header, derivano dalla classe astratta Header, ed
implementano l’interfaccia Parser.
Gli utilizzatori degli oggetti di tipo header, come ad esempio gli oggetti di tipo RtspClient ed
RtspServer, si occupano di interpretare semanticamente i valori dei corpi di riga che ogni parser
estrae da un messaggio.
Esistono degli header di riga particolari, che non appartengono a nessuno dei precedenti gruppi, per
cui sono state realizzate delle opportune classi che ne implementano il parsing. Tra questi sono stati
implementati i seguenti: CseqHeader, TransportHeader, Range; tra l’altro gli ultimi due sono
caratterizzati da un corpo di riga particolarmente strutturato, per cui sono state realizzate delle
opportune classi per poterne realizzare il parsing.
I due tipi di messaggi RTSP hanno delle parti del corpo in comune, comprese nella classe
RtspMessage, mentre differiscono nell’intestazione, ed in altri campi del corpo. Dunque sono
state implementate le due classi RtspRequest ed RtspReply, necessarie per tener conto di queste
differenze. La strutture sintattiche di una richiesta e di una risposta sono:
Request = Request-Line
*( general-header
| request-header
| entity-header)
CRLF
[message-body]
Response = Status-Line
*( general-header
|response-header
|entity-header)
CRLF
[message-body]
Esistono quindi due tipi di intestazione di messaggio: la RequestLine, del tipo richiesta, e la
StatusLine, del tipo risposta. Per entrambe sono state implementate le classi omonime.
4.2.3 Messaggio Richiesta.
Request-Line = Method SP Request-URI SP RTSP-Version CRLF
L’intestazione di una richiesta ha la seguente struttura:
Il campo “Method” rappresenta il comando che deve essere eseguito dal destinatario della richiesta
(server RTSP o client RTSP).
L’interpretazione di questo campo avviene nelle rispettive classi RtspClient ed RtspServer, che
implementano la semantica del protocollo RTSP.
I metodi3 attualmente definiti nel protocollo sono:
"DESCRIBE", "ANNOUNCE", "GET_PARAMETER", "OPTIONS", "PAUSE", "PLAY", "RECORD",
"REDIRECT", "SETUP", "SET_PARAMETER" e "TEARDOWN".
Il campo “Request-URI” specifica la risorsa (il flusso dei dati multimediali, il file che li contiene)
oggetto della richiesta. Per il parsing di questo campo è stata utilizzata una classe detta RtspURL.
Il campo “RTSP-Version” indica la versione del protocollo RTSP utilizzata nel messaggio;
la sua interpretazione avviene nella classe RequestLine stessa.
Il suo formato è:
RTSP-Version = "RTSP" "/" 1*DIGIT "." 1*DIGIT
4.2.4 Messaggio Risposta.
L’intestazione di una risposta ha la seguente struttura:
Status-Line = RTSP-Version SP Status-Code SP Reason-Phrase CRLF
Il campo RTSP-Version è identico a quello visto nella Request-Line.
Il campo Status-Code è una stringa numerica rappresentante, sotto forma di “codice di uscita”,
il risultato che ha avuto l’esecuzione del comando inviato nel messaggio di richiesta di cui questo è
il messaggio di risposta. La Reason-Phrase è il messaggio corrispondente allo Status-Code,
in una forma intellegibile anche per l’utente umano.
Il parsing della Status-Line viene effettuato nella classe omonima StatusLine.
3
Del significato d'ogni metodo si parlerà nel paragrafo relativo al server RTSP.
La seguente è la lista dei codici attualmente definiti nel protocollo:
Status-Code
* "100"
* "200"
"201"
"250"
* "300"
* "301"
* "302"
"303"
"304"
"305"
* "400"
"401"
"402"
"403"
* "404"
* "405"
* "406"
"407"
"408"
"410"
"411"
"412"
"413"
"414"
"415"
* "451"
"452"
"453"
* "454"
* "455"
"456"
"457"
"458"
* "459"
* "460"
"461"
"462"
* "500"
* "501"
"502"
"503"
"504"
* "505"
"551"
Reason-Phrase
Continue
OK
Created
Low on Storage Space
Multiple Choices
Moved Permanently
Moved Temporarily
See Other
Not Modified
Use Proxy
Bad Request
Unauthorized
Payment Required
Forbidden
Not Found
Method Not Allowed
Not Acceptable
Proxy Authentication Required
Request Time-out
Gone
Length Required
Precondition Failed
Request Entity Too Large
Request-URI Too Large
Unsupported Media Type
Parameter Not Understood
Conference Not Found
Not Enough Bandwidth
Session Not Found
Method Not Valid in This State
Header Field Not Valid for Resource
Invalid Range
Parameter Is Read-Only
Aggregate operation not allowed
Only aggregate operation allowed
Unsupported transport
Destination unreachable
Internal Server Error
Not Implemented
Bad Gateway
Service Unavailable
Gateway Time-out
RTSP Version not supported
Option not supported
Il primo numero di uno Status-Code ne definisce la classe:
-
1xx: Informativo - Richiesta ricevuta, il processo continua.
2xx: Successo - L’ultima azione è stata ricevuta, compresa e accettata con successo.
3xx: Redirezione - Bisogna intraprendere ulteriori azioni per completare la richiesta.
4xx: Errore del client - La richiesta contiene errori sintattici e non può essere soddisfatta.
5xx: Errore del server - Il server non è riuscito a soddisfare una richiesta apparentemente
valida.
Gli Status-Code sono estensibili. In generale un’implementazione di RTSP deve usare e
riconoscere almeno i codici del tipo x00: questa implementazione del protocollo riconosce ed usa i
codici marcati con “*”.
Le Reason-Phrase sono solo indicative, e possono essere modificate o estese in maniera
coerente, e questo è stato fatto in vari casi, per rendere maggiormente comprensibili i messaggi che
il client mostra all’utente.
4.2.5 General Header.
Questo tipo di header comprende i seguenti:
Cache-Control;
Connection;
Date;
Via.
Il parser della classe GeneralHeader riesce a riconoscerli tutti, però in questa implementazione
viene utilizzato solo l’header Date, implementato nella classe omonima.
"Date" ":" HTTP-date
L’header Date ha la seguente sintassi:
Questa implementazione utilizza il formato HTTP-date più recente, definito nell’ RFC 1123; un
esempio è :
Date:30 Oct 1998 16:59:03 GMT
Il valore di questo header si riferisce all’istante in cui il messaggio, che lo contiene, è stato inviato.
4.2.6 Entity Header.
Questo tipo di header definisce metainformazioni opzionali riguardanti il corpo-entità, oppure, se
questo non è presente, la risorsa identificata dalla richiesta.
Gli header compresi in questo gruppo sono :
- Allow;
- Content-Base;
- Content-Encoding;
- Content-Language;
- Content-Length;
- Content-Location;
- Content-Type;
- Expires;
- Last-Modified.
Come per gli General Header, il parser della classe EntityHeader li riconosce tutti, ma questa
implementazione usa solo quelli descritti di seguito.
L’ header Content-Base può essere usato per specificare l’URI di base per la risoluzione di un
URL relativo. La sintassi è:
"Content-Base" ":" absoluteURI
Se questo header non compare nel messaggio, l’URI di base viene definito o tramite l’header
Content-Location (se questo è un URI assoluto), oppure tramite il primo URI utilizzato nella
sessione RTSP.
L’header Content-Length indica la dimensione dell’entità del messaggio, il numero (in
formato decimale) degli ottetti che lo compongono. Deve essere sempre presente in tutti i messaggi
il cui corpo non è vuoto. Se viene omesso si assume che la lunghezza del corpo del messaggio è
zero. La sintassi è:
"Content-Length" ":" 1*DIGIT
L’header Content-Location può essere usato per ricostruire l’URI completo per individuare
una risorsa referenziata in un messaggio. La sintassi è:
"Content-Location" ":"( absoluteURI | relativeURI )
Se l’URI è relativo, viene interpretato in relazione all’URI del Content-Base, se invece non è
presente un header Content-Base, l’URI viene interpretato relativamente al Request-URI.
L’header Content-Type indica il tipo di dati inviati nell’entità del messaggio (in genere una
risposta). Il tipo di dati inviato in un messaggio deve essere tra quelli comprensibili per il
"Content-Type" ":" media-type
destinatario, il quale li specifica tramite l’header Accept inviato con la richiesta. La sintassi e:
Un esempio di media-type e “application/sdp”, con cui si indica che il corpo-entità del
messaggio trasporta una descrizione di sessione secondo il protocollo SDP.
4.2.7 Request Header.
In questo gruppo sono compresi:
Accept;
Accept-Encoding;
Accept-Language;
Authorization;
From;
If-Modified-Since;
Range;
Referer;
User-Agent.
Questi header sono utilizzati esclusivamente nelle richieste, eccetto l’header Range che può essere
usato anche nelle risposte.
Come nei casi precedenti il parser della classe RequestHeader li riconosce tutti, questa
implementazione utilizza quelli descritti di seguito.
L’header Accept può essere utilizzato per specificare quale tipologie di descrizioni di sessione
sono accettabili nella risposta ad una richiesta contenente questo header. Un esempio è:
Accept: application/rtsl, application/sdp
L’header Range specifica un intervallo di tempo. Questo intervallo può essere specificato in tre
diversi formati : smpte, npt e clock. L’ RtspServer e l’ RtspClient utilizzano il formato
npt. Quando Range viene utilizzato in una risposta, indica quale intervallo di tempo è
correntemente in fase di riproduzione o di registrazione. Inoltre possono essere usati intervalli aperti
a destra. Il corpo del’header può contenere un campo nel formato UTC, con cui si specifica
l’istante di tempo dal quale l’operazione relativa dovrà essere effettivamente eseguita. La sintassi è:
Dove i ranges-specifier sono descritti nel paragrafo 4.2.1.
"Range" ":" 1\#ranges-specifier[ ";" "time" "=" utc-time ]
ranges-specifier = npt-range | utc-range | smpte-range
Per la complessità dell’operazione di parsing, questo header è stato implementato nella classe
apposita Range.
4.2.8 Response Header.
In questo gruppo sono compresi:
Location;
Proxy-Authenticate;
Public;
Retry-After;
Server;
Vary;
WWW-Authenticate.
Sono utilizzati per consentire al destinatario di una richiesta di fornire nella risposta informazioni
addizionali, che non potrebbero essere inserite nella Status-Line. Queste informazioni
riguardano il server e ulteriori accessi alla risorsa identificata dal Request-URI.
In questa implementazione si utilizza solo l’header Location, utilizzato per redirigere il
ricevente ad un indirizzo diverso dal Request-URI, per poter completare la richiesta o
l’identificazione di una risorsa. La classe ResponseHeader si occupa del parsing di questo gruppo
di header.
4.2.9 Header di richiesta e risposta.
Il parsing di questi header viene effettuato in entrambe le classi RtspRequest ed RtspResponse.
Transport Header
Questo header, utizzato sia nelle richieste che nelle risposte, è fondamentale per il client ed il server
nel realizzare la contrattazione ed il setup dei parametri di una sessione RTSP.
Siccome è caratterizatto da una sintassi complessa per il suo parsing è stata realizzata una classe
apposita detta appunto TransportHeader.
La sintassi di questo header è:
Transport
transport-spec
transport-protocol
profile
lower-transport
parameter
ttl
port
ssrc
channel
address
mode
= "Transport" ":"
1\#transport-spec
= transport-protocol/profile[/lower-transport]
*parameter
= "RTP"
= "AVP"
= "TCP" | "UDP"
= ( "unicast" | "multicast" )
| ";" "destination" [ "=" address ]
| ";" "interleaved" "=" channel [ "-" channel ]
| ";" "append"
| ";" "ttl" "=" ttl
| ";" "layers" "=" 1*DIGIT
| ";" "port" "=" port [ "-" port ]
| ";" "client_port" "=" port [ "-" port ]
| ";" "server_port" "=" port [ "-" port ]
| ";" "ssrc" "=" ssrc
| ";" "mode" = <"> 1\#mode <">
= 1*3(DIGIT)
= 1*5(DIGIT)
= 8*8(HEX)
= 1*3(DIGIT)
= host
= <"> *Method <"> | Method
Parametri generali:
unicast | multicast: indica in maniera mutuamente esclusiva se il trasporto dei dati
deve essere unicast o multicast. Il valore predefinito è multicast.
destination: indica l’ndirizzo a cui devono essere spediti gli stream.
source: è utilizzato per specificare l’indirizzo da cui gli stream provengono, se differisce da
quello dei pacchetti RTSP (il server in caso di playback, il client in caso di recording).
layers: indica il numero di strati multicast usati per gli stream.
mode: indica i metodi supportati per la sessione. I valori possibili sono “PLAY” e
“RECORD”; se non specificato si assume il valore “PLAY”.
append: se il parametro mode include il valore “RECORD”, questo parametro indica che i
dati dei media devono essere accodati a quelli della risorsa esistente sul server anziché
sovrascriverli.
interleaved: indica che i dati dei media devono essere interlacciati con quelli del flusso
di controllo.
Parametri specifici per il multicast:
- ttl: multicast time-to-live
Parametri specifici per l’RTP:
port: questo parametro fornisce la coppia di porte per l’ RTP/RTCP, nel caso di una
sessione multicast. Viene specificato come un intervallo.
client_port:
questo parametro fornisce la coppia di porte RTP/RTCP, nel caso di
trasmissione unicast, su cui il client ha scelto di ricevere i dati del media e le relative
informazioni di controllo. Viene specificato come un intervallo.
-
server_port: questo parametro è il complementare del precedente per il server.
ssrc:
indica l’ SSRC dei pacchetti RTP che il server userà (risposta) oppure quello che il
client vorrebbe (richiesta).
Un Transport Header descrive un singolo stream RTP (RTSP può controllare stream
multipli come una singola entità).
Session Header
Identifica una sessione RTSP dal momento in cui viene inizializzata dal server in risposta ad una
richiesta di SETUP, fino a quando viene chiusa da una TEARDOWN. L’identificatore di sessione
viene scelto dal server; quando il client lo riceve, dovrà utilizzarlo sempre in tutte le richieste
"Session" ":" session-id [ ";" "timeout" "=" delta-seconds ]
relative a quella sessione. La sintassi è:
Il parametro timeout è utilizzabile dal server solo nelle risposte, per indicare per quanto tempo
attenderà tra un comando RTSP e il successivo prima di chiudere automaticamente la sessione, per
mancanza di attività del client. Qesto parametro è misurato in secondi, e il valore predefinito è pari
a 60 secondi.
Un singolo session-id può essere utilizzato per controllare stream multipli appartenenti alla
stessa sessione. Se un client apre più sessioni per uno stesso URL, dovrà usare un session-id
diverso per ogni sessione.
CSeq Header
Specifica il numero di sequenza per una coppia richiesta-risposta RTSP. E’ presente in tutte le
richieste e risposte: per ogni richiesta con un certo numero di sequenza deve esistere una risposta
"CSeq" ":" 1# ( DIGIT )
con lo stesso numero.
La sintassi è:
4.2.10 Riassunto degli Header.
La tabella seguente riassume gli header usati dal RTSP. Il tipo “g” indica un general header
utilizzabile sia nelle richieste che nelle risposte; il tipo “R” indica i request header; il tipo “r” indica
i response header; il tipo “e” gli entity header. Gli header contrassegnati con “req.” nella colonna
etichettata “support” devono essere implementati necessariamente, mentre quelli marcati con “opt.”
sono opzionali. Gli header contrassegnati con “u” sono quelli effettivamente usati in questa
implementazione, mentre è stato comunque implementato il parsing di tutti.
Inoltre sono indicati i metodi per i quali ogni header è significativo.
4.3 Dettagli implementativi.
Header
type
Accept
R
Accept-Encoding
R
Accept-Language
R
Allow
r
Authorization
R
Bandwidth
R
Blocksize
R
Cache-Control
g
Conference
R
Connection
g
Content-Base
e
Content-Encoding
e
Content-Encoding
e
Content-Language
e
Content-Length
e
Content-Length
e
Content-Location
e
Content-Type
e
Content-Type
r
CSeq
g
Date
g
Expires
e
From
R
If-Modified-Since
R
Last-Modified
e
Proxy-Authenticate
Proxy-Require
R
Public
r
Range
R
Range
r
Referer
R
Require
R
Retry-After
r
RTP-Info
r
Scale
Rr
Session
Rr
Server
r
Speed
Rr
Transport
Rr
Unsupported
r
User-Agent
R
Via
g
WWW-Authenticate
r
support
opt.
opt.
opt.
opt.
opt.
opt.
opt.
opt.
opt.
req.
opt.
req.
req.
req.
req.
req.
opt.
req.
req.
req.
opt.
opt.
opt.
opt.
opt.
req.
opt.
opt.
opt.
opt.
req.
opt.
req.
opt.
req.
opt.
opt.
req.
req.
opt.
opt.
opt.
u
u
u
u
u
u
u
u
u
u
u
u
u
methods
entity
entity
all
all
all
all
all but OPTIONS, TEARDOWN
SETUP
SETUP
all
entity
SET_PARAMETER
DESCRIBE, ANNOUNCE
DESCRIBE, ANNOUNCE
SET_PARAMETER, ANNOUNCE
entity
entity
SET_PARAMETER, ANNOUNCE
entity
all
all
DESCRIBE, ANNOUNCE
all
DESCRIBE, SETUP
entity
all
all
PLAY, PAUSE, RECORD
PLAY, PAUSE, RECORD
all
all
all
PLAY
PLAY, RECORD
all but SETUP, OPTIONS
all
PLAY
SETUP
all
all
all
all
4.3.1 Il server RTSP.
Il server RTSP, realizzato con la classe RtspServer, implementa la semantica del protocollo dal
lato server.
Si tratta di un server “a stati”, a differenza di un server HTTP, meccanismo necessario per
implementare una “memoria temporale” degli eventi che scandiscono il suo funzionamento.
Gli eventi che provocano le transizioni di stato, con la relativa esecuzione di azioni opportune, sono
generati dai messaggi di richiesta provenienti da un client. I metodi(par 4.2.3) di questi
messaggi ne costituiscono la “tipizzazione”, e impongono le transizioni di stato al server.
La figura rappresenta l’automa a stati del server.
Recording
PLAY’
Init
RECORD
SETUP
TEARDOWN
PAUSE
Ready
TEARDOWN
Terminated
PLAY
PAUSE
RECORD’
Playing
TEARDOWN
RECORD’ e PLAY’ avvengono solo durante un tunnelling
Figura 4.1: Automa del server e del client RTSP
A seguito di un messaggio di richiesta, il server esegue una serie di controlli, necessari per
verificare la consistenza e la soddisfacibilità della richiesta, quindi cerca di soddisfarla. Se tutto va a
buon fine, risponde al client con un messaggio di risposta positivo (status code 200),
altrimenti la risposta contiene il codice di errore opportuno, indicante al client la causa
dell’insoddisfacibilità della sua richiesta. Alcuni errori sono gestiti automaticamente dal client,
mentre altri sono notificati all’utente umano, che può quindi decidere le azioni da intraprendere per
risolvere l’errore, se è possibile.
Il funzionamento del server è organizzato e gestito basondolo sul concetto di “sessione”. Una
sessione, in quanto tale, esiste sotto forma di istanza della classe ServerSession. Su un host su cui
viene eseguito un server RTSP, possono esistere contemporaneamente più sessioni attive. Ogni
sessione può gestire contemporaneamente vari flussi di dati multimediali. Le sessioni si distinguono
in:
• “aggregate”, quando i vari media sono semanticamente correlati, quindi ogni richiesta
proveniente da un client, deve riferlirli come un tutt’uno (tranne nei SETUP), e quindi la loro
gestione è demandata ad un unico porcesso RtspServer;
• “non aggregate”, quando i vari media non sono necessariamente correlati, quindi un client deve
effettuare richieste separate per ogni media, e la gestione di ognuno di loro è affidata ad un
processo RtspServer diverso. La necessità di usare un processo server per ogni media deriva
dal funzionamento “a stati” dei server RTSP: quindi un media potrebbe essere in fase di
riproduzione, mentre un altro potrebbe ancora essere nella fase di inizializzazione.
La classe SessionManager si occupa della gestione delle sessioni, mettendo a disposizione del
processo server i seguenti servizi:
• crea una nuova sessione, quando un client la richiede;
• verifica se un client può essere inserito in una sessione esistente;
• risponde negativamente ad un client che cerca di inserirsi in una sessione gestita da un altro
client, che non l’abbia abbandonata disconnetendosi, oppure passandone espicitamente il
controllo;
• gestisce l’assegnazione delle porte per la creazione dei vari socket unicast e multicast, evitando
conflitti tra i vari processi server;
• gestisce il database dei file contenenti i dati multimediali, mantenendo un indice nel file
streamindex.dat dei vari media stream disponibili;
• genera automaticamente i file in formato SDP, per mantenere la descrizione delle nuove sessioni
registrate;
• gestisce la chiusura delle sessioni, causate da problemi di connessione su rete, oppure per errori
interni;
• utilizza un file (server.prop) personalizzabile, utile per inizializzare le proprietà dei server
RTSP, (path, timeout, maxSessionNumber, ecc.).
• gestisce gli accessi concorrenti dei vari processi server al file streamindex.dat, tramite un
monitor basato sull’algotitmo “lettori-scrittori” implementato nella classe IndexFileManager,
in cui si dà maggiore priorità ai processi “scrittori”, per rendere disponibili le modifiche
dell’elenco delle sessioni il più presto possibile.
Quando sull’host server non esiste nessun oggetto RtspServer attivo, resta in esecuzione un thread
demon (processo demone), istanza della classe RtspDemon, il quale attende su un ServerSocket,
alla porta 554, le connessioni provenienti dai client. Nel momento in cui un client apre una
connessione TCP con questo demon, esso crea una istanza della classe RtspServer, anch’essa un
thread, passandogli il socket TCP con cui comunicare col client, e ne fa partire l’esecuzione. Quindi
il demon ritorna in attesa di altri client sul suo socket.
Il server inizialmente è nello stato di Init, in cui può accettare solo tre tipi di richieste:
DESCRIBE, ANNOUNCE e SETUP.
DESCRIBE
Il client usa questo metodo per ottenere una descrizione completa della risorsa, identificata tramite
l’URL nella richiesta. In genere il client richiede un DESCRIBE per poter inizializzare il playback
di una sessione. Nella decrizione il server include tutte le informazioni necessarie per permettere al
client di ricevere i flussi dei media componenti la presentazione o sessione multimediale.
Il client indica nella richiesta, tramite l’header Accept, il tipo di descrizione che riesce ad
interpretare. Questa implementazione utilizza il protocollo SDP per descrivere le sessioni. Se
l’header Accept non contiene un formato di cui il server dispone, esso risponde con un messaggio
contenente il codice d’errore 451 (Parameter Not Understood). Il server ricerca nel suo file system il
file contente la descrizione nel formato SDP. Questi file hanno il nome formato dal prefisso “SDP“, a cui segue il nome della sessione. Se la sessione è disponibile, il server individua il file
contenente la descrizione in formato SDP, quindi con il contenuto costruisce il corpo della risposta
al DESCRIBE.
Se il sever non trova il file “SDP-<nome sessione>”, risponde con un messaggio contenente il
codice di errore 404 (Not Found).
Un esempio di DESCRIBE e relativa risposta è:
C->S: DESCRIBE rtsp://lis3.deis.unical.it/Lecture4/Part1 RTSP/1.0
CSeq: 312
Accept: application/sdp, application/rtsl, application/mheg
S->C: RTSP/1.0 200 OK
CSeq: 312
Date: 7 Nov 1998 15:35:06 GMT
Content-Type: application/sdp
Content-Length: 376
v=0
o=vincenzo.c 2890844526 2890842807 IN IP4 194.243.119.72
s=SDP Seminar
i=Lecture on Java Concurrency
u=http://www.telsa.it/~V.Ciminelli
[email protected] (Vincenzo Ciminelli)
c=IN IP4 224.2.17.12/127
t=2873397496 2873404696
m=audio 3456 RTP/AVP 0
m=video 2232 RTP/AVP 31
Se nell’URL del DESCRIBE il nome di sessione è costituito da un “*”,
[es.: DESCRIBE rtsp://lis3.deis.unical.it/* RTSP/1.0] il server risponderà
inviando nel corpo della risposta l’elenco di tutte le sessioni di cui dispone. Questo elenco è
ricavato dal file streamindex.dat contenente la lista di tutti i media stream disponibili sul server,
oltre ad ulteriori informazioni su ogni stream. Questo è implementato tramite il metodo
DescribeAll invocato dal metodo Describe stesso. Da questo elenco il client sceglie la sessione
che desidera, di cui può quindi richiedere il DESCRIBE specifico.
ANNOUNCE
Il client usa questo metodo quando vuole registrare sul server una nuova sessione, per informarlo di
tutti i dettagli riguardanti la sessione, necessari per eseguirne con successo la registrazione. Il corpo
dell’ANNOUNCE contiene la descrizione in formato SDP, come nel caso del DESCRIBE. Se il
client invia un formato di descrizione diverso, il server risponderà con un messaggio contenente il
codice di errore 406 (Not Acceptable).
Se tutto va a buon fine, il server conserverà la descrizione della sessione in una variabile opportuna,
che userà per le operazioni successive.
C->S: ANNOUNCE rtsp://lis3.deis.unical.it/Lecture4/Part2 RTSP/1.0
CSeq: 312
Date: 8 Jan 1998 15:35:06 GMT
Session: 47112344
Content-Type: application/sdp
Content-Length: 376
v=0
o=vincenzo.c 2890844526 2890842807 IN IP4 194.243.119.72
s=SDP Seminar
i=Lecture on Java Threads
u=http://www.telsa.it/~V.Ciminelli
[email protected] (Vincenzo Ciminelli)
c=IN IP4 224.2.17.12/127
t=2873397496 2873404696
m=audio 3456 RTP/AVP 0
m=video 2232 RTP/AVP 31
S->C: RTSP/1.0 200 OK
CSeq: 312
Un esempio di ANNOUNCE è:
SETUP
Il client, dopo aver ottenuto la descrizione di una sessione con un DESCRIBE, oppure averla fornita
al server con un ANNOUNCE, deve inviare una richiesta di SETUP per ogni media stream
compreso nella sessione di cui vuole fare il playback o il recording.
Il server può funzionare nei seguenti modi:
1. riproduzione di una sessione in unicast verso il client;
2. riproduzione di una sessione verso un gruppo multicast;
3. registrazione di una sessione inviata dal client in unicast;
4. registrazione di una sessione da un gruppo multicast;
5. tunnelling di una sessione da un gruppo multicast verso un client capace di comunicare solo in
unicast.
Tramite un SETUP il client comunica al server le informazioni necessarie per inizializzare le
connessioni su cui verranno inviati i pacchetti contenenti i dati, ed il tipo di funzionamento
desiderato tra quelli appena elencati. L’header principale utilizzato nel SETUP è il TransportHeader, tramite il quale il client comunica al server le seguenti informazioni:
• tipo di protocollo di trasporto dati multimediali (es. RTP);
• tipo di trasporto (TCP, UDP, ecc.);
• tipo di sessione: unicast, multicast;
• indirizzo del gruppo multicast a cui il server deve trasmettere o da cui deve ricevere i dati;
• le porte su cui il client attende i dati (unicast), oppure le porte del gruppo multicast su cui il
server deve trasmettere o da cui deve ricevere i dati;
• il tipo di sessione (PLAY o RECORD).
Ricevuto un SETUP, il server comincerà col verificare la presenza di un Transport-Header:
se manca risponde con un codice di errore 400 (“Bad Request”). Quindi stabilisce il tipo di sessione
richiesta: PLAY o RECORD. Se il client richiede il RECORD di uno stream esistente nel file
system del server, questo accetta se il RECORD deve essere fatto appendendo in coda al file i nuovi
dati, rifiuta con un codice di errore 406 (“Not Acceptable”) se il client richiede la sovrascrittura del
file.
Se la richiesta è un PLAY, il server verifica se dispone del file contenente il media stream richiesto.
Se così non è, risponde con un codice di errore 404 (“File Not Found”).
Dopo queste verifiche, il server controlla la presenza di un header Session, con cui il client può
indicare una sessione già attiva sull’host del server. Se il SETUP contiene questo header, il server
cerca di inserire la gestione di questo stream nella sessione richiesta dal client, se ciò non è possibile
risponde con un codice di errore 454 (“Session Not Found”). Se il SETUP non contiene un header
Session il client vuole inizializzare una nuova sessione, quindi il server la crea, generando un
session ID, che inserisce in un header Session nella risposta : da questo momento il client deve
usare sempre un header Session con questo session ID in tutte le richieste successive rivolte a
questa sessione, altrimenti il server, non riconoscendo la sessione, risponderà con un codice di
errore 454.
Dopo queste verifiche preliminari, il server interpreta il contenuto del Transport Header, nel
metodo getTransportHeader, in cui il server riconosce il tipo di funzionamento richiesto dal
client, e quindi prepara le informazioni necessarie da passare al sottosistema che si occupa del
trattamento dei dati multimediali4. Nella tabella è riassunta la semantica adottata per questa
operazione:
O. U.
D. U.
O. M. D. M. O. U.
D. M.
Sessione di Playback dal
PLAY
server al client
Non definito
(errore 406)
Playback dal
server al gruppo
Multicast.
Sessione di Recording dal
RECORD client al server
Non definito
(errore 406)
Non definito
(errore 406)
O. M.
D. U.
Tunnelling dal
gruppo Multicast
al
Client.
Tunnelling(1)
con
Recording dal
gruppo Multicast
sul server
O.=Origine; D.=Destinazione; U.=Unicast; M.=Multicast
(1) Il tunnelling viene attivato se la destinazione corrisponde all’indirizzo del client.
L’origine e la destinazione sono i due parametri Source e Destination del Transport
Header, contenenti gli indirizzi multicast del gruppo da cui provengono o a cui devono essere
trasmessi i dati dei media stream. La presenza contemporanea di questi due parametri non è
supportata, e provoca una risposta del server contenente il codice di errore 406 (“Not Acceptable;
Incoherent Transport Header”).
Quando l’origine o la destinazione non sono indicati, il server assume i valori predefiniti:
4
Questo sottosistema è descritto nel capitolo 5.
Origine
predefinita
Destinazione
Predefinita
Sessione di
PLAY
Indirizzo del
Server
Indirizzo del
Client
Sessione di
RECORD
Indirizzo del
Client
Indirizzo del
Server
Ovviamente il client deve indicare le porte relative all’indirizzo su cui egli deve trasmettere i media
stream, o da cui li deve ricevere. Le informazioni sulle porte possono essere ricavate dall’SDP se si
tratta di una sessione multicast, ma il client, se vuole, le può modificare e comunicarle al server
proprio nel Transport Header.
La tabella seguente riporta, per i vari modi di funzionamento, i parametri di porta scambiati tra
client e server:
O.U.
D.U.
O.M.
D.M.
O.U.
D.M.
O.M. D.U.
Sessione di
PLAY
Client-port
Server-port
Non definito
(errore 406)
Multicast
Port
Client-port
Server-port
Multicast port
Sessione di
RECORD
Client-port
Server-port
Non definito
(errore 406)
Non definito
(errore 406)
Multicast port
Client Port(1)
O.=Origine; D.=Destinazione; U.=Unicast; M.=Multicast
(1) Specificata in caso di tunnelling
La “Multicast port” corrisponde al parametro port del Transport Header. In una sessione
unicast, se il server rileva che sul suo host le porte specificate dal client generano conflitti, inizia
con questo una contrattazione, proponendo nella risposta al client un nuovo set di porte che non
generano conflitti: se il client le accetta, le operazioni proseguono, altrimenti quest’ultimo può
proporne delle altre in un nuovo SETUP. La contrattazione prosegue fino a quando i due non
raggiungono un accordo. Tutta la contrattazione è trasparente all’utente.
Quando il server ed il client dispongono di tutti i parametri, il primo crea il processo che si occupa
della trasmissione o della registrazione dei flussi multimediali, il secondo crea i processi che si
occuperanno del “rendering” dei flussi multimediali (VIC per il video e VAT per l’audio), per
l’utente.
Un esempio di SETUP è:
C->S: SETUP rtsp://lis3.deis.unical.it/Lecture1/video RTSP/1.0
CSeq: 302
Transport: RTP/AVP;unicast;client_port=4588-4589
S->C: RTSP/1.0 200 OK
CSeq: 302
Date: 23 Jan 1997 15:35:06 GMT
Session: 47112344
Transport: RTP/AVP;unicast;client_port=4588-4589
Alla fine di un SETUP che ha avuto successo, il server ed il client cambieranno il loro stato, da
Init a Ready.
In questo stato il server attende le richieste del client che possono essere: PLAY (per una sessione
di playing), RECORD (per una sessione di recording), TEARDOWN.
PLAY
Il client invia una richiesta di questo tipo quando vuole che il server cominci ad inviare i flussi
multimediali, secondo le specifiche di inizializzazione impostate nel SETUP.
Se la sessione è di tipo aggregato, il client deve inviare un solo PLAY per richiedere la trasmissione
di tutti i media stream che la compongono. Quindi l’URL della richiesta di PLAY deve contenere
nel path solo il riferimento al nome della sessione, altrimenti il server risponde con un codice di
errore 460 ("Only Aggregate Operation Allowed").
Se la sessione è di tipo non aggregato, il client deve invece inviare un messaggio di PLAY per ogni
media stream che la compone. In tal caso l’URL di ogni PLAY deve contenere nel path il
riferimento ad uno specifico media stream, altrimenti il server risponde con un codice di errore 459
("Aggregate Operation Not Allowed"). Il server effettua questi controlli anche per tutti i metodi
successivi.
Se si tratta del primo PLAY di una sessione, il server inizia la riproduzione dei media dall’inizio; se
invece si tratta di un PLAY seguente un messaggio di PAUSE, il server riprende la riproduzione dal
punto in cui era stata sospesa.
Se la sessione è di tipo aggregato, è disponibile la funzione di accesso casuale (seeking) all’interno
dei media stream: il client può richiedere di far ripartire la riproduzione da un istante qualsiasi,
indicandolo con un header Range nel messaggio di PLAY. Siccome i dati multimediali
digitalizzati sono discreti per la loro stessa natura, il server eseguirà il riposizionamento della
riproduzione all’istante di tempo all’interno degli stream, che più approssima quello richiesto.
Informa il client dell’esatto istante da cui ripartirà la riproduzione, indicandolo in un header Range
inserito nella risposta al PLAY.
Un esempio di questo tipo di richiesta è:
C->S: PLAY rtsp://lis3.deis.unical.it/Lecture1/video RTSP/1.0
CSeq: 835
Session: 12345678
Range: npt=9.6S->C: RTSP/1.0 200 OK
CSeq: 835
Date: 7 Nov 1998 15:35:06 GMT
Range: npt=10-
Dopo una richiesta di PLAY riuscita, sia il server che il client effettuano una transizione nello stato
Playing.
RECORD
Il client usa questo messaggio per chiedere al server di iniziare a registrare i media stream della
sessione appena inizializzata tramite la fase di SETUP.
In genere il client deve informare il server riguardo la sessione da registrare tramite un messaggio di
ANNOUNCE, che deve precedere la fase dei SETUP.
Il server fa partire la registrazione dopo aver effettuato gli opportuni controlli sull’URL del
messaggio di RECORD (come nel caso del PLAY).
C->S: RECORD rtsp://lis3.deis.unical.it/Lecture2/video RTSP/1.0
CSeq: 954
Session: 12345678
S->C: RTSP/1.0 200 OK
CSeq: 954
Session: 12345678
Un esempio di RECORD è:
Dopo una richiesta di RECORD riuscita, sia il server che il client effettuano una transizione nello
stato Recording.
PAUSE
Il client usa questo messaggio per chiedere al server una pausa nella riproduzione o nella
registrazione della sessione.
Il server, effettuati i controlli sull’URL, richiede al sottosistema di playback o recording di
effettuare la pausa. Se la sessione è aggregata, il server indica al client, in un header Range nella
risposta, l’esatto istante negli stream al quale la riproduzione è stata fermata. Questa indicazione
non è data nel caso di registrazione, o di sessione non aggregata.
C->S: PAUSE rtsp://lis3.deis.unical.it/Lecture1/video RTSP/1.0
CSeq: 201
Session: 12345678
S->C: RTSP/1.0 200 OK
CSeq: 201
Session: 12345678
Range:npt=0:12:43-
Un esempio di PAUSE è:
Dopo un PAUSE riuscito, sia il server che il client effettuano una transizione nello stato Ready.
SET_PARAMETER
Questo metodo può essere usato per assegnare dei valori ad opportuni parametri riferiti ad una
sessione o ad un singolo media stream.
Per il momento questo metodo è utilizzato dal client per ottenere che il server tratti sessioni di tipo
aggregato come se fossero di tipo non aggregato. Questa funzionalità è utile quando un client vuole
ricevere solo un sottoinsieme (proprio) dei media componenti la sessione. Infatti, secondo l’ RTSP
standard, il server determina tramite la descrizione SDP a sua disposizione se trattare la sessione
come aggregata o meno. Quindi se una sessione è stata registrata come aggregata, il client deve
accettarla come tale, e ricevere tutti gli stream che la compongono. Invece, in questa
implementazione di RTSP, il client ha la facoltà di decidere il tipo della sessione, tramite
l’impostazione del parametro force_not_aggregate_session in un SET-PARAMETER.
Un esempio di utilizzo di questo metodo è:
C->S: SET_PARAMETER rtsp://lis3.deis.unical.it/Lecture1 RTSP/1.0
CSeq: 421
Content-length: 20
Content-type: text/parameters
force_not_aggregate_session
S->C: RTSP/1.0 200 OK
Se il server riceve un SET_PARAMETER con un parametro sconosciuto, risponde con il codice di
errore 451 ("Parameter Not Understood").
Si comprende che questo client resta comunque compatibile con l’RTSP standard, in quanto se
chiedesse ad un server RTSP diverso da quello implementato, di trattare una sessione aggregata
come se non lo fosse, riceverebbe in risposta semplicemente il codice di errore 451, senza
provocare nessun tipo di problema.
Un SET_PARAMETER non provoca nessuna transizione di stato né del server né del client.
GET_PARAMETER
Questo metodo può essere usato per chiedere informazioni sul valore di parametri del server o del
client.
In questa implementazione è utilizzato dal client per chiedere il tempo di durata di una sessione, di
cui sta richiedendo la riproduzione. Per quanto riguarda la compatibilità con l’RTSP standard
valgono le considerazioni fatte nel caso del SET_PARAMETER.
C->S:GET_PARAMETER rtsp://lis3.deis.unical.it/Lecture1/video RTSP/1.0
CSeq: 421
Content-length: 16
Content-type: text/parameters
session_duration
S->C:RTSP/1.0 200 OK
CSeq: 421
30
C->S:Content-length:
OPTIONS * RTSP/1.0
Content-type:
text/parameters
CSeq: 1
S->C:session_duration:npt=01:05:00RTSP/1.0 200 OK
CSeq: 1
Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, RECORD,
PASS, CONTINUE, ANNOUNCE
Un esempio di GET_PARAMETER è:
Un GET_PARAMETER non provoca nessuna transizione di stato né del server né del client.
OPTIONS
Il server implementa questo metodo per rispondere ad un client che voglia sapere quali metodi
supporta. Il server nella risposta inserisce un header Public con l’elenco dei metodi da esso
supportati.
Un esempio è:
Un OPTION non influenza lo stato né del client né del server.
TEARDOWN
Questo messaggio è utilizzato dal client per chiedere la chiusura di una sessione:
se la sessione è aggregata basta un solo messaggio di questo tipo; altrimenti il client deve chiedere il
TEARDOWN per ogni media stream.
Il server chiude la sessione e si disconnette dal client. Se la sessione è di registrazione, il server
aggiorna il file indice streamindex.dat, inserendo per ogni media stream il suo percorso e il nome
del file in formato SDP che descrive la sessione a cui appartiene.
Il server libera le risorse di sistema occupate per la sessione chiudendo i processi costituenti il
sottosistema di trattamento dei flussi di dati, tutti i socket occupati, e quindi termina la sua
esecuzione eliminando dal sistema se stesso in quanto thread.
Un esempio di TEARDOWN è:
Se durante la sessione capita che il server perde la connessione con il client, il primo non chiude
immediatamente la sessione, ma va in uno stato di attesa, per un tempo pari al timeout predefinito
nel file server.prop dal gestore del sistema su cui funziona il server RTSP. Se il client resce a
riaprire la connessione prima dello scadere del timeout, il server ritorna in attività. Durante il
timeout la sessione continua a rimanere nello stato in cui era nel momento della sospensione. Se
scade il timeout, il server chiude la sessione, e libera le risorse occupate sul sistema. In caso di
fallimento per timeout di una sessione di registrazione, il server non elimina gli stream registrati
fino a quel momento, ma registra nel file streamindex.dat il fallimento della sessione (indicandolo
a fianco di ogni media stream con la dicitura “RECORDING_ERROR”). Sarà cura del gestore del
sistema su cui funziona il server, decidere di rimuovere gli stream di quella sessione, o renderli
comunque disponibili, rimuovendo l’indicazione di errore all’interno del file streamindex.dat.
Il meccanismo di “fault tollerance” con timeout è sfruttato anche per implementare una estensione
del protocollo RTSP tramite due nuovi metodi: PASS e CONTINUE.
4.3.2 Il client RTSP.
Il client RTSP è implementato tramite le due classi RtspClient ed RtspReceive (package
rtsp.client) che lavorano in coppia.
La classe RtspReceive è un thread utilizzato esclusivamente per gestire le comunicazioni TCP con
il server. Si occupa solo di trasmettere i messaggi di richiesta costruiti nel sul socket TCP e
riceverne le risposte. La semantica del client è implementata nella classe RtspClient, le cui istanze
sono create nell’ambito del sottosistema che gestisce l’interfaccia utente. Ogni istanza di questa
classe mette a disposizione dell’interfaccia utente i seguenti servizi:
• creazione e gestione dei socket TCP per le comunicazioni col server RTSP (delegata alla
relativa istanza della RtspReceive;
• costruzione dei messaggi di richiesta da inviare al server, partendo dall’interazione dell’utente
con l’interfaccia grafica del sistema client5. La classe RtspClient contiene tanti metodi quanti
sono quelli descritti nel precedente paragrafo sul server RTSP (oltre ad altri metodi privati).
L’interfaccia grafica interpreta le richieste dell’utente e le traduce in opportune chiamate verso
questi metodi. L’effetto finale è quello di trasmettere gli opportuni messaggi di richiesta verso il
server, ed ottenere quindi il controllo remoto della sessione multimediale.
• contrattazione automatica con il server delle porte dei socket che creano conflitti;
• parsing dei messaggi di risposta del server, e presentazione dei messaggi di errore.
In questa implementazione è previsto un meccanismo di filtraggio di alcuni messaggi di errore del
server, come quelli derivanti dai conflitti sulle porte, ma la maggior parte degli altri messaggi
vengono tipizzati con il meccanismo delle eccezioni di JAVA, e passati al sistema di interfaccia
utente, che si occupa della loro visualizzazione. Sono affidate all’utente umano le decisioni in
C->S: TEARDOWN rtsp://lis3.deis.unical.it/Lecture1/video RTSP/1.0
CSeq: 900
Session: 12345678
S->C: RTSP/1.0 200 OK
CSeq: 900
5
L’interfaccia grafica del sistema client implementato è descritta nel capitolo 5.
merito alla soluzione dei problemi indicati da questi messaggi (descritti nel paragrafo sul server
RTSP per ogni metodo).
4.3.3 “RTSP+”
In questa implementazione di RTSP sono stati introdotti due metodi nuovi: PASS e CONTINUE.
Questo è stato fatto come primo passo verso la realizzazione di un meccanismo di collaborazione
client-client6, in cui un client, creatore di una sessione, può condividerne il controllo con altri client.
PASS
Questo metodo è utilizzato da un client per cedere il controllo di una sessione ad un altro client.
Quando il server riceve una richiesta di PASS, invia un messaggio di risposta (200 OK) al client;
quindi chiude la connessione TCP; infine entra in uno stato di attesa con timeout, similmente a
come è stato descritto nel paragrafo sulla TEARDOWN, riguardo alla “fault tolerance”. Il server
rimane in attesa di un messaggio di CONTINUE fino allo scadere del timeout. Se il timeout scade il
server chiude la sessione e libera le risorse occupate. Un esempio di PASS:
C->S: PASS rtsp://lis3.deis.unical.it/Lecture1/video RTSP/1.0
CSeq: 900
Session: 12345678
S->C: RTSP/1.0 200 OK
CSeq: 900
C->S: CONTINUE rtsp://lis3.deis.unical.it/Lecture1/video RTSP/1.0
CSeq: 900
Session: 12345678
S->C: RTSP/1.0 200 OK
CSeq: 900
CONTINUE
Questo metodo è legato al precedente, essendo utilizzato da un client per guadagnare il controllo di
una sessione che era stato ceduto in precedenza con una PASS. Il messaggio CONTINUE deve
contenere nell’header Session il session ID esatto per la sessione che si vuole controllare,
altrimenti il server respinge la richiesta, rispondendo con un codice di errore 454 ("Session Not
Found").
Se la CONTINUE ha successo, il nuovo client guadagna il controllo della sessione richiesta, che
potrà a sua volta cedere con una PASS. Un esempio di CONTINUE:
6
Di quest’argomento si parla più estesamente nel capitolo “Conclusioni e sviluppi futuri”.