Nav-Soft an OpenSource Software GNSS company.


Home > Waas Data Encoding > Waas Data Encoding Logic

WAAS/EGNOS Signal Encoding Logic

Message Encoding

The following example should help clarify what happens in practice, you will see it is pretty simple. In fact it is much easier to understand how to calculate the parity value by looking at the following example than it is by trying to understand the obscure mathematics presented in the WAAS manual.

First we start by loading the provided bit stream into an array of bytes. However because we are given 2 bits to start and then all the other values are hexadecimal, which takes 2 values to fill a byte, it is easier to add 6 empty bits to the first data byte and then the two binary digits and then just fill the remaining data bytes 2 hexadecimal digits at a time, than try and figure out what values to use without adding the 6 binary bits at the beginning.

However adding the 6 extra bits means we also have to increase the loop counter by 6 to process these extra bits, since they are zero they do not affect the final result.


int crc_parity(unsigned char[]);

#define CRC_POLY  0x01864CFB

int main(int argc, char **argv)
{
unsigned char data[32];
int byte,bit;

    data[0] = 0x03;
    data[1] = 0x18;
    data[2] = 0x24;

    data[3] = 0x00;
    data[4] = 0x3c;
    data[5] = 0x00;
    data[6] = 0x3c;
    data[7] = 0x22;
    data[8] = 0x00;
    data[9] = 0x03;
    data[10] = 0xf4;
    data[11] = 0xbc;
    data[12] = 0x00;
    data[13] = 0x03;
    data[14] = 0xc0;
    data[15] = 0x03;
    data[16] = 0xc0;
    data[17] = 0x03;
    data[18] = 0xc0;
    data[19] = 0x00;
    data[20] = 0x3f;
    data[21] = 0xfd;
    data[22] = 0x80;
    data[23] = 0x00;
    data[24] = 0x3c;
    data[25] = 0xb2;
    data[26] = 0x40;
    data[27] = 0x00;
    data[28] = 0x3f;
    data[29] = 0x00;
    data[30] = 0x00;
    data[31] = 0x00;

    crc_parity(&data[0]);

}

static unsigned int shift;
int bit,byte,word;

    shift = 0;
    byte = 3;

    shift = (unsigned int)data[0]<<24;
    shift += (unsigned int)data[1]<<16;
    shift += (unsigned int)data[2]<< 8;

    for(bit=0;bit<232;bit++)
    {
        if(bit%8 == 0)shift += (unsigned int)data[byte++];
        printf("\n%03d %02x %08x",bit,data[byte],shift);
        if((shift&0x80000000) == 0x80000000)
        {
            shift = shift ^ (CRC_POLY<<7);
        }
        printf(" %08x",shift);
        shift = shift<<1;
    }
    printf("\n%03d %02x %08x",bit,data[byte],shift);
    printf("\nCRC check value is %08x\n",shift>>8);

    return(shift);
}

Normally this would stop at bit 226, but the test example given in the manual has an extra 6 empty bits at the begining of the data message.

The output data from this program is below, it starts with the bit no, then the next data byte followed by the 32 bit word before and after the parity logic has been applied, then we shift the 32 bit word left 1 bit and start again. If you look closely you can see that the last 32 bit word only changes when there is a 1 in the left most binary digit of the first 32 bit word, ie when the hex value is 8 or more.

000 3c 03182400 03182400
001 3c 06304800 06304800
002 3c 0c609000 0c609000
003 3c 18c12000 18c12000
004 3c 31824000 31824000
005 3c 63048000 63048000
006 3c c6090000 052f7d80
007 3c 0a5efb00 0a5efb00
008 00 14bdf63c 14bdf63c
009 00 297bec78 297bec78
010 00 52f7d8f0 52f7d8f0
011 00 a5efb1e0 66c9cc60
012 00 cd9398c0 0eb5e540
013 00 1d6bca80 1d6bca80
014 00 3ad79500 3ad79500
015 00 75af2a00 75af2a00
016 3c eb5e5400 28782980
017 3c 50f05300 50f05300
018 3c a1e0a600 62c6db80
019 3c c58db700 06abca80
.
.
.
.
211 00 b668a700 754eda80
212 00 ea9db500 29bbc880
213 00 53779100 53779100
214 00 a6ef2200 65c95f80
215 00 cb92bf00 08b4c280
216 00 11698500 11698500
217 00 22d30a00 22d30a00
218 00 45a61400 45a61400
219 00 8b4c2800 486a5580
220 00 90d4ab00 53f2d680
221 00 a7e5ad00 64c3d080
222 00 c987a100 0aa1dc80
223 00 1543b900 1543b900
224 00 2a877200 2a877200
225 00 550ee400 550ee400
226 00 aa1dc800 693bb580
227 00 d2776b00 11511680
228 00 22a22d00 22a22d00
229 00 45445a00 45445a00
230 00 8a88b400 49aec980
231 00 935d9300 507bee80
232 00 a0f7dd00
CRC check value is a0f7dd

Back to Top of Page