Laborator 03 - Capacitatea ideală a mediului

Materiale ajutătoare

Teorie:

  • Despre modulațiile DSSS-CCK și OFDM - quick intro bun aici
  • Despre comuncația la lower level MAC - quick intro aici
  • studiu similar pentru a/g/n/ac, agregare 80211notes

Concepte

  • Modulație PHY - Modulația este un proces folosit în telecom prin care modificăm parametrii unui semnal cu scopul de a transmite informații. Dacă la radio am auzit de AM (modularea în amplitudine a semnalului) sau FM (modularea în frecvență a semnalului) în WiFi întâlnim preponderent DSSS (Direct Sequence Spread Spectrum), CCK (Complementary Code Keyring) și, cea mai modernă, inclusiv în tehnologia 802.11ac și 4G-LTE: OFDM (Orthogonal Frequency Division Multiplexing)
  • Cadrele (frame-urile) în wifi - vă veți tot lovi de conceptele astea fie prin curs, fie prin standard, fie chiar și prin kernelul de Linux:
  • Pachetele ETH/IP/UDP cu care suntem familiari circulă prin WiFi conform figurii de mai jos (valabil pentru orice standard) - în lumea wifi ele poartă numele de MSDU (MAC Service Data Unit)

  • La nivel MAC (L2) clientții (în standard îi întâlniți sub numele de STA de la stații) comunică cu AP (access point) prin MPDU - MAC Protocol Data Units. Headerul de MAC va conține chestii de interes pentru noi în acest laborator:
    • dataRate (sau MCS):
      • la frame-uri de tip “legacy” (802.11a și 802.11b/g) întâlnim valori în Mbps:
        • Uzual pentru 802.11b (2.4 GHz DSSS-CCK): 1, 2, 5.5, 11 Mbps
        • Uzual pentru 802.11g (2.4 GHz ERP-OFDM): 6, 12, 36, 54 Mbps
        • Uzual pentru 802.11a (5 GHz ERP-OFDM): 6, 9, 12, 18, 24, 36, 48, 54 Mbps
      • Acestea sunt valori “teoretice” maxime care pot fi atinse de standardul respectiv
    • OPȚIONAL: la frame-uri de tip HT/VHT (802.11n/802.11ac) întâlniți valori de MCS de la 0 la 9 care conțin informații despre schema de modulare (BPSK, QPSK, QAM etc.) și rata de codare
    • duration - durata în microsecunde a semnalului modulat pe aer prin simboluri - cât timp va ține acest device mediul ocupat cu transmiterea pachetului plus timpul pe care acesta îl cere pentru ACK la nivel de wifi (SIFS)
    • CRC - 4 bytes adăugați de stivă pentru validarea MSDU-ului
    • Mai sunt și altele dar nu intră în scopul acestui laborator
    • La nivel PHY: avem PSDU (PLCP Service Data unit) și PPDU (PLCP Protocol Data Unit - o sumă de PSDU-uri)
    • Algoritmul de acces la mediu în wifi:
      • DCF (Distributed Coordinated Function) - întâlnită la majoritatea AP-urilor și clienților de 802.11 a/b/g/n, dar și la unele device-uri 802.11ac mai ales de tip Wave1
      • EDCA (Enhanced Distributed Channel Access) - întâlnim de la 802.11ac în sus
      • acestea afectează durata unei tranzacții atomice de transmitere a unui cadru (care nu e doar timpul în microsecunde necesar plasării simboluri PHY pe aer)
    • Durata de transmitere a unui cadru wifi cu tehnologia DCF pe aer e suma următoarelor elemente
      • DIFS - DCF Inter Frame Spacing - o valoare care spune device-urilor Wifi așa: dacă mediul e liber pentru un timp egal cu DIFS atunci puteți transmite cadrul vostru
      • Slot time - arbitraj - durate de timp definite de layerul de MAC pentru inter-frame spacing - depinde de tehnologia de PHY
      • transmiterea PPDU-ului pe aer: antet PHY, antet MAC, header IP, header UDP sau TCP, Payload L4 de x octeți, CRC (4 bytes)
      • SIFS - Short Inter Frame Spacing - durata de timp în care mă aștept să primesc ACK la nivel wifi (L2) de la celălalt device că a recepționat corect cadrul
      • ACK - durata de timp ocupată pe aer de cadrul de tip ACK - el e trimis tot cu o modulație (dataRate) în format legacy - de obicei se alege cea mai mică rată pe care o suportă un anumit standard (e.g 6 Mbps pentru 802.11a/g OFDM și 1 Mbps pentru 802.11b DSSS-CCK)

