[MAVLINK] Issue with Checksum / mavlink_message_crcs

992 views
Skip to first unread message

Lauriane C

unread,
Jun 20, 2016, 11:54:43 AM6/20/16
to MAVLink
Hello everyone,

I'm trying to implement a parser in C++/Qt and my issue lies in calculating the checksum. I found this code that I slightly adapted to my parser :

#define X25_INIT_CRC 0xffff
#define X25_VALIDATE_CRC 0xf0b8

static inline void crc_accumulate(uint8_t data, uint16_t *crcAccum)
{
        /*Accumulate one byte of data into the CRC*/
        uint8_t tmp;

        tmp = data ^ (uint8_t)(*crcAccum &0xff);
        tmp ^= (tmp<<4);
        *crcAccum = (*crcAccum>>8) ^ (tmp<<8) ^ (tmp <<3) ^ (tmp>>4);
}

//Initialize the buffer for the X25 CRC
static inline void crc_init(uint16_t* crcAccum)
{
        *crcAccum = X25_INIT_CRC;
}

//Calculates the X.25 checksum on a byte buffer

//Here index and length help me to go through my QByteArray representing the message, from the second byte (so length_payload) to the last byte of the payload.

static inline uint16_t crc_calculate(QByteArray pBuffer, uint16_t index, uint8_t length, uint8_t message_id) {

        static const uint8_t mavlink_message_crcs[256] = {50, 124, 137, 0, 237, 217, 104, 119, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 0, 214, 159, 220, 168, 24, 23, 170, 144, 67, 115, 39, 246, 185, 104, 237, 244, 222, 212, 9, 254, 230, 28, 28, 132, 221, 232, 11, 153, 41, 39, 78, 196, 0, 0, 15, 3, 0, 0, 0, 0, 0, 153, 183, 51, 59, 118, 148, 21, 0, 243, 124, 0, 0, 38, 20, 158, 152, 143, 0, 0, 0, 106, 49, 22, 143, 140, 5, 150, 0, 231, 183, 63, 54, 0, 0, 0, 0, 0, 0, 0, 175, 102, 158, 208, 56, 93, 138, 108, 32, 185, 84, 34, 174, 124, 237, 4, 76, 128, 56, 116, 134, 237, 203, 250, 87, 203, 220, 25, 226, 46, 29, 223, 85, 6, 229, 203, 1, 195, 109, 168, 181, 47, 72, 131, 127, 0, 103, 154, 178, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 71, 15, 0, 0, 0, 0, 0, 0, 0, 163, 105, 0, 35, 0, 0, 0, 0, 0, 0, 0, 90, 104, 85, 95, 130, 184, 0, 8, 204, 49, 170, 44, 83, 46, 0};

        uint16_t crcTmp;
            crc_init(&crcTmp);
        while (length--) {
                crc_accumulate(pBuffer.at(index), &crcTmp);
                index++ ;
        }
        crc_accumulate(mavlink_message_crcs[message_id], &crcTmp);
        return crcTmp;
}


