# Automatic repeat request

Nei sistemi di telecomunicazioni, Automatic Repeat-reQuest è una strategia di controllo di errore, che svolge il compito di rivelare un errore (ma non di correggerlo). I pacchetti corrotti vengono scartati e viene richiesta la loro ritrasmissione.

## Definizioni

Affinché il sistema sia capace di riconoscere i messaggi corrotti è necessario che questi vengano preliminarmente codificati da un codificatore. Dopo la trasmissione il decodificatore decodifica il messaggio e, a seconda che questo sia integro o meno, si comporta in base a uno dei 3 diversi protocolli più comuni:
* Stop-and-wait: il mittente invia un messaggio e attende dal destinatario una conferma positiva (ACK, acknowledge), negativa (NACK, contrazione di negative acknowledge) o un comando; se scade il tempo di attesa (time-out) per uno di questi tre, il mittente provvederà a rispedire il pacchetto e il destinatario si incaricherà di scartare eventuali repliche. Nel caso in cui si verificasse un errore nella trasmissione del segnale di conferma (ACK), il mittente provvederà a rinviare il pacchetto; il destinatario riceverà in questo modo una copia del pacchetto già ricevuto, credendo che gli sia pervenuto un nuovo pacchetto. Per ovviare a questo problema si può procedere numerando i pacchetti trasmessi, ovvero inserendo un bit di conteggio.
* Go-Back-N: il mittente dispone di un buffer dove immagazzina N pacchetti da spedire, man mano che riceve la conferma ACK svuota il buffer e lo riempie con nuovi pacchetti; nell'eventualità di pacchetti persi o danneggiati e scartati avviene il reinvio del blocco di pacchetti interessati. I pacchetti ricevuti dal destinatario dopo quello scartato vengono eliminati.
* Selective Repeat: in questo caso anche il destinatario dispone di un buffer dove memorizzare i pacchetti ricevuti dopo quello/quelli scartati; quando i pacchetti interessati vengono correttamente ricevuti, entrambi i buffer vengono svuotati (mittente) o i pacchetti contenuti salvati (destinatario).
In presenza di una comunicazione real-time il sistema ARQ risulta inadeguato a causa dei tempi di latenza della ritrasmissione. In questo caso si preferiscono sistemi a correzione di errore (Forward Error Correction).

## Stop-and-wait

Il protocollo Stop-and-wait è il più semplice protocollo di comunicazione di richiesta di ripetizione automatica (ARQ) della trasmissione di un pacchetto informativo in caso di rilevazione di errore nel pacchetto stesso a valle nel ricevitore. Un mittente manda un solo frame alla volta. Dopo che ogni frame è stato inviato, non viene inviato più nulla sino a quando il mittente non riceve un segnale ACK. Dopo che il destinatario ha ricevuto un frame corretto, manda un ACK al mittente. Se l'ACK non raggiunge il mittente prima di un certo tempo (timeout), il mittente rimanda nuovamente il frame.
Solitamente il mittente aggiunge un numero alla fine di ogni frame, che il destinatario utilizza per controllare il pacchetto alla ricerca di possibili errori. Se non viene individuato alcun errore, il destinatario invia un ACK, altrimenti scarta il pacchetto e non invia nulla, interpretando il pacchetto come "perso" anziché solamente come "danneggiato".
Un altro problema si verifica quando l'ACK inviato dal destinatario è danneggiato o perso: in questo caso, il mittente non riceve l'ACK, va in timeout e invia nuovamente il frame. Questo comportamento genera un problema per il destinatario, che si trova con due copie dello stesso frame, senza sapere se ciò che ha ricevuto è un frame duplicato oppure un frame contenente gli stessi dati di quello precedente.
Il fatto che il mezzo trasmissivo possa avere lunghi tempi di latenza, introduce un'ulteriore difficoltà, in quanto si potrebbe verificare l'occasione in cui il mittente vada in timeout prima che il pacchetto raggiunga il destinatario. In questo caso il mittente rimanderebbe il pacchetto e, nel caso in cui questo arrivi per tempo, il destinatario si troverebbe nuovamente con due pacchetti. Se questo decidesse di rispondere con un ACK per ognuno, il mittente si troverebbe ad avere due ACK, il che porterebbe ad assumere che il secondo ACK sia quello del prossimo frame della sequenza. Per evitare questi problemi, la soluzione più comune è quella di definire un numero di sequenza di 1 bit (che si alterna sempre) nell'header del frame. Quando il destinatario invia un ACK, include anche il numero di sequenza del prossimo frame che si aspetta. In questo modo, il ricevente è in grado di riconoscere i frame duplicati tramite il semplice controllo del bit di sequenza. Questo significa che, se due frame consecutivi hanno lo stesso numero di sequenza, sono duplicati e quindi il secondo viene scartato. Lo stesso discorso si può applicare agli ACK.
Anche questo metodo non risolve tutti i problemi, poiché si può verificare l'eventualità in cui il mittente invia un frame con bit di sequenza pari a zero non ricevuto dal destinatario, e immediatamente dopo riceve un ACK con bit si sequenza pari a uno: in questo modo vengono persi due frame a causa della dissincronia dei due contatori. Una soluzione possibile per limitare questo genere di errori è aumentare il numero di bit di sequenza, anche se questo rende solo più improbabile l'evenienza sopra descritta.
Concludendo, il metodo ARQ stop-and-wait è parecchio inefficiente (basso goodput) rispetto ad altri protocolli ARQ, specialmente a causa del tempo che intercorre tra l'invio dei vari frame, e contando anche il fatto che essendoci gli ACK, il tempo per terminare la comunicazione raddoppia, limitando di fatto la capacità del canale di comunicazione. Delle soluzioni differenti sono state implementate con i protocolli Go-Back-N e selective repeat.