Scop

Scopul acestui laborator este de a calcula capacitatea unui canal 802.11 pentru diverse standarde, în condiții ideale. Vom face o analiză teoretică folosind temporizările, randomizările, și dimensiunile antetelor din standard, versus estimarea în simulator.

[00] Pregătire laborator

Intrați în directorul /home/student/Desktop/ISRM/ns-3-dev. Rulați comenzile:

git remote add isrm https://gitlab.com/b12mihai1/ns-3-dev.git 
git remote update
git checkout -b isrm_2020 remotes/isrm/isrm_2020
git submodule init
git submodule update --remote --merge
git submodule foreach git pull origin master   # in caz ca cea anterioara nu ne muta pe ultimul commit din master

Dacă directorul nu există rulați comenzile de mai jos și țineți minte unde aveți ns-3-dev folder cu toate lucrurile compilate:

git clone https://gitlab.com/b12mihai1/ns-3-dev.git ~/ns-3-dev
cd ~/ns-3-dev
git checkout -b isrm_2020 remotes/origin/isrm_2020
git submodule init
git submodule update --remote --merge
git submodule foreach git pull origin master
./waf configure --build-profile=debug --enable-examples --enable-tests && ./waf build -j4

Pentru a realiza grafice, trebuie sa instalam si pachetele de Python:

student@isrm-vm-2020:~$ sudo apt-get update
student@isrm-vm-2020:~$ sudo apt-get install python3-pip
student@isrm-vm-2020:~$ pip3 install matplotlib jupyter
student@isrm-vm-2020:~$ sudo ln -s ~/.local/bin/jupyter-notebook /usr/bin/jupyter-notebook

Pentru a lansa aplicatia de Jupyter Notebook, rulati urmatoarea comanda:

student@isrm-vm-2020:~$ jupyter-notebook

Pe parcursul laboratorului, vom avea nevoie de utilitarul tshark:

student@isrm-vm-2020:~$ sudo apt-get install tshark

[01] Analiza capturii profilului de trafic

Utilitarul Wireshark este un utilitar grafic pentru captură și inspecție de trafic de rețea. Tshark este un wireshark pentru terminal. Are avantajul de a folosi limbajul wireshark pentru filtre (condițiile pot fi create în wireshark si apoi copiate cu copy/paste), dar în același timp oferă controlul afișarii la stdout.

Până acum foloseați de obicei aceste utilitare pentru a analiza o captură real-time de pachete pe o interfață sau o captură pcap/pcapng obținută cu tcpdump.

Simulatorul ns-3 ne oferă un mecanism de tracing foarte puternic de analiză: pcap-tracing

[01a] Rularea simulării

student@isrm-vm:~/ns-3-dev$ ./waf --run "wifi-tcp --pcap=true"
(...)
student@isrm-vm:~/ns-3-dev$ ls -al *.pcap
-rw-rw-r-- 1 mihai mihai 76129717 Mar  4 15:44 AccessPoint-0-0.pcap
-rw-rw-r-- 1 mihai mihai 80172767 Mar  4 15:44 Station-1-0.pcap

Deschideți oricare din cele două capturi cu Wireshark. Filtrați și afișați doar pachetele TCP. Fără a citi codul simulării și nici descrierea de la începutul sursei, ci doar PCAP-urile, care credeți că e direcția traficului? Sunt două noduri: 0 și 1 - 0→1 sau 1→0?

Primul număr din numele PCAP-ului generat este indexul nodului din simulare, iar al doilea număr e interfața de rețea (un nod poate avea mai multe interfețe de rețea). În simulare nodul 0 e AP (access point) și 1 este stație mobilă (STA). Un pachet care ajunge la STA (nodul 1) dar care a fost aruncat nu va putea fi văzut în captura Station-1-0.pcap dar în AccessPoint-0-0.pcap îl vom putea vedea.