It doesn't match the checksum I have in my packets in tlog files but I don't get why. My guess would be that the mavlink_message_crcs is not right (I'm using mavlink 1.0) but I can't find other values.

Thanks a lot for your help (in advance) !

Lauriane C

unread,
Jun 21, 2016, 10:04:14 AM6/21/16
to MAVLink
Just to be more precise about what I'm trying to do.

I have got some .tlog files (so binary code of thousands of mavlink packets) that I want to "decode", meaning store in a Vector of "Packets". The struct Packets that I defined is close to mavlink_message_t : I can store length_payload, message_id etc and the payload but I dont read the payload itselft.

Thus when I want to calculate the checksum I have an issue : this mavlink_message_crcs that I don't have (it is generated from xml files apparently but I only have the one .tlog binary file I told you about).



I wanted to let my parser/lexer aside for a while and try using the one from mavlink C library availiable on github but they define macros for the CRCS as well so it is not useful for me at all.

Hoping someone could help me out,

Lauriane.

Message has been deleted

Milan E

unread,
Jul 3, 2016, 1:11:06 PM7/3/16
to MAVLink
Hello Lauriane,

This is a function that I use to check the CRC, maybe it can be useful to you too. It relies on the crc_accumulate from mavlink's checksum.h.

Hope it helps,
Milan


u_int8_t mavlink_message_crcs[256] = MAVLINK_MESSAGE_CRCS;

// check the received message CRC, return true if OK
bool check_mavlink_crc(u_int8_t *buff_in, ssize_t recsize, u_int8_t msgid) {
    u_int16_t *crc_accum = new u_int16_t(X25_INIT_CRC);
    u_int8_t temp;
    u_int16_t recv_crc;
    for (int i = 1; i < (recsize-2); ++i)
    {
        temp = buff_in[i];
        crc_accumulate(temp,crc_accum);
    }
    // adding the "seed"
    crc_accumulate(mavlink_message_crcs[msgid],crc_accum);
    recv_crc = buff_in[recsize-1]<<8 ^ buff_in[recsize-2];
    //cout << "CRC(recv): " << hex << setw(4) << recv_crc << endl;
    //cout << "CRC(calc): " << hex << setw(4) << *crc_accum << endl;
    // if the CRCs are the same, the subtraction result should be 0:
    recv_crc -= *crc_accum;
    delete crc_accum;
    if(!recv_crc) return true;
    return false;
}

Lauriane CHILAUD

unread,
Jul 5, 2016, 9:55:33 AM7/5/16
to MAVLink
Thank you Milan, I solved my problem in the meantime.

Indeed, there was no issue with my code but the mavlink_message_crcs array that I posted only works for messages that are in the Mavlink common message set, which I did not realise. Thus when the id corresponds to a zero value in the array, the checksum would fail because the array does not include the extra seed byte needed. This is fine for what I'm trying to do because I only need the packets with message_id == 33 to get the telemetry data.

Furthermore I did not get that the checksum was written from right to left in the mavlink protocol (big endian) thus my conversion from byte array to int failed as well...

time.m...@gmail.com

unread,
May 12, 2017, 6:54:57 AM5/12/17
to MAVLink, lauriane...@civicdrone.com
Hi Lauriane,

I need very similar as you describe, so please can you give me your help.

I want to calculate CRC of the message, example i have need to calculate CRC code for follow message (taken from my xml file):

<message id="3" name="CMN_HEARTBEAT_RSP">                                                                                                                                                                                                                                                                                                                                        
           
<descripton>Message for reporting the heartbeat</descripton>                                                                                                                                                                                                                                                                                                                  
           
<field type="uint32_t" name="timestamp">Unix time stamp</field>                                                                                                                                                                                                                                                                                                          
           
<field type="uint32_t" name="elapsedtime">Elapsed time since component power on</field>                                                                                                                                                                                                                                                                                        
           
<field type="uint8_t" name="runningstate"></field>                                                                                                                                                                                                                                                                                                                            
           
<field type="uint8_t" name="errorstate"></field>                                                                                                                                                                                                                                                                                                                              
           
<field type="uint8_t" name="Uint16_t"></field>                                                                                                                                                                                                                                                                                                                                
       
</message>

When i create class files over python scripts it show follow CRC code in correspond class:

#define MAVLINK_MSG_ID_CMN_HEARTBEAT_CRC 172
#define MAVLINK_MSG_ID_3_CRC 172

I am also using C++/Qt source for my application.

My general need is to load each message from xml file and calculate CRC for each of message with my C++/Qt application, so i need application that will received message as string (or other way?) and to return/caluclate CRC number (example 172 for previous example).

Please can you help me or share your ideas/source about how to achieve this?

Thanks in advance,

Time
Reply all
Reply to author
Forward
0 new messages