private void Encode(uint crcInitialValue = 0x0)
        {
            var bytes             = new List <byte>();
            var frameControlByte0 = (byte)Type;

            if (FramePending)
            {
                frameControlByte0 |= (0x1 << 4);
            }
            bytes.Add(frameControlByte0);
            bytes.Add(0); // frameControlByte1

            bytes.Add(DataSequenceNumber);
            if (AddressInformation != null && AddressInformation.Bytes.Count > 0)
            {
                bytes.AddRange(AddressInformation.Bytes);
            }
            if (Payload != null && Payload.Count > 0)
            {
                bytes.AddRange(Payload);
            }

            var crcLength = CRCPolynomial.GetLength();
            var crc       = CalculateCRC(bytes, crcInitialValue, CRCPolynomial);

            switch (crcLength)
            {
            case 2:
                bytes.Add(crc[0]);
                bytes.Add(crc[1]);
                break;

            case 4:
                bytes.Add(crc[0]);
                bytes.Add(crc[1]);
                bytes.Add(crc[2]);
                bytes.Add(crc[3]);
                break;

            default:
                Logger.Log(LogLevel.Error, "Cannot generate CRC of invalid length {0}, the packet will not contain CRC data", crcLength);
                break;
            }

            Bytes = bytes.ToArray();
        }
        public bool CheckCRC(uint crcInitialValue = 0x0)
        {
            var crcLength = CRCPolynomial.GetLength();
            var crc       = CalculateCRC(Bytes.Take(Bytes.Length - crcLength), crcInitialValue, CRCPolynomial);

            // Byte little endian order
            switch (crcLength)
            {
            case 2:
                return(Bytes[Bytes.Length - 2] == crc[0] && Bytes[Bytes.Length - 1] == crc[1]);

            case 4:
                return(Bytes[Bytes.Length - 4] == crc[0] && Bytes[Bytes.Length - 3] == crc[1] && Bytes[Bytes.Length - 2] == crc[2] && Bytes[Bytes.Length - 1] == crc[3]);

            default:
                Logger.Log(LogLevel.Error, "Cannot check CRC of invalid length {0}", crcLength);
                return(false);
            }
        }
Exemple #3
0
        /// <summary>
        /// Generates a CRC using a common polynomial for the next closest bitlength above that specified.
        /// For example, a bit length of 13 through 16 will use the CCITT16 polynomial masking off bits necessary to maintain the specified bitlength.
        /// </summary>
        /// <param name="data">Data to generate a CRC for</param>
        /// <param name="offset">The offset into the source data at which to start the CRC</param>
        /// <param name="length">The number of bytes in the source data to analyze</param>
        /// <param name="polynomial">Standard polynomial to use for the CRC</param>
        /// <param name="seedCRC">CRC seed value</param>
        /// <returns>The CRC</returns>
        /// <returns></returns>
        public static ulong GenerateChecksum(byte[] data, int offset, int length, CRCPolynomial polynomial, ulong seedCRC)
        {
            int bits = 0;

            switch (polynomial)
            {
            case CRCPolynomial.CRC_8:
                bits = 8;
                break;

            case CRCPolynomial.CRC_10:
                bits = 10;
                break;

            case CRCPolynomial.CRC_12:
                bits = 12;
                break;

            case CRCPolynomial.CRC_16:
            case CRCPolynomial.CRC_16ARC:
            case CRCPolynomial.CRC_CCITT16:
                bits = 16;
                break;

            case CRCPolynomial.CRC_24:
                bits = 24;
                break;

            case CRCPolynomial.CRC_CCITT32:
            case CRCPolynomial.CRC_32:
                bits = 32;
                break;

            case CRCPolynomial.CRC_64:
                bits = 64;
                break;
            }

            return(GenerateChecksum(data, offset, length, bits, (ulong)polynomial, seedCRC));
        }
Exemple #4
0
 public static ulong GenerateChecksum(byte[] data, int crcBitLength, CRCPolynomial polynomial)
 {
     return(GenerateChecksum(data, crcBitLength, (ulong)polynomial, 0));
 }
Exemple #5
0
 public static ulong GenerateChecksum(byte[] data, int crcBitLength, CRCPolynomial polynomial)
 {
     return GenerateChecksum(data, crcBitLength, (ulong)polynomial, 0L);
 }
Exemple #6
0
        public static ulong GenerateChecksum(byte[] data, int offset, int length, CRCPolynomial polynomial, ulong seedCRC)
        {
            int crcBitLength = 0;
            switch (polynomial)
            {
                case CRCPolynomial.CRC_10:
                    crcBitLength = 10;
                    break;

                case CRCPolynomial.CRC_12:
                    crcBitLength = 12;
                    break;

                case CRCPolynomial.CRC_CCITT16:
                case CRCPolynomial.CRC_16ARC:
                case CRCPolynomial.CRC_16:
                    crcBitLength = 0x10;
                    break;

                case CRCPolynomial.CRC_64:
                    crcBitLength = 0x40;
                    break;

                case CRCPolynomial.CRC_8:
                    crcBitLength = 8;
                    break;

                case CRCPolynomial.CRC_24:
                    crcBitLength = 0x18;
                    break;

                case CRCPolynomial.CRC_32:
                case CRCPolynomial.CRC_CCITT32:
                    crcBitLength = 0x20;
                    break;
            }
            return GenerateChecksum(data, offset, length, crcBitLength, (ulong)polynomial, seedCRC);
        }