Acest lucru e util când vom analiza de ce se pierd pachete în WiFi

Determinați canalul routerului și frecvența centrală a lui analizând câmpurile din secțiunea 802.11 radio information sau Radiotap Header.

[01b] Analiza PCAP cu tshark

Exemple filtre

Exemplu rulare:

student@isrm-vm:~/ns-3-dev$ tshark -T fields -e frame.time_epoch \
     -e frame.number -e ip.src  \
     -r ./AccessPoint-0-0.pcap '(ip.proto == 6) && (ip.src == 10.0.0.1)' > frames.txt
  • -T fields indică câmpurile din pachete care se doresc printate

Colecție de câmpuri de interes:

opțiune pentru -e semnificație
frame.time_epoch timpul de la începutul simulării
frame.number numărul cadrului
ip.src adresa IP sursă
ip.id IP identifier field
ip.ttl câmpul TTL din headerul de IP
wlan.flags câmpul flags din headerul WLAN
wlan.seq numărul de secvență WLAN
wlan.fcs_good cadrul WLAN este validat de câmpul FCS
  • (ip.proto == 6) && (ip.src == 10.0.0.1) indică condiția de filtrare a pachetelor din .pcap - pachete de tip TCP (proto=6) și IP sursă; folosește acelasi limbaj ca și wireshark

Exerciții:

  • Folosind tshark cu filtrul wlan.fc.type_subtype == 0x08 extrageți și numărați câte pachete de tip beacon trimite AP-ul din captura ./AccessPoint-0-0.pcap
    • Hint: pentru contorizare în bash puteți folosi wc -l
    • Folosiți câmpurile frame.time_epoch de la câteva linii consecutive și determinați la ce interval de timp (în ms) AP-ul (access point-ul) trimite beacon-uri
  • Folosind tshark extrageți în 2 fișiere separate, fiecare fișier având filtrul wlan.fc.type_subtype ⇐ 0x0011 (subtipul ⇐ 0x0011) și celălalt wlan.fc.type_subtype == 0x0028 următoarele câmpuri: frame.time_epoch, wlan_radio.phy, frame.number.
    • Ce puteți spune despre PHY type-ul din primul fișier, dar al doilea? Ce credeți că se întâmplă
    • Dacă sunteți curioși ce inseamna type/subtype, consultați acest tabel din standardul 802.11

Veți vedea și la curs și vom vedea și pe parcursul laboratoarelor: cadrele de date se trimit cu cel mai mare MCS posibil (în anumite condiții) iar cele de management/control (e.g. beacon, probe request) cu cel mai mic MCS stabilit intre AP și STA - motivul este că pentru acestea vrem o constelație robustă deoarece pierderile nu sunt acceptabile pentru cadre de control.

[01c] Analiza trace-ului ASCII

Mecanismul de tracing din ns-3 ne permite să logăm și în format ASCII evenimentele. Rulați simularea aferentă laboratorului 3 astfel:

./waf --run "lab3 --numberOfNodes=2 --payloadSize=1400 \
    --offeredRate=11Mbps --phyRate=DsssRate11Mbps --simulationTime=2 --tracing=true"

Vom obține două trace-uri: unul PCAP (cum am analizat mai sus) și unul text: wifi-lab3.tr. Deschideți și inspectați fișierul.

Explicația conținutului fișierului:

Prima literă este:

r for received
d for dropped
+ for enqueued
- for dequeued
t is for transmitted #Relevant for WiFi tracefiles

A doua coloană reprezintă timestamp.

A treia coloană are următoarea semnificație:

name of the event in the configuration namespace, sometimes called the configuration path name. The NodeList value represents the node (A=0, etc), the DeviceList represents the interface, and the final part of the name repeats the action: Drop, MacRx, Enqueue, Dequeue.

Apoi urmează o serie de nume de clase din sistemul de atribute al ns-3 (ns3::Ipv4Header, ns3::TcpHeader) și cu o listă de trace-uri specifice clasei respective.

[02] Capacitatea ideală teoretica

In cadrul acestui exercitiu vom calcula capacitatea unui canal 802.11 pentru standardele 802.11b si 802.11g, în condiții optime. Vom face o analiză teoretică folosind temporizările, randomizările și dimensiunile antetelor din standard.

