private void cbDataCheckType_SelectedIndexChanged(object sender, EventArgs e) { dataWidth = 8; if (_DataBytes == null) { return; } gbCRCParam.Enabled = false; int index = cbDataCheckType.SelectedIndex; if (index == 0) { dataWidth = 16; } else if (index == 1) { dataWidth = 8; } else if (index == 2) { dataWidth = 8; } else { gbCRCParam.Enabled = true; CRCType crcType = (CRCType)(index - 3); CRCInfo crcInfo = DataCheck.GetCRCInfo(crcType); chkRefIn.Checked = crcInfo.RefIn; chkRefOut.Checked = crcInfo.RefOut; chkXorOut.Checked = crcInfo.XorOut == 0 ? false : true; if (crcType >= CRCType.CRC16_IBM && crcType <= CRCType.CRC16_DNP) { txtPoly.Text = string.Format("{0:X4}", crcInfo.Poly); txtInit.Text = string.Format("{0:X4}", crcInfo.Init); dataWidth = 16; } else if (crcType >= CRCType.CRC32 && crcType <= CRCType.CRC32_MPEG2) { txtPoly.Text = string.Format("{0:X8}", crcInfo.Poly); txtInit.Text = string.Format("{0:X8}", crcInfo.Init); dataWidth = 32; } } CalCheckData(); }
static public CRCInfo GetCRCInfo(CRCType type) { CRCInfo param = null; switch (type) { case CRCType.CRC16_IBM: param = new CRCInfo(0x8005, 0x0000, true, true, 0x0000); break; case CRCType.CRC16_MAXIM: param = new CRCInfo(0x8005, 0x0000, true, true, 0xFFFF); break; case CRCType.CRC16_USB: param = new CRCInfo(0x8005, 0xFFFF, true, true, 0xFFFF); break; case CRCType.CRC16_MODBUS: param = new CRCInfo(0x8005, 0xFFFF, true, true, 0x0000); break; case CRCType.CRC16_CCITT: param = new CRCInfo(0x1021, 0x0000, true, true, 0x0000); break; case CRCType.CRC16_CCITT_FALSE: param = new CRCInfo(0x1021, 0xFFFF, false, false, 0x0000); break; case CRCType.CRC16_X25: param = new CRCInfo(0x1021, 0xFFFF, true, true, 0xFFFF); break; case CRCType.CRC16_XMODEM: param = new CRCInfo(0x1021, 0x0000, false, false, 0x0000); break; case CRCType.CRC16_DNP: param = new CRCInfo(0x3D65, 0x0000, true, true, 0xFFFF); break; case CRCType.CRC32: param = new CRCInfo(0x04C11DB7, 0xFFFFFFFF, true, true, 0xFFFFFFFF); break; case CRCType.CRC32_MPEG2: param = new CRCInfo(0x04C11DB7, 0xFFFFFFFF, false, false, 0x00000000); break; } return(param); }
public static ICRC GetCRC(this CRCType cRCType) { if (cRCType == CRCType.CRC8) { return(new CRC8()); } if (cRCType == CRCType.CRC16) { return(new CRC16()); } return(new CRC32()); }
private bool CheckHeader(CRCType crcType, byte[] data, int len, out Header hdr) { if (CheckCRC(crcType, data, len)) { hdr = new Header(data); return(true); } else { hdr = new Header(); return(false); } }
static public UInt32 GetCRC(CRCType type, byte[] data) { CRCInfo param; param = GetCRCInfo(type); if (type >= CRCType.CRC16_IBM && type <= CRCType.CRC16_DNP) { return(GetCRC16(param, data)); } else if (type >= CRCType.CRC32 && type <= CRCType.CRC32_MPEG2) { return(GetCRC32(param, data)); } return(0); }
public static int GetLength(this CRCType type) { switch (type) { case CRCType.CRC16CCITTPolynomial: case CRCType.CRC16Polynomial: return(2); case CRCType.CRC32CCITTPolynomial: return(4); default: var result = (uint)type > 0xFFFF ? 4 : 2; // we will assume that a long polynomial has a long CRC Logger.Log(LogLevel.Warning, "Unknown CRC type length for polynomial 0x{0:X}. Guessed {1} bytes.", (int)type, result); return(result); } }
public static string CalculateCheckSum(byte[] byteArray, CRCType crcType) { string checkSumString = string.Empty; switch (crcType) { case CRCType.Mod95: int c = CRC.Mod95(byteArray); checkSumString += c.ToString(); break; case CRCType.XOR: int d = CRC.XOR(byteArray); checkSumString += d.ToString(); break; case CRCType.CRC16: int data = CRC.crc_mcl(byteArray); byte[] chk = new byte[2]; chk[0] = (byte)(data & ('\x00FF')); chk[1] = (byte)(data >> 8); checkSumString += chk[0].ToString() + ","; checkSumString += chk[1].ToString(); break; case CRCType.CRC_CCITT_Kermit: int da = CRC.CRC_CCITTKermit(byteArray); byte[] a = new byte[2]; a[1] = (byte)(da & ('\x00FF')); a[0] = (byte)(da >> 8); checkSumString += a[0].ToString() + ","; checkSumString += a[1].ToString(); break; default: break; } return(checkSumString); }
private bool CheckCRC(CRCType crcType, byte[] data, int len) { if (crcType == CRCType.CRC32) { uint crc = Crc32.Update(Crc32.InitialValue, data, 0, len - 4) ^ Crc32.XorValue; //Debug.WriteLine("CRC32: {0:x8}", crc); uint crcfld = (((uint)data[len - 4]) | ((uint)data[len - 3] << 8) | ((uint)data[len - 2] << 16) | ((uint)data[len - 1] << 24)); return(crc == crcfld); } else { // CRC16 ushort crc = Crc16.Update(Crc16.InitialValue, data, 0, len - 2); //Debug.WriteLine("CRC16: {0:x4}", crc); ushort crcfld = (ushort)((data[len - 2] << 8) | data[len - 1]); return(crc == crcfld); } }
public static CheckSumRV CalculateCheckSum(byte[] byteArray, CRCType crcType) { switch (crcType) { case CRCType.SUM: return(Sum(byteArray)); case CRCType.Mod95: return(Mod95(byteArray)); case CRCType.XOR: return(XOR(byteArray)); case CRCType.CRC16: return(CRC16(byteArray)); case CRCType.CRC_CCITT_Kermit: return(CRC_CCITT_Kermit(byteArray)); case CRCType.CRC32: return(GetCRC32CheckSum(byteArray)); case CRCType.SumComplement: return(SumComplement(byteArray)); default: return(null); } }
/// <summary> /// Constructor for custom 32-bit CRC object - Don't use this unless you really know /// what the heck you are doing. /// </summary> /// <param name="KeyPoly">Custom key polynomial</param> /// <param name="InitialRegVal">Initial register value</param> /// <param name="FinalizeXorVal">Value that is xor'd with final CRC</param> /// <param name="Reflected">Indicates whether the algorithm expects reflected input bytes</param> /// <param name="BytesShiftedPerCycle">How many bytes are handled at a time (1 or 2). /// <param name="CrcType">Indicates whether CRC is incremental (incomplete) or oneshot (complete).</param> /// <param name="CrcCalcMethod">How many bytes are handled at a time (1 or 2). /// The internal table size is determined by this parameter, 1 is most common (leads to 1kbyte table).</param> public CRC32(UInt32 KeyPoly, UInt32 InitialRegVal, UInt32 FinalizeXorVal, Boolean Reflected, Int32 BytesShiftedPerCycle, CRCType CrcType, CRCCalcMethod CrcCalcMethod) { lut = null; poly = KeyPoly; initReg = InitialRegVal; currCRC = initReg; finalReg = FinalizeXorVal; reflected = Reflected; NumBytesPerRegShift = BytesShiftedPerCycle; this.CrcType = CrcType; this.CrcCalcMethod = CrcCalcMethod; // Build the look up table BuildTable(); // Call reset to set initial value for currCRC; ResetCRC(); }
public CRCEngine(CRCType polynomial) { this.reversedPolynomial = polynomial.GetLength() == 4 ? BitHelper.ReverseBits((uint)polynomial) : BitHelper.ReverseBits((ushort)polynomial); // this cast is needed to rotate only lower bits }
public static Frame CreateACK(byte sequenceNumber, bool pending, uint crcInitialValue = 0x0, CRCType crcPolynomial = CRCType.CRC16CCITTPolynomial) { var result = new Frame(); result.Type = FrameType.ACK; result.CRCPolynomial = crcPolynomial; result.FramePending = pending; result.DataSequenceNumber = sequenceNumber; result.Encode(crcInitialValue); return(result); }
public static Frame CreateAckForFrame(byte[] frame, uint crcInitialValue = 0x0, CRCType crcPolynomial = CRCType.CRC16CCITTPolynomial) { var sequenceNumber = frame[2]; // TODO: here we set pending bit as false return(CreateACK(sequenceNumber, false, crcInitialValue, crcPolynomial)); }
/// <summary> /// Basic Constructor except with a different key (divisor) polynomial /// </summary> /// <param name="KeyPoly">The user-provided key polynomial (hex number of bits[31-0])</param> /// <param name="CrcType">Indicates whether CRC is incremental (incomplete) or oneshot (complete).</param> public CRC32(UInt32 KeyPoly, CRCType CrcType) : this(KeyPoly, 0xFFFFFFFF, 0xFFFFFFFF, true, 1, CrcType, CRCCalcMethod.LUT) { }
/// <summary> /// Constructor for custom 32-bit CRC object - Don't use this unless you really know /// what the heck you are doing. /// </summary> /// <param name="KeyPoly">Custom key polynomial</param> /// <param name="InitialRegVal">Initial register value</param> /// <param name="FinalizeXorVal">Value that is xor'd with final CRC</param> /// <param name="Reflected">Indicates whether the algorithm expects reflected input bytes</param> /// <param name="BytesShiftedPerCycle">How many bytes are handled at a time (1 or 2). /// <param name="CrcType">Indicates whether CRC is incremental (incomplete) or oneshot (complete).</param> /// <param name="CrcCalcMethod">How many bytes are handled at a time (1 or 2). /// The internal table size is determined by this parameter, 1 is most common (leads to 1kbyte table).</param> public CRC32( UInt32 KeyPoly, UInt32 InitialRegVal, UInt32 FinalizeXorVal, Boolean Reflected, Int32 BytesShiftedPerCycle, CRCType CrcType, CRCCalcMethod CrcCalcMethod ) { lut = null; poly = KeyPoly; initReg = InitialRegVal; currCRC = initReg; finalReg = FinalizeXorVal; reflected = Reflected; NumBytesPerRegShift = BytesShiftedPerCycle; this.CrcType = CrcType; this.CrcCalcMethod = CrcCalcMethod; // Build the look up table BuildTable(); // Call reset to set initial value for currCRC; ResetCRC(); }
// サーバからの受信データを解析する // Readerクラスから呼ばれる public override void OnReception(ByteDataFragment fragment) { Interlocked.Exchange(ref _lastReceptionTimeUtcTicks, DateTime.UtcNow.Ticks); byte[] data = fragment.Buffer; int offset = fragment.Offset; int length = fragment.Length; //Debug.WriteLine(String.Format("OnReception len={0} state={1}", length, _state.ToString())); if (_state == State.None || _state == State.Error || Volatile.Read(ref _aborting)) { return; } string errorMessage = null; for (int i = 0; i < length; i++) { if (Volatile.Read(ref _aborting)) { return; } byte c = data[offset + i]; // abort sequence detection if (c == CAN) { _canCount++; if (_canCount > 5) { _state = State.None; // don't accept any more ProcessAbortByPeer(); return; } } else { _canCount = 0; } // 0x11, 0x13, 0x81, 0x83は無視する if ((c & 0x7f) == XON || (c & 0x7f) == XOFF) continue; CheckByte: switch (_state) { case State.WaitingZPAD: { switch (c) { case ZPAD: _state = State.WaitingZDLE; break; default: break; } } break; case State.WaitingZDLE: { switch (c) { case ZPAD: break; case ZDLE: _state = State.GetHeaderFormat; break; default: _state = State.WaitingZPAD; break; } } break; case State.GetHeaderFormat: { switch (c) { case ZBIN: //Debug.WriteLine("ZBIN"); _crcType = CRCType.CRC16; _bytesNeeded = 7; _state = State.GetBinaryData; break; case ZHEX: //Debug.WriteLine("ZHEX"); _crcType = CRCType.CRC16; _bytesNeeded = 7; _state = State.GetHexData; break; case ZBIN32: //Debug.WriteLine("ZBIN32"); _crcType = CRCType.CRC32; _bytesNeeded = 9; _state = State.GetBinaryData; break; default: _state = State.WaitingZPAD; break; } // initialize variables _rcvPacketLen = 0; _hexLo = false; _gotZDLE = false; } break; case State.GetBinaryData: { // binary('A') or binary('C') data if (_gotZDLE) { // unescape _rcvPacket[_rcvPacketLen++] = (byte)(c ^ 0x40); _bytesNeeded--; _gotZDLE = false; } else if (c == ZDLE) { _gotZDLE = true; } else { _rcvPacket[_rcvPacketLen++] = c; _bytesNeeded--; _gotZDLE = false; } if (_bytesNeeded <= 0) { _state = State.WaitingZPAD; Header hdr; if (CheckHeader(_crcType, _rcvPacket, _rcvPacketLen, out hdr)) { ProcessHeader(hdr); if (hdr.Type == ZDATA) { _state = State.GetFileData; _rcvPacketLen = 0; _gotZDLE = false; } else if (hdr.Type == ZFILE) { _state = State.GetFileInfo; _rcvPacketLen = 0; _gotZDLE = false; } } } } break; case State.GetHexData: { // HEX('B') data if ((c >= '0') && (c <= '9')) { c -= 0x30; } else if ((c >= 'a') && (c <= 'f')) { c -= 0x57; } else { Debug.WriteLine("Unexpected character in {0}", _state); errorMessage = XZModemPlugin.Instance.Strings.GetString("Message.ZModem.InvalidHeader"); goto Error; } if (_hexLo) { // lower _rcvPacket[_rcvPacketLen++] |= c; _hexLo = false; _bytesNeeded--; if (_bytesNeeded <= 0) { Header hdr; if (CheckHeader(_crcType, _rcvPacket, _rcvPacketLen, out hdr)) { ProcessHeader(hdr); _state = State.GetHexEOL; _bytesNeeded = 2; // CR LF } else { _state = State.WaitingZPAD; } } } else { // upper _rcvPacket[_rcvPacketLen] = (byte)(c << 4); _hexLo = true; } } break; case State.GetHexEOL: { byte cc = (byte)(c & 0x7f); // sz sends { 0x0d, 0x8a } as CR/LF if (cc == 0x0a || cc == 0x0d) { _bytesNeeded--; if (_bytesNeeded <= 0) { _state = State.WaitingZPAD; } } else { _state = State.WaitingZPAD; goto CheckByte; } } break; case State.GetFileInfo: case State.GetFileData: { if (_rcvPacketLen >= _rcvPacket.Length) { Debug.WriteLine("Buffer full in {0}", _state); errorMessage = XZModemPlugin.Instance.Strings.GetString("Message.ZModem.BufferFull"); goto Error; } if (_gotZDLE) { if (c == ZCRCE || c == ZCRCG || c == ZCRCQ || c == ZCRCW) { // end of frame. need CRC bytes. _rcvPacket[_rcvPacketLen++] = c; _gotZDLE = false; _bytesNeeded = (_crcType == CRCType.CRC32) ? 4 : 2; // CRC bytes _state = (_state == State.GetFileInfo) ? State.GetFileInfoCRC : (_state == State.GetFileData) ? State.GetFileDataCRC : State.Error; } else { // unescape _rcvPacket[_rcvPacketLen++] = (byte)(c ^ 0x40); _gotZDLE = false; } } else if (c == ZDLE) { _gotZDLE = true; } else { _rcvPacket[_rcvPacketLen++] = c; _gotZDLE = false; } } break; case State.GetFileInfoCRC: case State.GetFileDataCRC: { if (_rcvPacketLen >= _rcvPacket.Length) { Debug.WriteLine("Buffer full in {0}", _state); errorMessage = XZModemPlugin.Instance.Strings.GetString("Message.ZModem.BufferFull"); goto Error; } if (_gotZDLE) { // unescape _rcvPacket[_rcvPacketLen++] = (byte)(c ^ 0x40); _bytesNeeded--; _gotZDLE = false; } else if (c == ZDLE) { _gotZDLE = true; } else { _rcvPacket[_rcvPacketLen++] = c; _bytesNeeded--; _gotZDLE = false; } if (_bytesNeeded <= 0) { int dataLen = _rcvPacketLen - (_crcType == CRCType.CRC32 ? 5 : 3); if (_state == State.GetFileInfoCRC) { if (CheckCRC(_crcType, _rcvPacket, _rcvPacketLen)) { ParseFileInfo(_rcvPacket, 0, dataLen); _rcvPacketLen = 0; _gotZDLE = false; _state = State.WaitingZPAD; } else { Debug.WriteLine("CRC Error in {0}", _state); errorMessage = XZModemPlugin.Instance.Strings.GetString("Message.ZModem.CRCError"); goto Error; } } else if (_state == State.GetFileDataCRC) { byte frameType = _rcvPacket[dataLen]; //Debug.WriteLine("frameType = 0x{0:x2}", frameType); if (CheckCRC(_crcType, _rcvPacket, _rcvPacketLen)) { ProcessFileData(_rcvPacket, 0, dataLen); _rcvPacketLen = 0; _gotZDLE = false; if (frameType == ZCRCE) { // finished _state = State.WaitingZPAD; } else if (frameType == ZCRCW) { SendACK(); // read next subpacket _state = State.WaitingZPAD; } else { // read next subpacket _state = State.GetFileData; } } else { Debug.WriteLine("CRC Error in {0}", _state); errorMessage = XZModemPlugin.Instance.Strings.GetString("Message.ZModem.CRCError"); goto Error; } } } } break; } } return; Error: _state = State.Error; Abort(errorMessage, false); }
public CRCChecksum() { cr = new Dictionary <CRCType, ICRC>(); CRCType = CRCType.None; }
private void CalCheckData() { try { UInt32 checkResult = 0; if (_DataBytes == null) { return; } gbCRCParam.Enabled = false; int index = cbDataCheckType.SelectedIndex; if (index == -1) { return; } if (index == 0) { checkResult = Convert.ToUInt16(DataCheck.GetCheckSum(_DataBytes) & 0xFFFF); dataWidth = 16; } else if (index == 1) { checkResult = Convert.ToByte(DataCheck.GetCheckSum(_DataBytes) & 0xFF); dataWidth = 8; } else if (index == 2) { checkResult = DataCheck.GetXor(_DataBytes); dataWidth = 8; } else { gbCRCParam.Enabled = true; CRCType crcType = (CRCType)(index - 3); CRCInfo crcInfo = DataCheck.GetCRCInfo(crcType); crcInfo.Poly = Convert.ToUInt32(txtPoly.Text, 16); crcInfo.Init = Convert.ToUInt32(txtInit.Text, 16); crcInfo.RefIn = chkRefIn.Checked; crcInfo.RefOut = chkRefOut.Checked; crcInfo.XorOut = chkXorOut.Checked ? 0xFFFFFFFF : 0x00000000; if (crcType >= CRCType.CRC16_IBM && crcType <= CRCType.CRC16_DNP) { checkResult = DataCheck.GetCRC16(crcInfo, _DataBytes); dataWidth = 16; } else if (crcType >= CRCType.CRC32 && crcType <= CRCType.CRC32_MPEG2) { checkResult = DataCheck.GetCRC32(crcInfo, _DataBytes); dataWidth = 32; } } CheckResultValue = checkResult; txtResult.Text = getStringByUint32(CheckResultValue, chkIsLittleEndian.Checked, dataWidth); } catch (System.Exception ex) { MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); } }
public Frame(byte[] data, CRCType crcPolynomial = CRCType.CRC16CCITTPolynomial) { Bytes = data; CRCPolynomial = crcPolynomial; Decode(data); }
protected override void ProcessHeader(Header hdr) { switch (hdr.Type) { case ZRINIT: Debug.WriteLine("Got ZRINIT"); if (_afterZRPOS) { Debug.WriteLine("--> ZFIN"); SendZFIN(); } else { int bufSize = (hdr.ZP1 << 8) | hdr.ZP0; _frameSize = Math.Min(Math.Max(_frameSize, bufSize), MAX_BLOCK); _txCrcType = ((hdr.ZF0 & CANFC32) != 0) ? CRCType.CRC32 : CRCType.CRC16; SendZFILE(); } break; case ZRPOS: { Debug.WriteLine("Got ZRPOS"); _afterZRPOS = true; uint pos = ((uint)hdr.ZP3 << 24) | ((uint)hdr.ZP2 << 16) | ((uint)hdr.ZP1 << 8) | ((uint)hdr.ZP0); Volatile.Write(ref _filePosReq, (uint)Math.Min(Math.Max(0, pos), _fileSize)); Debug.WriteLine("_filePosReq = {0}", _filePosReq); Volatile.Write(ref _filePosReqChanged, true); if (_sendingTask == null) { _sendingTask = Task.Run(() => SendZDATA(_cancellation.Token), _cancellation.Token); } } break; case ZFIN: Debug.WriteLine("Got ZFIN"); SendOverAndOut(); Completed(false, true, _fileSkipped ? XZModemPlugin.Instance.Strings.GetString("Message.ZModem.FileSkipped") : XZModemPlugin.Instance.Strings.GetString("Message.XModem.SendComplete")); break; case ZSKIP: Debug.WriteLine("Got ZSKIP"); _fileSkipped = true; SendZFIN(); break; case ZACK: Debug.WriteLine("Got ZACK"); break; default: Debug.WriteLine("Unknown Header : 0x{0:x2}", hdr.Type); break; } }
// サーバからの受信データを解析する // Readerクラスから呼ばれる public override void OnReception(ByteDataFragment fragment) { Interlocked.Exchange(ref _lastReceptionTimeUtcTicks, DateTime.UtcNow.Ticks); byte[] data = fragment.Buffer; int offset = fragment.Offset; int length = fragment.Length; //Debug.WriteLine(String.Format("OnReception len={0} state={1}", length, _state.ToString())); if (_state == State.None || _state == State.Error || Volatile.Read(ref _aborting)) { return; } string errorMessage = null; for (int i = 0; i < length; i++) { if (Volatile.Read(ref _aborting)) { return; } byte c = data[offset + i]; // abort sequence detection if (c == CAN) { _canCount++; if (_canCount > 5) { _state = State.None; // don't accept any more ProcessAbortByPeer(); return; } } else { _canCount = 0; } // 0x11, 0x13, 0x81, 0x83は無視する if ((c & 0x7f) == XON || (c & 0x7f) == XOFF) { continue; } CheckByte: switch (_state) { case State.WaitingZPAD: { switch (c) { case ZPAD: _state = State.WaitingZDLE; break; default: break; } } break; case State.WaitingZDLE: { switch (c) { case ZPAD: break; case ZDLE: _state = State.GetHeaderFormat; break; default: _state = State.WaitingZPAD; break; } } break; case State.GetHeaderFormat: { switch (c) { case ZBIN: //Debug.WriteLine("ZBIN"); _crcType = CRCType.CRC16; _bytesNeeded = 7; _state = State.GetBinaryData; break; case ZHEX: //Debug.WriteLine("ZHEX"); _crcType = CRCType.CRC16; _bytesNeeded = 7; _state = State.GetHexData; break; case ZBIN32: //Debug.WriteLine("ZBIN32"); _crcType = CRCType.CRC32; _bytesNeeded = 9; _state = State.GetBinaryData; break; default: _state = State.WaitingZPAD; break; } // initialize variables _rcvPacketLen = 0; _hexLo = false; _gotZDLE = false; } break; case State.GetBinaryData: { // binary('A') or binary('C') data if (_gotZDLE) { // unescape _rcvPacket[_rcvPacketLen++] = (byte)(c ^ 0x40); _bytesNeeded--; _gotZDLE = false; } else if (c == ZDLE) { _gotZDLE = true; } else { _rcvPacket[_rcvPacketLen++] = c; _bytesNeeded--; _gotZDLE = false; } if (_bytesNeeded <= 0) { _state = State.WaitingZPAD; Header hdr; if (CheckHeader(_crcType, _rcvPacket, _rcvPacketLen, out hdr)) { ProcessHeader(hdr); if (hdr.Type == ZDATA) { _state = State.GetFileData; _rcvPacketLen = 0; _gotZDLE = false; } else if (hdr.Type == ZFILE) { _state = State.GetFileInfo; _rcvPacketLen = 0; _gotZDLE = false; } } } } break; case State.GetHexData: { // HEX('B') data if ((c >= '0') && (c <= '9')) { c -= 0x30; } else if ((c >= 'a') && (c <= 'f')) { c -= 0x57; } else { Debug.WriteLine("Unexpected character in {0}", _state); errorMessage = XZModemPlugin.Instance.Strings.GetString("Message.ZModem.InvalidHeader"); goto Error; } if (_hexLo) // lower { _rcvPacket[_rcvPacketLen++] |= c; _hexLo = false; _bytesNeeded--; if (_bytesNeeded <= 0) { Header hdr; if (CheckHeader(_crcType, _rcvPacket, _rcvPacketLen, out hdr)) { ProcessHeader(hdr); _state = State.GetHexEOL; _bytesNeeded = 2; // CR LF } else { _state = State.WaitingZPAD; } } } else // upper { _rcvPacket[_rcvPacketLen] = (byte)(c << 4); _hexLo = true; } } break; case State.GetHexEOL: { byte cc = (byte)(c & 0x7f); // sz sends { 0x0d, 0x8a } as CR/LF if (cc == 0x0a || cc == 0x0d) { _bytesNeeded--; if (_bytesNeeded <= 0) { _state = State.WaitingZPAD; } } else { _state = State.WaitingZPAD; goto CheckByte; } } break; case State.GetFileInfo: case State.GetFileData: { if (_rcvPacketLen >= _rcvPacket.Length) { Debug.WriteLine("Buffer full in {0}", _state); errorMessage = XZModemPlugin.Instance.Strings.GetString("Message.ZModem.BufferFull"); goto Error; } if (_gotZDLE) { if (c == ZCRCE || c == ZCRCG || c == ZCRCQ || c == ZCRCW) { // end of frame. need CRC bytes. _rcvPacket[_rcvPacketLen++] = c; _gotZDLE = false; _bytesNeeded = (_crcType == CRCType.CRC32) ? 4 : 2; // CRC bytes _state = (_state == State.GetFileInfo) ? State.GetFileInfoCRC : (_state == State.GetFileData) ? State.GetFileDataCRC : State.Error; } else { // unescape _rcvPacket[_rcvPacketLen++] = (byte)(c ^ 0x40); _gotZDLE = false; } } else if (c == ZDLE) { _gotZDLE = true; } else { _rcvPacket[_rcvPacketLen++] = c; _gotZDLE = false; } } break; case State.GetFileInfoCRC: case State.GetFileDataCRC: { if (_rcvPacketLen >= _rcvPacket.Length) { Debug.WriteLine("Buffer full in {0}", _state); errorMessage = XZModemPlugin.Instance.Strings.GetString("Message.ZModem.BufferFull"); goto Error; } if (_gotZDLE) { // unescape _rcvPacket[_rcvPacketLen++] = (byte)(c ^ 0x40); _bytesNeeded--; _gotZDLE = false; } else if (c == ZDLE) { _gotZDLE = true; } else { _rcvPacket[_rcvPacketLen++] = c; _bytesNeeded--; _gotZDLE = false; } if (_bytesNeeded <= 0) { int dataLen = _rcvPacketLen - (_crcType == CRCType.CRC32 ? 5 : 3); if (_state == State.GetFileInfoCRC) { if (CheckCRC(_crcType, _rcvPacket, _rcvPacketLen)) { ParseFileInfo(_rcvPacket, 0, dataLen); _rcvPacketLen = 0; _gotZDLE = false; _state = State.WaitingZPAD; } else { Debug.WriteLine("CRC Error in {0}", _state); errorMessage = XZModemPlugin.Instance.Strings.GetString("Message.ZModem.CRCError"); goto Error; } } else if (_state == State.GetFileDataCRC) { byte frameType = _rcvPacket[dataLen]; //Debug.WriteLine("frameType = 0x{0:x2}", frameType); if (CheckCRC(_crcType, _rcvPacket, _rcvPacketLen)) { ProcessFileData(_rcvPacket, 0, dataLen); _rcvPacketLen = 0; _gotZDLE = false; if (frameType == ZCRCE) { // finished _state = State.WaitingZPAD; } else if (frameType == ZCRCW) { SendACK(); // read next subpacket _state = State.WaitingZPAD; } else { // read next subpacket _state = State.GetFileData; } } else { Debug.WriteLine("CRC Error in {0}", _state); errorMessage = XZModemPlugin.Instance.Strings.GetString("Message.ZModem.CRCError"); goto Error; } } } } break; } } return; Error: _state = State.Error; Abort(errorMessage, false); }
public static long GetCRC(this string value, CRCType CRCType, Encoding encoding) { return(CRCType.GetCRC().GetCrc(value, encoding)); }
private bool CheckHeader(CRCType crcType, byte[] data, int len, out Header hdr) { if (CheckCRC(crcType, data, len)) { hdr = new Header(data); return true; } else { hdr = new Header(); return false; } }
private bool CheckCRC(CRCType crcType, byte[] data, int len) { if (crcType == CRCType.CRC32) { uint crc = Crc32.Update(Crc32.InitialValue, data, 0, len - 4) ^ Crc32.XorValue; //Debug.WriteLine("CRC32: {0:x8}", crc); uint crcfld = (((uint)data[len - 4]) | ((uint)data[len - 3] << 8) | ((uint)data[len - 2] << 16) | ((uint)data[len - 1] << 24)); return crc == crcfld; } else { // CRC16 ushort crc = Crc16.Update(Crc16.InitialValue, data, 0, len - 2); //Debug.WriteLine("CRC16: {0:x4}", crc); ushort crcfld = (ushort)((data[len - 2] << 8) | data[len - 1]); return crc == crcfld; } }
public static byte[] CalculateCRC(IEnumerable <byte> bytes, uint crcInitialValue = 0x0, CRCType crcPolynomial = CRCType.CRC16CCITTPolynomial) { uint crc = crcInitialValue; CRCEngine crcEngine = new CRCEngine(crcPolynomial); var crcLength = crcPolynomial.GetLength(); // Byte little endian order switch (crcLength) { case 2: crc = crcEngine.CalculateCrc16(bytes, (ushort)crc); return(new[] { (byte)crc, (byte)(crc >> 8) }); case 4: crc = crcEngine.CalculateCrc32(bytes, crc); return(new[] { (byte)crc, (byte)(crc >> 8), (byte)(crc >> 16), (byte)(crc >> 24) }); default: Logger.Log(LogLevel.Error, "Cannot calculate CRC of invalid length {0}", crcLength); return(new byte[crcLength]); } }
public static long GetCRC(this string value, CRCType CRCType) { return(CRCType.GetCRC().GetCrc(value)); }