Any bit-twiddling, CRC-generation experts out there? I'm trying to implement an Xmodem CRC receive function. I have code from here in C# but it doesn't implement CRC on receiving, only on sending. I also have code from here in C that does implement CRC on receiving. The C# code looks like it was based on the C code.
I've got my code doing the CRC checking in what *I think* is the same way the C code is doing it, but when I connect to one of my company's remote devices and try to retrieve a file, the CRC values never match. I can retrieve a file fine using Xmodem CRC in Tera Term Pro when connecting to the same device (I'm doing this over sockets, not serial, if that matters).
The CRC-16 lookup table used by both the C and C# code are the same. Are these C/C# code blocks equivalent? And if they *are* equivalent, can anyone tell what I'm doing wrong that makes the crc comparison fail?? ('buf' contains the block of data received that needs to be checked; 'sz' is either 1024 or 128)
C#: private bool check(bool isCrc, byte[] buf, int index, int sz) { // 'index' has a value of '3' passed in
if (isCrc) {
ushort crc = CRC16.CRC16_ccitt(buf, index, sz);
ushort tcrc = (ushort)((buf[sz + index] << 8) + buf[sz + index + 1]);
if (crc == tcrc)
return true;
}
return false;
}
C: static int check(int crc, const unsigned char *buf, int sz) {
if (crc) {
unsigned short crc = crc16_ccitt(buf, sz);
unsigned short tcrc = (buf[sz]<<8)+buf[sz+1];
if (crc == tcrc)
return 1;
}
return 0;
}
------------------------------
And are these blocks equivalent?
C#: static public ushort CRC16_ccitt(byte[] buf, int index, int len) {
int counter;
ushort crc = 0;
for( counter = 0; counter < len; counter++)
crc = (ushort)((crc << 8) ^ crc16tab[((crc >> 8) ^ buf[index + counter]) & 0x00FF]);
return crc;
}
C: unsigned short crc16_ccitt(const void *buf, int len) {
register int counter;
register unsigned short crc = 0;
for( counter = 0; counter < len; counter++)
crc = (crc<<8) ^ crc16tab[((crc>>8) ^ *(char *)buf++)&0x00FF];
return crc;
}
Guest UserPosted Feb 11, 2009, 3:12 PM
Glad you got it working!
DavePosted Feb 11, 2009, 3:10 PM
I got it figured out. And it had absolutely nothing to do with the code snippets I posted. Doh! Guess I was too focused on that part because that's where the inequality of the CRC's showed up. That code works just fine.
My problem was that I wasn't reading the entire block into the buffer array before calling the 'check' method; I was stopping one byte short so was missing part of the sender's CRC value. It's always some dumb error. <:)
Thanx for reading/replying!
Dave
Guest UserPosted Feb 11, 2009, 2:10 PM
DavePosted Feb 11, 2009, 1:18 PM
The problem with that is that I don't know C at all and I'd have to write some kind of wrapper to call the Xmodem code. I might have to try to tackle that though.
Thanx,
Dave
Guest UserPosted Feb 11, 2009, 12:13 PM
If so, add a printf to display the index being calculated. Do the same with the C# code, using a Console.WriteLine() call. Compare the values being generated between the two loops.
DavePosted Feb 11, 2009, 12:00 PM
The 'index' parameter is needed (though it could have been hard-coded in the method instead of passed-in; it will always be '3') in the C# code. It tells the 'check' method where in the buffer array to start checking. I should have included the code that calls the 'check' method.
For C the call is: check(crc, &xbuff[3], bufsz)
For C# it's : check(true, xbuff, 3, bufsz)
Dave
Guest UserPosted Feb 11, 2009, 11:51 AM
I'd recommend removing "index" and all references to it.