## Go-Back-N

Go-Back-N ARQ è un'istanza specifica del protocollo ARQ, nel quale il processo mittente continua a mandare un numero di frame specificato da una "grandezza della finestra" (window size) anche senza ricevere alcun frame di ACK dal ricevitore.
Mittente e destinatario necessitano di accordarsi preventivamente sulla semantica degli acknowledgement, poiché tre vie sono possibili:
La prima, che utilizza ACK individuali (o selettivi), assegna all'ACK(n) il significato "ho ricevuto il frame n" e prevede che il destinatario mantenga traccia del numero di sequenza del successivo frame che si aspetta di ricevere, e spedisce tale numero, ogni volta che manda un segnale ACK. Se un frame inviato dal mittente non arriva al destinatario, il mittente fermerà l'invio dei frame. Una volta che il mittente ha spedito tutti i frame della sua finestra, si renderà conto che tutti i frame dalla prima perdita in poi sono stati evasi, e tornerà quindi indietro all'ultimo numero di sequenza ACK ricevuto dal processo destinatario e ricomincerà a creare la finestra, a partire proprio da quel frame.
La seconda, che utilizza ACK cumulativi e assegna all'ACK(n) il significato di "ho ricevuto tutti i frame fino ad n escluso", funziona similmente alla prima, ma su gruppi di frame: questo permette di risparmiare sugli ACK inviati, ma in caso di errore va ritrasmessa l'intera finestra.
Come ultima possibilità vi è quella dell'ACK negativo, dove il destinatario notifica la necessità di ritrasmissione di un singolo frame.
La grandezza della finestra deve essere un numero comparabile a quello della sequenza per permettere la verifica di avvenuta trasmissione anche nel caso in cui ogni frame venga perso. Se per l'ordinamento delle trame vengono utilizzati numeri di sequenza a m bit, la dimensione massima della finestra sarà 2$^m$.
Il metodo Go-Back N è uno dei modi più efficienti di effettuare una connessione, perché contrariamente al dovere aspettare che ogni frame invii il proprio frame ACK, la connessione viene usata più a lungo, mandando altri frame mentre si aspetta. In altre parole, durante il tempo che altrimenti sarebbe stato di attesa, vengono inviati frame aggiuntivi a prescindere dal risultato dell'invio precedente. Infatti, l'arrivo di un ACK relativo al frame che occupa l'estremo inferiore della finestra, genera la cancellazione di tale frame dal buffer di trasmissione e il conseguente "scorrimento" della finestra di una posizione in avanti, per permettere l'invio di un frame in più.
Tuttavia, questo metodo può dare come risultato l'invio multiplo di frame (nel caso in cui si perdesse un frame o un ACK). Per evitare tutto ciò, viene spesso utilizzato il metodo ARQ a ripetizione selettiva.
Come ulteriore metodo di ottimizzazione, si può introdurre il piggybacking che, nel caso di flussi di informazione bidirezionali, consiste nello scrivere l'informazione di riscontro (ACK) di un frame nell'intestazione del frame di informazione successivo che viaggia nella direzione opposta evitando latenze di trasmissione dovute alla trasmissione del solo ACK.

## Selective Repeat

Il Selective Repeat è un metodo simile al Go-Back-N, con la differenza che si ha una finestra di ricezione oltre a quella di trasmissione.
Selective Repeat accetta qualunque PDU valida all'interno della finestra di ricezione. L'arrivo di frame corretti al ricevitore genera lo scorrimento della finestra di ricezione, l'arrivo di ACK al trasmettitore genera lo scorrimento della finestra di trasmissione.
Se sono utilizzate ACK cumulativi e timer associati, il mittente si comporta nel seguente modo:
* invia Protocol Data Unit (PDU), facendone copia
* attiva un solo orologio delle PDU poi resettate alle trasmissioni
* Attende conferma (ACK)
* Se c'è timeout ripete le trasmissioni delle PDU
Il ricevitore controlla la correttezza della PDU. Se lo è la consegna al livello superiore, se non è in sequenza o la memorizza o la scarta, dipendendo dalla finestra di ricezione.
Se c'è una perdita, il protocollo si comporta come il protocollo Go-Back-N.
Ha vantaggi se il Round Trip Time (RTT) è inferiore alla trasmissione tramite finestra o se su più perdite si può inviare copia unica al ricevitore.