Analisi del Protocollo di Comunicazione USB

Da MeteoNetwork Wiki.
Jump to navigation Jump to search

Il tipo di periferica

Innanzitutto bisogna capire in che modo la nostra stazione viene riconosciuta dal sistema. Se analizziamo l'elenco periferiche scopriamo che, al momento del collegamento USB una nuova periferica di tipo HID è presente sul sistema. A dirla tutta le periferiche che compaiono sono due ma ciò dipende essenzialmente dal tipo di interfacce che ogni periferica HID espone verso il sistema.

Elenco periferiche.png

HID è una specifica SW/HW che permette il riconoscimento di periferiche USB senza bisogno di driver aggiuntivi, tipicamente è usata per dispositivi “Human Interface” quali mouse, tastiere, joysticks e similari.

Concentriamoci però su qualche dettaglio: facendo click col tasto destro e selezionando Proprietà, scopriamo qualcosa di più “intimo” della periferica ovvero il VendorID e il ProductID cioè due parametri che individuano univocamente in ogni sistema la periferica. Dalla figura che segue scopriamo essere VID: 1130 e PID: 6880.

Dettagli.png

A titolo di esempio vediamo anche cosa succede su linux:

comando: tail -f /var/log/messages

Linux.png

notate il riconoscimento di una periferica HID

comando: lsusb

Lsusb.png

potete verificare che i VID e PID sono gli stessi.

L'arte dello “Sniffing”

Appurato con che tipo di periferica abbiamo a che fare il passo successivo è indagare ulteriormente per scoprire se la periferica supporta un tipo di comunicazione “avanzata” tipica dell'HID protocol. Per chi volesse approfondire questo aspetto consiglio questa lettura: http://www.linuxjournal.com/article/8145 che verte su Linux ma le cui cosiderazioni sul protocollo HID sono di validità generale. La nostra periferica risponde all'indagine in questo modo:

Interface Descriptor:

     bLength                 9                         
     bDescriptorType         4                         
     bInterfaceNumber        0                         
     bAlternateSetting       0                         
     bNumEndpoints           1                         
     bInterfaceClass         3 Human Interface Device  
     bInterfaceSubClass      0 No Subclass             
     bInterfaceProtocol      0 None                    
     iInterface              0                         
     ** UNRECOGNIZED:  09 21 10 01 00 01 22 22 00      
     Endpoint Descriptor:
       bLength                 7
       bDescriptorType         5
       bEndpointAddress     0x81  EP 1 IN
       bmAttributes            3
         Transfer Type            Interrupt
         Synch Type               None
         Usage Type               Data
       wMaxPacketSize     0x0008  1x 8 bytes
       bInterval              10


l'UNRECOGNIZED ci dice sostanzialmente che il tipo di comunicazione è “bulk”: Tale tipo di comunicazione è costituito da una richiesta dell'host (il ns PC) e da risposte attraverso richieste di interrupt, ad ogni richiesta la periferica riversa i dati su un buffer corrispondente all'Endpoint (parametro bEndpointAddress) per un max di byte pari a wMaxPacketSize ad intervalli minimi di bInterval ms.

Cerchiamo di verificare quanto dedotto dall' Interface Descriptor. Per far ciò useremo su Windows il programma SnoopyPro(http://sourceforge.net/projects/usbsnoop/files/) che permette di catturare il traffico USB generato tra MeteoLog e la stazione. Utilizziamolo secondo i seguenti passi:

  • lanciamo SnoopyPro PRIMA di avviare MeteoLog
  • il primo passo fare l'unpack dei drivers e successivamente installarli (operazione che va ripetuta tutte le volte che si lancia il prog, i driver che installa sono infatti temporanei visto che sono attivi solo in memoria)

Snoopy2.png

  • aprire la finestra delle periferiche USB premendo F2 oppure il pulsante cerchiato di verde

Snoopy1.png

  • selezionare la periferica riconoscibile da VID e PID e, tramite click con il tasto destro, scegliere “Install and Restart”

Snoopy3.png

  • a questo punto si apre una finestra di log ed è adesso che va avviato MeteoLog. Noterete che il contatore dei pacchetti inizierà ad aumentare e, nella prima fase di MeteoLog ovvero lo scarico del datalogger, vederemo arrivare il contatore a circa 20000.

Snoopy4.png

  • una volta che lo scarico del datalogger è terminato assisteremo a incrementi di 48 pacchetti ogni 5 minuti: è il polling che MeteoLog fa per acquisire i dati realtime. Lasciamo che il polling acquisisca 2-3 campioni e poi premiamo sul pulsante di stop: compare la seguente finestra con l'intero log della comunicazione USB

Snoopylog.png


Analizziamola in dettaglio:

  • 1) Meteolog fa richiesta di polling tramite un comando USB di tipo CLASS_INTERFACE inviato all'EndPoint “bulk” 0x00: tale comando è costituito da un pacchetto di 8 byte di cui il primo indica il “payload” del pacchetto stesso ovvero quanti byte vadano considerati come dato vero e proprio. In questo caso, quindi, il comando sono i due byte FF AF.
  • 2) Dopo un po' di tempo (inferiore al secondo) la stazione inizia a inviare richieste di interrupt rendendo disponibile all'Endpoint 0x81 pacchetti di 8 byte. Tali richieste si susseguono a intervalli cadenzati di circa 40ms e sono anch'essi caratterizzati da avere il primo byte come indicatore del payload.
  • 3) A un certo punto la stazione, non avendo più dati da inviare, si silenzia. Notate infatti che Meteolog invia un successivo comando di polling dopo circa un secondo dall'ultima richiesta di interrupt. Questo comportamento permette una tecnica di lettura del buffer di tipo FIFO tramite un loop infinito che si interrompe quando il buffer viene trovato vuoto. La criticità in questo caso è solo evitare di essere troppo “aggressivi” nella lettura del buffer dando quindi alla stazione il giusto tempo (come abbiamo visto almeno 40ms) tra una lettura e l'altra altrimenti il rischio è uscire dal loop anzitempo.