[02a] Durata unei tranzactii atomice

Inainte de a porni la calcul, trebuie sa vedem mai intai cum arata antetul de PHY pentru cele 2 standarde.

Pentru 802.11b, avem un antet PHY de 192 de biti care este trimis la un MCS de 1 Mbps:

Pentru 802.11g, avem un antet PHY de 16 us plus 24 de biti care sunt transmisi la un MCS de 6 Mbps:

Pentru inceput, vom calcula durata minima (in microsecunde) a unei tranzacții atomice de transmitere a unui cadru de date. Aceasta durata poate fi calculata ca suma duratelor urmatoarelor componente: DIFS, arbitraj, PHY header, MAC header, IP/UDP header, UDP Payload de x octeți, FCS (CRC), SIFS, antent PHY, ACK. Motivul pentru care avem un al doilea antet PHY este pentru ca mesajul de ACK este precedat la randul lui de un antet PHY.

Antetele de MAC, IP, UDP, payload-ul UDP, FCS si ACK-ul se transmit prin aer la rata MCS, măsurată în bps.

Folosiți duratele temporizărilor specificate în standard și dimensiunile antetelor PHY din schemele de mai sus:

  • 11b: slot time=20, SIFS=10, DIFS=50
  • 11g: slot time=9, SIFS=10, DIFS=28
  • arbitraj=numar de sloturi * slot time; Numarul de sloturi poate sa varieze de la 0 pana la o anumita valoare prestabilita, minimul acestei valori fiind de 31. Pentru laborator, vom folosi o valoare medie a timpului de arbitraj minim: 31 / 2 * slot time = 15.5 * slot time.

Header-ul de MAC pentru standardul 802.11 arata in felul urmator (dimensiunile sunt in octeti). Nu luati in calcul a patra adresa MAC care este optionala:

Header-ul IPv4 arata in felul urmator:

Header-ul UDP arata in felul urmator:

Mesajele de ACK au dimensiunea de 14 octeti.

Calculati duratele tranzactiilor atomice pentru 802.11b si 802.11g.

Durata unei tranzactii atomice pentru 802.11b este:

Click to display ⇲

Click to hide ⇱

50 + 310 + 192 / 1 + (24 + 20 + 8 + x + 4) *8 / MCS + 10 + 192 / 1 + 14 * 8 / MCS

[02b] Calcul si grafice throughput

Vom calcula throughput-ul ca raportul dintre dimensiunea payload-ului UDP (date utile) si durata unei tranzactii.

Calculati throughput-ul in Mbps pentru standardele 802.11b si 802.11g. Tineti cont ca throughput-ul va fi dependent de dimensiunea payload-ului UDP si de MCS.

Click to display ⇲

Click to hide ⇱

Throughput_11b(x) = x*8 / (754 + (70 + x) * 8/ MCS)

La 802.11g, obtinem urmatoarea durata a tranzactiei atomice: 28 + 15.5 * 9 + 16 + 24 / 6 + (24 + 20 + 8 + x + 4) *8 / MCS + 10 + 16 + 24 / 6 + 14 * 8 / MCS Throughput_11g(x) = x*8 / (217.5 + (70 + x) * 8/ MCS)

Realizati cate un grafic pentru standardele 802.11b si 802.11g care sa evidentieze evolutia throughput-ului in Mbps (axa Oy) in functie de dimensiunea payload-ului UDP (axa Ox). Puteti varia dimensiunea payload-ului de la 0 la 1400 de octeti.

Din moment ce throughput-ul depinde si de MCS, in cadrul fiecarui grafic vor trebui construite 4 curbe (subgrafice) care sa corespunda urmatoarelor valori de MCS:

  • pentru 802.11b - MCS: 1, 2, 5.5, 11 Mbps
  • pentru 802.11g - MCS: 6, 12, 24, 54 Mbps

Graficele la care trebuie sa ajungeti sunt urmatoarele:

Pentru realizarea graficelor, puteti folosi urmatorul template:

import copy
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
 
MCS_802_11_B = [1, 2, 5.5, 11]
MCS_802_11_G = [6, 12, 24, 54]
PAYLOAD_SIZES = [100 * i for i in range(15)]
 
