The RadioReference.com Forums CRC-16 and CRC-32
 FAQ Members List Calendar Search Today's Posts Mark Forums Read

 Trunking Control Channel Decoding For discussion of installation, setup, configuration, and use of the Trunker / Unitrunker digital decoding utilities (for decoding Trunking control channels)

09-18-2013, 8:47 AM
 Member Premium Subscriber Amateur Radio Join Date: Jul 2002 Location: Sydney, Australia Posts: 388
CRC-16 and CRC-32

ActiveHat - I'm very curious as to what you're working on there!
09-18-2013, 9:59 AM
 Member Premium Subscriber Amateur Radio Join Date: Mar 2009 Location: Lakeland, Florida Posts: 155
Updated CRC methods

Here are the revised methods

Code:
```        static bool crc16(byte[] data)
{
uint polynom = 0x1021;
uint crc = 0xc921;
uint i, j, bit;

for (i = 0; i < 12; i++)
{
for (j = 0x80; j != 0; j >>= 1)
{
bit = crc & 0x8000;
crc <<= 1;
if ((data[i] & j) != 0)
bit ^= 0x8000;
if (bit != 0)
crc ^= polynom;
}
}

return (crc & 0xFFFF) != 0 ? false : true;
}

static bool crc32(byte[] data, int length)
{
ulong polynom = 0x04c11db7;
ulong crc = 0x0;
ulong crcxor = 0xFFFFFFFF;
ulong j, bit, crcin;

//Last four bytes are CRC check value
crcin = (ulong)((data[length - 4] << 24) | (data[length - 3] << 16) | (data[length - 2] << 8) | data[length - 1]) & 0xFFFFFFFF;

for (int i = 0; i < length - 4; i++)
{
for (j = 0x80; j != 0; j >>= 1)
{
bit = crc & 0x80000000;
crc <<= 1;
if ((data[i] & j) != 0)
bit ^= 0x80000000;
if (bit != 0)
crc ^= polynom;
}
}

crc ^= crcxor;
crc &= 0xFFFFFFFF;
return (crc ^ crcin) != 0 ? false : true;
}```
Call them with your data like
Code:
```            byte[] header = { 0x37, 0xFD, 0x00, 0x35, 0xF1, 0x24, 0x82, 0x31, 0xBE, 0xE0, 0x73, 0xA9 };

if (crc_ok)
{
int length = (int)(header[6] & 0x7F) * 12;

// First 12 bytes are first data message second 12 are last data message (last four bytes are CRC32 checksum)
byte[] data = { 01, 0xA7, 0x35, 0xF1, 0x24, 0x5A, 0xC9, 0x5B, 0x90, 0xDC, 0x35, 0x02, 0x42, 0x5B, 0x4B, 0xDA, 0x59, 0x87, 0x81, 0x34, 0x40, 0x1C, 0xCF, 0xB0 };
crc_ok = crc32(data, length);
}```
There certainly may be better ways to do this but this will get you started.
__________________
K4USF
Yaesu FT-450 | FT-8900 | FT-7900 | BCD396XT | BR330T | Pro-160 (2) | Pro-94 | Pro 34
09-18-2013, 7:19 PM
 Member Audio Feed Provider Join Date: Feb 2009 Location: Omaha, NE Posts: 721

Quote:
 Originally Posted by aharry Here are the revised methods Code: ``` static bool crc16(byte[] data) { uint polynom = 0x1021; uint crc = 0xc921; uint i, j, bit; for (i = 0; i < 12; i++) { for (j = 0x80; j != 0; j >>= 1) { bit = crc & 0x8000; crc <<= 1; if ((data[i] & j) != 0) bit ^= 0x8000; if (bit != 0) crc ^= polynom; } } return (crc & 0xFFFF) != 0 ? false : true; } static bool crc32(byte[] data, int length) { ulong polynom = 0x04c11db7; ulong crc = 0x0; ulong crcxor = 0xFFFFFFFF; ulong j, bit, crcin; //Last four bytes are CRC check value crcin = (ulong)((data[length - 4] << 24) | (data[length - 3] << 16) | (data[length - 2] << 8) | data[length - 1]) & 0xFFFFFFFF; for (int i = 0; i < length - 4; i++) { for (j = 0x80; j != 0; j >>= 1) { bit = crc & 0x80000000; crc <<= 1; if ((data[i] & j) != 0) bit ^= 0x80000000; if (bit != 0) crc ^= polynom; } } crc ^= crcxor; crc &= 0xFFFFFFFF; return (crc ^ crcin) != 0 ? false : true; }``` Call them with your data like Code: ``` byte[] header = { 0x37, 0xFD, 0x00, 0x35, 0xF1, 0x24, 0x82, 0x31, 0xBE, 0xE0, 0x73, 0xA9 }; bool crc_ok = crc16(header); if (crc_ok) { int length = (int)(header[6] & 0x7F) * 12; // First 12 bytes are first data message second 12 are last data message (last four bytes are CRC32 checksum) byte[] data = { 01, 0xA7, 0x35, 0xF1, 0x24, 0x5A, 0xC9, 0x5B, 0x90, 0xDC, 0x35, 0x02, 0x42, 0x5B, 0x4B, 0xDA, 0x59, 0x87, 0x81, 0x34, 0x40, 0x1C, 0xCF, 0xB0 }; crc_ok = crc32(data, length); }``` There certainly may be better ways to do this but this will get you started.
Everything works perfectly! Thanks a lot for your help. Turns out I get a few bad transmissions here and there (even when I collected the data right next to the tower).
__________________

09-18-2013, 7:29 PM
 Member Audio Feed Provider Join Date: Feb 2009 Location: Omaha, NE Posts: 721

Quote:
 Originally Posted by MattSR ActiveHat - I'm very curious as to what you're working on there!
I am working on a P25 Decoder Library that is coded in C# / .NET. The end result is the ability to subscribe to "events" when certain Opcodes are detected and extract the data from them without needing to know anything about the protocol. This project will also help newbies understand the protocol so they don't have to start the way I did. This project will be completely free and open source. I'm hoping this will spur some interesting programs / projects from it. One major benefit that this library provides and taking any kind of output of a control channel and "extracting" the P25 message. It does a regex match for a message meaning any type of output would work from any scanner as long as it meets basic requirements.

I personally plan to use this library to make a project similar to Pro96Com but without remote control. I'm not trying to making competing products (seeing as I want mine to be free) but just offering another option (never can have too many). I do plan to make a commercial part of the project that runs as a service in Windows and logs events into a database. I also plan to have an option to record audio so it can link audio with a radio key up. I have 4 input streams (one for each dispatch channel of a local police department) and another radio that only does decoding, this project will host a local website (on the computer) that allows me to see who was keying up, what frequency and talkgroup, and then play back the audio. I just store all the audio (and database data) on a 3 TB hard drive and I can hold years of information (it won't store dead air).

My next project will be an open source library for controlling scanners that have a protocol in place.
__________________