martedì 8 agosto 2017

Checksum su pacchetti UBX Ublox

Circa un anno fa avevo riportato il metodo di calcolo del CRC per i pacchetti dei GPS Ublox

Adesso riporto il codice di calcolo in Python

Esempio di pacchetto UBX


In pratica si procede a scorrere lo stream dei dati fino a raggiungere il pacchetto di sincronia dati definito dai due byte successivi 0xB5-0x62 (oppure in decimanle 181 e 98).
I byte successivi indicano

1 byte = classe pacchetto
1 byte = id pacchetto
2 byte = lunghezza del payload (LSB+MSB)

segue poi il payload della lunghezza calcolata come in precedenza

2 byte di CRC

attenzione: per il calcolo del CRC si devono escludere i primi due byte di sync e gli ultimi due byte di CRC.

il codice in Pyton e' il seguente
-----------------------------------------------------------
# coding=utf-8
with open("c:\Python27\COM.ubx", "rb") as binary_file:
    data = binary_file.read()

msg = []

for x in range(0,100):
    test =  data[x]
    if ((data[x] == 181) and (data[x+1] == 98)):
        print("Sync Found! B5 62")
        msg_cls = data[x+2] #classe
        msg_id = data[x+3] #id
        msg_len_lsb = data[x+4] #byte meno significativo lunghezza messaggio
        msg_len_msb = data[x+5] #byte piu' significativo lunghezza messaggio
        len_msb = msg_len_lsb + (msg_len_msb*256)+4   #lunghezza messaggio
        for t in range(0,len_msb):
            msg.append(data[x+2+t]) # salva il payload 
        msg_chk1 = data[x+len_msb+2] #estrai i due byte di checksum
        msg_chk2 = data[x+len_msb+3]    
        
        #calcolo del checksum del payload
        CK_A,CK_B = 0, 0
        for i in range(len(msg)):
            CK_A = CK_A + msg[i]
            CK_B = CK_B + CK_A
        CK_A = CK_A & 0xFF
        CK_B = CK_B & 0xFF

        # controlla se il CRC del pacchetto e quello calcolato coincidono    
        if ((CK_A == msg_chk1) and (CK_B == msg_chk2)):
            print("Pacchetto ok")