def compute_throughput_802_11_b(payload_size, mcs):
    #TODO - replace tput with the correct value based on the payload_size and mcs
    tput = 0
    return tput
 
def compute_throughput_802_11_g(payload_size, mcs):
    #TODO - replace tput with the correct value based on the payload_size and mcs
    tput = 0
    return tput
 
def plot_802_11_b_throughput():
    # Apelul subplots poate fi folosit pentru a crea mai multe subgrafice in cadrul aceluiasi grafic sau in cadrul unor grafice diferite
    # Prin figsize se specifica dimensiunea graficului
    fig, ax = plt.subplots(figsize=(12,12))
 
    # Valori stilistice pentru grafic
    ax.grid(color='b', alpha=0.5, linestyle='dashed', linewidth=0.5)
 
    # Denumirile axelor Ox si Oy, precum si titlul graficului
    plt.xlabel('Payload size [bytes]')
    plt.ylabel('Throughput [Mbps]')
    plt.title('802.11b throughput')
 
    # Aici este construit efectiv graficul. Campul label va fi folosit in cadrul legendei graficului
    for mcs in MCS_802_11_B:
        tput_values = [compute_throughput_802_11_b(payload_size, mcs) for payload_size in PAYLOAD_SIZES]
        ax.plot(PAYLOAD_SIZES, tput_values, label='%s' % mcs)
    ax.legend()
 
    plt.show()
 
def plot_802_11_g_throughput():
    #TODO
    pass
 
if __name__ == '__main__':
    plot_802_11_b_throughput()
    plot_802_11_g_throughput()

[03] Capacitatea ideală simulare

  • Pentru un singur client, se vor repeta curbele de mai sus folosind ns-3. Modelul lab3.cc configurează la (0,0) un AP și n-1 noduri plasate în vecinătatea sa. Traficul este generat de la AP către fiecare nod.
  • Pentru capacitatea ideală, folosim un AP, un client, trafic de tip UDP. Exepmlu de rulare de interes (cu parametrii de interes) pentru acest task:
mihai@wormhole:~/facultate/ns-3-dev$ ./waf --run "lab3 --numberOfNodes=2 \
     --payloadSize=1400 --offeredRate=11Mbps --phyRate=DsssRate11Mbps --simulationTime=2"
Waf: Entering directory `/home/mihai/facultate/ns-3-dev/build'
Waf: Leaving directory `/home/mihai/facultate/ns-3-dev/build'
Build commands will be stored in build/compile_commands.json
'build' finished successfully (4.605s)
Flow 1 (10.0.0.2 -> 10.0.0.1)
  Tx Packets: 1964
  Tx Bytes:   2804592
  TxOffered:  11.2311 Mbps
  Rx Packets: 1388
  Rx Bytes:   1982064
  Throughput: 7.93722 Mbps
 
Average throughput: 7.7728 Mbit/s

numberOfNodes reprezintă numărul total de noduri (inclusiv AP-ul).

Pentru a schimba standardul folosit in cadrul scriptului, modificati la linia.

Parametrul phyRate (reprezinta MCS) va lua urmatoarele valori:

  • Pentru 802.11b:
  DsssRate1Mbps
  DsssRate2Mbps
  DsssRate5_5Mbps
  DsssRate11Mbps
  • Pentru 802.11g:
  ErpOfdmRate6Mbps
  ErpOfdmRate9Mbps
  ErpOfdmRate12Mbps
  ErpOfdmRate18Mbps
  ErpOfdmRate24Mbps
  ErpOfdmRate36Mbps
  ErpOfdmRate48Mbps
  ErpOfdmRate54Mbps

Parametrul offeredRate corespunde traficului trimis de aplicație în socketul UDP. Pe linia de comandă trebuie dați parametrii relevanți pentru dimensiunea pachetului și rata dorită de UDP.

Scopul acestui task este să repetați graficele precedente/teoretice folosind simularea în ns-3. Puncte de evaluare pentru payloadSize: 20, 50, 100, 500, 1000, 1500.

Pe Oy pentru throughput extrageti valoarea obtinuta la Average throughput: 7.7728 Mbit/s

Puteți reduce timpii simulării folosind parametrul --simulationTime=1

Puteti folosi acest template pentru construirea graficelor (va trebui sa implementati TODO-urile):

