Laboratorul 03 - Detectia și corectarea erorilor

Detectarea și corectarea erorilor de transmisie

În timpul transmisiei de date pot apărea erori. Acestea pot sa se manifeste ca biți a căror valoare a fost schimbata într-un cadru. De exemplu, dacă am trimite șirul de biți 11111111 pe un cablu, din cauza interferentelor electromagnetice ultimul bit ar putea avea valoarea schimbata și am primi șirul 11111110 în loc. In general, pentru a putea transmite date peste un mediu imperfect vom folosi una din urmatoarele metode

  • detectarea erorilor si retransmisia atunci cand latenta este mica
  • corectarea erorilor de transmisie atunci cand latenta este mare(e.g. trimitem un frame intre pamant si marte cu o latenta medie de 20 de minute)

Sume de control

Deseori când transmitem date peste un canal este necesar să știm dacă au fost recepționate fără eroare. De exemplu, am putea primi un frame corupt și vrem să știm dacă trebuie sa așteptăm sa fie retransmis. Ca soluție putem folosi algoritmi de checksum, aceștia primesc ca input un sir arbitrar de bytes și calculează o suma finită la output.

Ca exemplu vom lua Internet Checksum, algoritm folosit de protocoalele stivei TCP/IP pentru detectarea erorilor. Acesta descompune un sir de bytes într-un sir de words de 2 bytes. Si calculează suma negării lor pe biți. Dacă un sir este de dimensiune impară, ultimul byte este transformat într-un word prin shiftare la stânga cu 8 biți.

Click to display ⇲

Click to hide ⇱

 {
 /* Compute Internet Checksum for "count" bytes
  *         beginning at location "addr".
  */
 uint32_t sum = 0;
 /* 
    Move through the buffer two bytes at the time,
    cast the bytes to a number and add them to the sum
 */
 while( count > 1 )  {
     /*  This is the inner loop */
         sum += * (uint16_t *) addr;
         addr += 2;
         count -= 2;
 }
 
     /*  Add left-over byte, if any */
 if( count > 0 )
         sum += * (uint8_t *) addr;
 
     /*  Fold 32-bit sum to 16 bits */
 while (sum>>16)
     sum = (sum & 0xffff) + (sum >> 16);
 
 checksum = ~sum;
}

Ce facem daca am detectat o erorare? De cele mai multe ori, la detectia unei erori vom face o retransmisie. Receiver-ul va instiinta sender-ul ca o eroare a fost intalnita la trimiterea unui frame. Pentru a diferentia intre frame-uri, vom folosi un sequence number.

Coduri corectoare de erori

Am văzut mai sus ca putem detecta erorile de transmisie folosind algoritmi de checksum. Dar dacă frecventa erorilor pe un canal este prea mare, avem o alternativă mai buna la retransmiterea datelor?

Un răspuns la aceasta întrebare îl reprezintă codurile corectoare de erori, acestea codează datele originale astfel încât chiar și în cazul producerii unui anumit număr de erori, datele originale să poată fi recuperate.

Un exemplu de cod corector de erori îl reprezintă codarea Hamming. Aceasta va coda secventele de 4 biți(nibble) în secvente de 7 biți, intercalând trei biți de paritate. Astfel algoritmul pentru codare Hamming este:

  • Pornim de la un sir de 4 biți: d1, d2, d3, d4
  • Calculăm biții de paritate astfel(simbolul “^” reprezinta operația XOR):
    p1 = d1 ^ d2 ^ d4
    p2 = d1 ^ d3 ^ d4
    p3 = d2 ^ d3 ^ d4
    
  • Intercalăm biții de paritate cu cei originali: p1, p2, d1, p3, d2, d3, d4

Pentru a corecta o eroare în biții transmiși, trebuie sa calculam sindromul(z), astfel:

  • Pornim de la un sir de 7 biți: r1, r2, r3, r4, r5, r6, r7
   z1 = r1 ^ r3 ^ r5 ^ r7
   z2 = r2 ^ r3 ^ r6 ^ r7
   z3 = r4 ^ r5 ^ r6 ^ r7
   z = (z3 << 2) | (z2 << 1) | (z1 << 0)
   

O data calculat, sindromul ne va indica care bit din cei 7 transmiși a avut valoarea schimbata. De ex, daca z = 0, înseamna ca sirul a fost transmis corect, în schimb daca z = 3, înseamnă ca r3 a avut valoarea schimbata.

Algoritmul il gasiti mai bine detaliat aici

Exerciții

Pentru laboratorul acesta veți folosi scheletul oferit la adresa: lab3

1(5p). In funcția inet_csum din schelet, implementați algoritmul Internet Checksum, asa cum a fost descris in laborator. Verificați ca au fost transmise corect pachetele. In scriptul run_experiment.sh avem campurile CORRUPTION care manipuleaza rata de corupere a pachetelor.

2(3p). In funcția hamming_4to7 din schelet, implementați codarea Hamming, cum a fost descrisa in laborator. Ca input veti primi un byte ce are ultimii 4 biti setati la nibbleul ce trebuie codat, restul bitilor vor fi 0. La output veti returna un byte cu utlimii 7 biti setati la valoare codata a inputului.

Vom folosi bitmasks pentru a lucra la nivel de biti.

3(2p). In funcția hamming_7to4 din schelet (in send.c), implementati decodarea Hamming, cum a fost descrisa în laborator Inputul și outputul vor fi interschimbate fata de cele de la exercițiul 1. Deocamdată nu este necesara calcularea sindromului sau corectarea erorilor.

4(1p). In funcția hamming_7to4 din schelet (in recv.c), implementați corectarea erorilor folosind sindromul. Adaugați erori la poziții aleatoare în pachete. Tratând atât cazul în care are loc o eroare pe octet, cat și mai multe. Observați daca checksum-ul încă este corect.

Pentru a depana problemele va recomandam crash course-ul de Debugging.

O posibila solutie a laboratorului se gaseste aici

pc/laboratoare/03.txt · Last modified: 2022/03/23 18:33 by vlad_andrei.badoiu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0