Verify the CRC h and CRC from ETI file

117 views
Skip to first unread message

Tu Duong Anh

unread,
May 2, 2013, 11:00:16 AM5/2/13
to crc-mm...@googlegroups.com
Hi everybody,

I am trying to understand the structure of the ETI file, which I generated from the DAB+ Audio WAPP.

In ETS 300 799 (Annex D, p. 52) it is said that the ETI file uses CRC16-CCITT to create the fields for the CRC_h and CRC. The register is initialized to all ones, therefore CRC16-CCITT (0xFFFF) is used.

I have used LabVIEW to open the ETI file, to extract all the single fields and informations. But my CRC16-CCITT calculation of the CRC_h and CRC does not match with the values inside the ETI file. I have done the CRC calculation with a LabVIEW application, but also with the online calculator from http://www.lammertbies.nl/comm/info/crc-calculation.html. Both calculators give me the same output on the same input, so they there can't be a problem with the CRC calculation implementation.

I am also sure that I am using the right fields (bytes) to calculate those CRC. 

For CRC_h I have used the contents of the Frame Characterization (FC, 4 Bytes), Stream Characterization (STC, number of streams x 4 Bytes, two streams are inside the ETI file -> 8 Bytes total) and the Multiplex Network Signaling Channel field (MNSC, 2 Bytes). The CRC_h of my ETI file is 1110 1001 1010 1011. 

For the CRC calculation I haves used as said in the ETS 300 799 the content of Main Stream Data (MST, in my file 408 Bytes). My CRC calculation should give me as a result the CRC of 1000 1101 1110 1100. Just like the CRC_h, the CRC calculation with LabVIEW and the online CRC calculator does not match with the CRC values inside the ETI file. 

I hope somebody can give ve a hint or could verify his CRC with the online calculator.

Best regards
revolutionaries1s.eti

Ekkehard Domning

unread,
Apr 2, 2014, 5:19:44 AM4/2/14
to crc-mm...@googlegroups.com
Hi,
even a year ago, I would like to answer, since there is no other discussion place, regarding this issue.
I downloaded you attached file an found the following first few bytes
a8 61 00 00 b4 01 ff 07 3a b6 00 82 10 69 00 00
88 15 04 2a 48 12 00 00 e9 ab

The meaning of this as follow (taken from http://www.etsi.org/deliver/etsi_i_ets%5C300700_300799%5C300799%5C01_60%5Cets_300799e01p.pdf)
a8 61 00 00 // number of frames in file (not defined in standard)
b4 01 // len of next file 0x01B4 = 436 (not defined in standard)
ff 07 3a b6 // header (Chapter 6.1)
00 82 10 69 // Frame Characterization field (FC) 0x82 and 0x7F = 2 NST (Number of Stream Characterization)
00 00 88 15 // 1. Stream Characterization (STC)
04 2a 48 12 // 2. Stream Characterization (STC)
00 00 e9 ab // EOH (End Of Header 0xe9 0xab = CRC Checksum

On Page http://www.sdr-j.tk/index.html you can find the download link to a DAB software. In the software in the file "fic_handler.cpp" is the following code included, which does the bit-wise CRC calculation, corresponding to the picture on Annex D of ETS 300 799 linked above.
As you see there is a different loop back made.
In standard CRC the
- next new bit is made from the XOR of the Input and the MSB of the current CRC
- the CRC stages are XOR'ed, if the MSB  by the current CRC is "1"
In the ETI standard
- next new bit is made from the XOR of the Input and the MSB of the current CRC (same as above)
- the CRC stages are XOR'ed, if the next new bit is one.

static
const uint8_t crcPolynome [] =
    {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0};    // MSB .. LSB

bool    ficHandler::check_ficCRC (uint8_t *in, int16_t size) {
int16_t    i, f;
uint8_t    b [16];
int16_t    Sum    = 0;

    memset (b, 1, 16);

    for (i = size - 16; i < size; i ++) //inversion of the CRC, as it is inverted transmitted
       in [i] ^= 1;

    for (i = 0; i < size; i++) {
       if ((b [0] ^ in [i]) == 1) { // this is the difference to the "standard" CRC
          for (f = 0; f < 15; f++)
             b [f] = crcPolynome [f] ^ b[f + 1];
          b [15] = 1;
       }
       else {
          memmove (&b [0], &b[1], sizeof (uint8_t ) * 15); // Shift
          b [15] = 0;
       }
    }

    for (i = 0; i < 16; i++)
       Sum += b [i];

    return Sum == 0;
}

the above given data passed to this function (after a byte to bit string conversion!!) will calculate the correct CRC wich is 0.

My problem with the code above is, that it is painful slow.
The standard CRC alogrithm offers the possibility to pre calculate a table with 256 entries (one for each possible input byte combinations) and a charming fast single line calculation of the CRC

return = Hi(CRCOld) ^ CRCETITable[b ^ Lo(CRCOld)];

Due to the fact that the ETI calculation of CRC words uses the xor'ed input bit and MSB of the current state as input, instead of a direct linkback in the standard CRC, this approach does not work.

Question: Is there any simple approach to fix this? I think there must be an other possibility instead of building a 16MByte table for every CRC state and every input Byte.

Best regard
Ekkehard Domning

Matthias P. Braendli

unread,
Apr 4, 2014, 2:09:25 AM4/4/14
to crc-mm...@googlegroups.com
Hi,

On 02. 04. 14 11:19, Ekkehard Domning wrote:
> My problem with the code above is, that it is painful slow.
> The standard CRC alogrithm offers the possibility to pre calculate a
> table with 256 entries (one for each possible input byte combinations)
> and a charming fast single line calculation of the CRC
>
> return = Hi(CRCOld) ^ CRCETITable[b ^ Lo(CRCOld)];
>
> Due to the fact that the ETI calculation of CRC words uses the xor'ed
> input bit and MSB of the current state as input, instead of a direct
> linkback in the standard CRC, this approach does not work.
>
> Question: Is there any simple approach to fix this? I think there must
> be an other possibility instead of building a 16MByte table for every
> CRC state and every input Byte.


have a look at how it's calculated in dabmux:

https://github.com/Opendigitalradio/ODR-DabMux/blob/master/src/crc.c#L247

I don't see a reason why it shouldn't work elsewhere...

Cheers,
mpb

Ekkehard Domning

unread,
Apr 4, 2014, 4:00:30 AM4/4/14
to crc-mm...@googlegroups.com
Thank you very much. The code pointed me to the problem, my table was wrong, caused by a bit reversed polynom. Still in doubt why it works, but it works :-)
Regards Ekkehard
Reply all
Reply to author
Forward
0 new messages