import copy
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
 
# Calea absoluta catre fisierul de date din care citim
# TODO - trebuie inlocuita cu calea corecta
DATA_FILE_802_11_B = '/home/student/ns-3-dev/output_802_11_b.txt'
DATA_FILE_802_11_G = '/home/student/ns-3-dev/output_802_11_g.txt'
columns = ['mcs', 'payload_size', 'throughput']
 
# Citim datele din fisier
# Argumentul delimiter precizeaza care este delimitatorul dintre coloane
# Argumentul skip_header precizeaza cate linii nu vor fi citite pornind cu inceputul fisierului
# Argumentul names este unul foarte util deoarece permite asocierea de nume pentru coloanele din fisier si
# de asemenea duce la un acces foarte usor al datelor in script. In acest exemplu, names va fi egal cu ['x', 'y']
# ceea ce inseamna ca putem accesa valorile din prima coloana prin sim_data['x'].
# Argumentul dtype setat specifica modul in care vor fi interpretate coloanele (string-urile ca string-uri, float-urile ca float-uri).
# In absenta acestui argument, valorile din coloane vor fi interpretate ca float.
sim_data_802_11_b = np.genfromtxt(DATA_FILE_802_11_B, delimiter=' ', names=columns, dtype=None)
#TODO - decomentati linia dupa ce ati obtinut fisierul de output pentru 802.11g
# sim_data_802_11_g = np.genfromtxt(DATA_FILE_802_11_G, delimiter=' ', names=columns, dtype=None)
 
def plot_802_11_b_throughput(sim_data):
    data = copy.deepcopy(sim_data)
 
    # Apelul subplots poate fi folosit pentru a crea mai multe subgrafice in cadrul aceluiasi grafic sau in cadrul unor grafice diferite
    # Prin figsize se specifica dimensiunea graficului
    fig, ax = plt.subplots(figsize=(12,12))
    # Valori stilistice pentru grafic
    ax.grid(color='b', alpha=0.5, linestyle='dashed', linewidth=0.5)
    # Denumirile axelor Ox si Oy, precum si titlul graficului
    plt.xlabel('Payload size [bytes]')
    plt.ylabel('Throughput [Mbps]')
    plt.title('802.11b throughput')
 
    # Aici este construit efectiv graficul. Campul label va fi folosit in cadrul legendei graficului
    #TODO
    # Daca in fisierul de output aveti toate valorile de MCS, este posibil sa aveti nevoie de Python slicing pentru 
    # a construi graficele usor. Exemplu: data['mcs'][0:6] sau data['throughput'][0:6] pentru a extrage primele 6 elemente din 
    # coloana.
    ax.legend()
 
    plt.show()
 
 
def plot_802_11_g_throughput(sim_data):
    data = copy.deepcopy(sim_data)
 
    # Apelul subplots poate fi folosit pentru a crea mai multe subgrafice in cadrul aceluiasi grafic sau in cadrul unor grafice diferite
    # Prin figsize se specifica dimensiunea graficului
    fig, ax = plt.subplots(figsize=(12,12))
    # Valori stilistice pentru grafic
    ax.grid(color='b', alpha=0.5, linestyle='dashed', linewidth=0.5)
    # Denumirile axelor Ox si Oy, precum si titlul graficului
    plt.xlabel('Payload size [bytes]')
    plt.ylabel('Throughput [Mbps]')
    plt.title('802.11g throughput')
 
    # Aici este construit efectiv graficul. Campul label va fi folosit in cadrul legendei graficului
    #TODO
 
    ax.legend()
 
    plt.show()
 
 
if __name__ == '__main__':
    plot_802_11_b_throughput(sim_data_802_11_b)
    #TODO - decomentati linia dupa ce ati obtinut fisierul de output pentru 802.11g
#     plot_802_11_g_throughput(sim_data_802_11_g)

Pentru mai multe informatii legate de list slicing in Python, puteti consulta aceasta pagina.

De ce iterăm peste aceste packet size-uri? Iată câteva valori din trafic real: VoIP ~ 20-300; DNS, TCP~ 500; Ethernet MTU=1500; 802.11 Beacon=380

isrm/laboratoare/new/03.txt · Last modified: 2020/05/17 14:19 by vlad.traista
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