Generating a CRC

Generating a CRC

Postby Jeff Barnes » Fri Feb 22, 2008 1:49 am

Hi Everyone,

I am trying to connect to a patient monitor to extract data.
The monitor has an ASCII protocol the requires a CRC as part of the command request.

For example, If I want to issue a "Connect" command I would need to do the following:

Format: Header <command> CRC

so the actual command to send is: DIAP000<connect>CRC

In the manual they have a small section on the CRC that I just do not understand.

From the manual:


CRC Algorithm

The algorithm used to create the CRC follows:

const unsigned short crcTable[256] = {

0x0000, 0x0108, 0x0210, 0x0318, 0x0420, 0x0528, 0x0630, 0x0738,

0x0840, 0x0948, 0x0A50, 0x0B58, 0x0C60, 0x0D68, 0x0E70, 0x0F78,

0x1081, 0x1189, 0x1291, 0x1399, 0x14A1, 0x15A9, 0x16B1, 0x17B9,

0x18C1, 0x19C9, 0x1AD1, 0x1BD9, 0x1CE1, 0x1DE9, 0x1EF1, 0x1FF9,

0x2102, 0x200A, 0x2312, 0x221A, 0x2522, 0x242A, 0x2732, 0x263A,

0x2942, 0x284A, 0x2B52, 0x2A5A, 0x2D62, 0x2C6A, 0x2F72, 0x2E7A,

0x3183, 0x308B, 0x3393, 0x329B, 0x35A3, 0x34AB, 0x37B3, 0x36BB,

0x39C3, 0x38CB, 0x3BD3, 0x3ADB, 0x3DE3, 0x3CEB, 0x3FF3, 0x3EFB,

0x4204, 0x430C, 0x4014, 0x411C, 0x4624, 0x472C, 0x4434, 0x453C,

0x4A44, 0x4B4C, 0x4854, 0x495C, 0x4E64, 0x4F6C, 0x4C74, 0x4D7C,

0x5285, 0x538D, 0x5095, 0x519D, 0x56A5, 0x57AD, 0x54B5, 0x55BD,

0x5AC5, 0x5BCD, 0x58D5, 0x59DD, 0x5EE5, 0x5FED, 0x5CF5, 0x5DFD,

0x6306, 0x620E, 0x6116, 0x601E, 0x6726, 0x662E, 0x6536, 0x643E,

0x6B46, 0x6A4E, 0x6956, 0x685E, 0x6F66, 0x6E6E, 0x6D76, 0x6C7E,

0x7387, 0x728F, 0x7197, 0x709F, 0x77A7, 0x76AF, 0x75B7, 0x74BF,

0x7BC7, 0x7ACF, 0x79D7, 0x78DF, 0x7FE7, 0x7EEF, 0x7DF7, 0x7CFF,

0x8408, 0x8500, 0x8618, 0x8710, 0x8028, 0x8120, 0x8238, 0x8330,

0x8C48, 0x8D40, 0x8E58, 0x8F50, 0x8868, 0x8960, 0x8A78, 0x8B70,

0x9489, 0x9581, 0x9699, 0x9791, 0x90A9, 0x91A1, 0x92B9, 0x93B1,

0x9CC9, 0x9DC1, 0x9ED9, 0x9FD1, 0x98E9, 0x99E1, 0x9AF9, 0x9BF1,

0xA50A, 0xA402, 0xA71A, 0xA612, 0xA12A, 0xA022, 0xA33A, 0xA232,

0xAD4A, 0xAC42, 0xAF5A, 0xAE52, 0xA96A, 0xA862, 0xAB7A, 0xAA72,

0xB58B, 0xB483, 0xB79B, 0xB693, 0xB1AB, 0xB0A3, 0xB3BB, 0xB2B3,

0xBDCB, 0xBCC3, 0xBFDB, 0xBED3, 0xB9EB, 0xB8E3, 0xBBFB, 0xBAF3,

0xC60C, 0xC704, 0xC41C, 0xC514, 0xC22C, 0xC324, 0xC03C, 0xC134,

0xCE4C, 0xCF44, 0xCC5C, 0xCD54, 0xCA6C, 0xCB64, 0xC87C, 0xC974,

0xD68D, 0xD785, 0xD49D, 0xD595, 0xD2AD, 0xD3A5, 0xD0BD, 0xD1B5,

0xDECD, 0xDFC5, 0xDCDD, 0xDDD5, 0xDAED, 0xDBE5, 0xD8FD, 0xD9F5,

0xE70E, 0xE606, 0xE51E, 0xE416, 0xE32E, 0xE226, 0xE13E, 0xE036,

0xEF4E, 0xEE46, 0xED5E, 0xEC56, 0xEB6E, 0xEA66, 0xE97E, 0xE876,

0xF78F, 0xF687, 0xF59F, 0xF497, 0xF3AF, 0xF2A7, 0xF1BF, 0xF0B7,

0xFFCF, 0xFEC7, 0xFDDF, 0xFCD7, 0xFBEF, 0xFAE7, 0xF9FF, 0xF8F7,

};

unsigned short Crc (unsigned short lastCrc, unsigned long sizeOfBuffer,

unsigned char *buffer) {

unsigned long i;

unsigned char index;

for (i = 0L; i < sizeOfBuffer; i++) {

index = buffer[i] ^ ((unsigned char)(lastCrc & 0x00FF));

lastCrc = ((lastCrc >> 8) & 0x00FF) ^ (crcTable[index]);

}

return (lastCrc);

}



