Dividere un protocollo di pacchetto in livelli

1

Lavoro su sistemi embedded, così frequentemente, mi viene richiesto di implementare i protocolli. Quando faccio questo mi piace fare dei bei livelli puliti.

Tuttavia, questo diventa difficile dove i campi utilizzati da diversi livelli sono condivisi.

Mi piace pensare che i livelli offrano un certo numero di servizi seguendo lo spirito del modello OSI:

Framing
  1. Inizia byte / sequenza (SOF)
  2. lunghezza del pacchetto / messaggio
  3. integrità del messaggio (CRC, xor checksum)

Rete
 4. Fonte / Destinazione

Applicazioni
 5. Tipo comando / risposta (come interpretare il carico utile).

(Mi rendo conto che questo non è il modello ISO, ma ottieni il punto che spero.)

A volte il protocollo esiste su un collegamento punto-punto (socket RS232 o tcp), quindi non esiste alcun concetto di origine e destinazione.

In genere avrei un livello software per ciascuno di: Framing, Network e Application. Il livello è in genere un byte di elaborazione della macchina di stato, o frame o pacchetti. Nella parte superiore, vi è un punto di aggancio per la funzionalità specifica dell'applicazione.

Tipicamente quando un pacchetto si sposta sullo stack e i layer vengono rimossi, passo semplicemente un puntatore al successivo ambito interno. Primo puntatore a SOF, quindi puntatore ai campi di rete e infine un puntatore al payload dell'applicazione.

Man mano che i campi vengono analizzati, vengono aggiunti a una struttura specifica per il livello che la produce. (Una struttura con un nome come: Frame, Pacchetto, Messaggio / Comando / Risposta) Ogni struttura ha un puntatore al buffer del pacchetto.

In alto posso deallocare la struttura chiamando gratuitamente su ogni livello fino a quando in basso un puntatore è disponibile per liberare. (o tornare a un pool)

La domanda è: come posso gestire in modo pulito i casi in cui i campi hanno un duplice uso o sono campi di bit in un byte. (il nibble superiore è la lunghezza del payload, il nibble più basso è il tipo di pacchetto, ecc ...)

Un esempio di questo è un semplice formato di pacchetto come questo:
<SOF> <CMD> <command specific payload> <CRC>

In questo caso la lunghezza del pacchetto è implicita dal codice di comando. Quindi il campo CMD (un singolo byte in questo caso) è condiviso tra il framing e i livelli dell'applicazione.

Penso che in questo caso il livello di framing abbia una tabella di ricerca per il comando di lunghezza e passa un puntatore al campo CMD fino al livello applicazione per la gestione in una struttura.

    
posta JeffV 21.06.2013 - 14:41
fonte

1 risposta

1

Se hai a che fare con un protocollo progettato in modo così sfavorevole che i campi di intestazione degli strati concettuali delle differenze sono dappertutto, allora non hai molta scelta e devi solo trattarlo come un grande strato Fortunatamente, non ho mai incontrato un tale protocollo e penso che tendano a diventare obsoleti piuttosto velocemente.

Se hai un protocollo in cui un limite di livello cade da qualche parte nel mezzo di un byte, il codice di analisi del livello inferiore non dovrebbe far avanzare il puntatore del buffer oltre quel byte (poiché non è stato completamente consumato) ed entrambi i livelli dovrebbero essere consapevole che i bit di riserva di quel byte potrebbero contenere dati preziosi per un altro livello e trattarli di conseguenza. Loro non devono sapere cosa significano quei bit per l'altro livello.

Per evitare sovraccarichi del buffer se i campi di lunghezza in un messaggio vengono corrotti, le funzioni di analisi devono sempre essere informate di quanto è grande il buffer che possono ispezionare. Se qualche strato di protocollo ha parte delle sue informazioni nella coda del buffer (come spesso accade con i checksum CRC), allora le informazioni sulla lunghezza del buffer possono essere utilizzate sia per trovare il CRC (gli ultimi due byte del buffer) sia per evitare che i livelli superiori interpretino erroneamente i byte CRC come dati per loro (dicendo al livello superiore che il buffer termina prima).

In questo modo, nel formato del pacchetto

<SOF> <CMD> <command specific payload> <CRC>

il livello di framing non deve avere alcuna conoscenza dei comandi (o anche la possibilità che ci possa essere più di un comando nel messaggio). Il livello di frammentazione controlla solo <SOF> , estrae <CRC> dalla fine e convalida <CRC> controllando i byte intermedi come dati non elaborati. Poi dice al livello dell'applicazione che c'è un messaggio nel buffer che inizia con <CMD> e finisce poco prima di <CRC> .

    
risposta data 21.06.2013 - 15:26
fonte

Leggi altre domande sui tag