CRC Test Program

The following program can be used to test the above:

#include <stdio.h>

int main(void) {

unsigned char buffer [] = {0, 0, 0, 0, 0, 0x77, 0xCF};

printf(“CRC(Expected 0x73F3) = 0x%04X\n”, Crc(0x0, 7, buffer));

return(0);

}

NOTE: For the example above, the value for the last CRC

parameter should be initalized to zero (0).







Can anyone help me to understand this and point me in the right direction?



Thanks in advance,
Thanks,
Jeff Barnes

(FWH 16.11, xHarbour 1.2.3, Bcc730)
User avatar
Jeff Barnes
 
Posts: 929
Joined: Sun Oct 09, 2005 1:05 pm
Location: Ontario, Canada

Re: Generating a CRC

Postby Enrico Maria Giordano » Fri Feb 22, 2008 7:49 am

Try using HB_CRC32().

EMG
User avatar
Enrico Maria Giordano
 
Posts: 8718
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia

Postby Antonio Linares » Fri Feb 22, 2008 9:38 am

Jeff,

FWH provides:

nFileCRC( cFileName ) --> nCRC

nStrCRC( cString ) --> nCRC
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42118
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby Jeff Barnes » Fri Feb 22, 2008 2:31 pm

Enrico/Antonio,

The problem is that the CRC can only be a 4 char hex string.

Here is an example of the error codes returned with their correct CRC values:

DIAP000<%REQUEST CORRUPT>734D

DIAP000<%INVALID CRC CHAR>A471


I am just so lost on this one. I have send an email to the manufacturer of the device but I have no idea when they will reply and I need to provide an answer to end user today.

Any help you can provide will be greatly appreciated.
Thanks,
Jeff Barnes

(FWH 16.11, xHarbour 1.2.3, Bcc730)
User avatar
Jeff Barnes
 
Posts: 929
Joined: Sun Oct 09, 2005 1:05 pm
Location: Ontario, Canada

Postby Antonio Linares » Fri Feb 22, 2008 5:52 pm

Jeff,

You can use FWH DecToHex():

DecToHex( nFileCRC( cFileName ) )

DecToHex( nStrCRC( cString ) )
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42118
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby Jeff Barnes » Fri Feb 22, 2008 7:09 pm

Hi Antonio,

I've tried with the DecToHex() but still end up with an 8 char Hex number instead of the needed 4 char hex number as in the example below:


Header <command> CRC

DIAP000<%REQUEST CORRUPT>734D

DIAP000<%INVALID CRC CHAR>A471


I still have not had a reply from the manufacturer :-(
Thanks,
Jeff Barnes

(FWH 16.11, xHarbour 1.2.3, Bcc730)
User avatar
Jeff Barnes
 
Posts: 929
Joined: Sun Oct 09, 2005 1:05 pm
Location: Ontario, Canada

Postby Antonio Linares » Fri Feb 22, 2008 8:25 pm

Jeff,

A hex number of four characters can hold a number <= 65535

So if the number is larger than 65535 (FFFF) then you can not use four characters only.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42118
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby Jeff Barnes » Fri Feb 22, 2008 8:49 pm

I have written a small app that will send the command with 0000 to FFFF and see what CRC works. It is going to take a while but I can not figure out how they generate this 4 char hex either.

Thanks for the effort ... You know they will finally get back to me after it has been figured out :-)
Thanks,
Jeff Barnes

(FWH 16.11, xHarbour 1.2.3, Bcc730)
User avatar
Jeff Barnes
 
Posts: 929
Joined: Sun Oct 09, 2005 1:05 pm
Location: Ontario, Canada

Postby Enrico Maria Giordano » Fri Feb 22, 2008 9:45 pm

Maybe you'd need of a CRC16 function.

EMG
User avatar
Enrico Maria Giordano
 
Posts: 8718
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia

Postby Jeff Barnes » Fri Feb 22, 2008 11:42 pm

Is there a CRC16 function?
Thanks,
Jeff Barnes

(FWH 16.11, xHarbour 1.2.3, Bcc730)
User avatar
Jeff Barnes
 
Posts: 929
Joined: Sun Oct 09, 2005 1:05 pm
Location: Ontario, Canada

Postby Enrico Maria Giordano » Sat Feb 23, 2008 11:24 am

This is a function I used with Clipper long time ago:

Code: Select all  Expand view  RUN
#include "extend.h"


CLIPPER crc16()
{
    char *s = _parc( 1 );
    int crc = 0;
    int i, j;

    for ( i = 0; i < 128; i++ )
    {
        crc ^= *s++ << 8;

        for ( j = 0; j < 8; j++ )
            if ( crc & 0x8000 )
                crc = ( crc << 1 ) ^ 0x1021;
            else
                crc = crc << 1;
    }

    _retni( crc );
}


EMG
User avatar
Enrico Maria Giordano
 
Posts: 8718
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia

Postby Enrico Maria Giordano » Sat Feb 23, 2008 11:26 am

The fixed value of 128 has to be calculated using strlen() instead.

EMG
User avatar
Enrico Maria Giordano
 
Posts: 8718
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 58 guests