Ejemplo n.º 1
0
        // ZFILE
        private void SendZFILE()
        {
            if (_stopped)
            {
                return;
            }

            Header hdr         = new Header(ZFILE, zf0: ZCBIN);
            int    pktOutCount =
                (_txCrcType == CRCType.CRC32) ?
                BuildBin32Header(_sndBuff, hdr) :
                BuildBin16Header(_sndBuff, hdr);

            SendPacket(_sndBuff, pktOutCount);

            string fn = Path.GetFileName(_fileName);

            fn = fn.Replace(" ", "_");

            string data = fn + '\0' + _fileSize.ToString() + '\0';

            byte[] bytes = Encoding.UTF8.GetBytes(data);

            int index = 0;

            foreach (byte b in bytes)
            {
                index = PutBin(_sndBuff, index, b);
            }
            uint crc =
                (_txCrcType == CRCType.CRC32) ?
                Crc32.Update(Crc32.InitialValue, bytes, 0, bytes.Length) :
                Crc16.Update(Crc16.InitialValue, bytes, 0, bytes.Length);

            _sndBuff[index++] = ZDLE;
            _sndBuff[index++] = ZCRCW;
            crc = (_txCrcType == CRCType.CRC32) ?
                  Crc32.Update(crc, ZCRCW) ^ Crc32.XorValue :
                  Crc16.Update((ushort)crc, ZCRCW);

            if (_txCrcType == CRCType.CRC32)
            {
                index = PutCRC32(_sndBuff, index, crc);
            }
            else
            {
                index = PutCRC16(_sndBuff, index, (ushort)crc);
            }

            _sndBuff[index++] = XON;    // ZCRCW requires response

            SendPacket(_sndBuff, index);
        }
Ejemplo n.º 2
0
        protected int BuildBin16Header(byte[] data, Header hdr)
        {
            data[0] = ZPAD;
            data[1] = ZDLE;
            data[2] = ZBIN;
            int index = 3;

            index = PutBin(data, index, hdr.Type);
            ushort crc = Crc16.Update(Crc16.InitialValue, hdr.Type);

            index = PutBin(data, index, hdr.ZP0);
            crc   = Crc16.Update(crc, hdr.ZP0);
            index = PutBin(data, index, hdr.ZP1);
            crc   = Crc16.Update(crc, hdr.ZP1);
            index = PutBin(data, index, hdr.ZP2);
            crc   = Crc16.Update(crc, hdr.ZP2);
            index = PutBin(data, index, hdr.ZP3);
            crc   = Crc16.Update(crc, hdr.ZP3);
            index = PutCRC16(data, index, crc);
            return(index);
        }
Ejemplo n.º 3
0
 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);
     }
 }
Ejemplo n.º 4
0
        private void SendBlock(bool useCrc, bool resend)
        {
            if (_input == null || _fileClosed)
            {
                return;
            }

            if (resend)
            {
                Trace("Seek to {0}", _prevPos);
                _input.Seek(_prevPos, SeekOrigin.Begin);
            }
            else
            {
                _prevPos = _nextPos;
                _sequenceNumber++;
            }

            int dataLength;

            if (useCrc)
            {
                dataLength = (_fileSize - _prevPos < 1024L) ? 128 : 1024;
            }
            else
            {
                dataLength = 128;
            }

            int readLen = _input.Read(_sendBuff, 3, dataLength);

            _nextPos = _input.Position;

            if (readLen == 0)
            {
                _state = State.AfterEOT;
                Trace("<-- EOT");
                Send(EOT);
                return;
            }

            _sendBuff[0] = (dataLength == 1024) ? STX : SOH;
            _sendBuff[1] = _sequenceNumber;
            _sendBuff[2] = (byte)(255 - _sequenceNumber);

            for (int i = 3 + readLen; i < 3 + dataLength; ++i)
            {
                _sendBuff[i] = CPMEOF;
            }

            int blockLen = 3 + dataLength;

            if (useCrc)
            {
                ushort crc = Crc16.Update(Crc16.InitialValue, _sendBuff, 3, dataLength);
                _sendBuff[blockLen++] = (byte)(crc >> 8);
                _sendBuff[blockLen++] = (byte)crc;
            }
            else
            {
                byte checksum = 0;
                for (int i = 3; i < 3 + dataLength; ++i)
                {
                    checksum += _sendBuff[i];
                }
                _sendBuff[blockLen++] = checksum;
            }

            Trace("<-- {0:X2} {1:X2} ...({2})", _sendBuff[0], _sendBuff[1], blockLen);

            Send(_sendBuff, blockLen);

            SetProgressValue((int)_nextPos, (int)_fileSize);
        }
Ejemplo n.º 5
0
        public override void OnReception(ByteDataFragment fragment)
        {
            Interlocked.Exchange(ref _lastReceptionTimeUtcTicks, DateTime.UtcNow.Ticks);

            if (_aborting)
            {
                return;
            }

            byte[] data   = fragment.Buffer;
            int    offset = fragment.Offset;
            int    length = fragment.Length;

            BlockTypeInfo blockInfo;

            if (_recvLen > 0)
            {
                blockInfo = GetBlockTypeInfo(_recvBuff[0], Volatile.Read(ref _mode));
            }
            else
            {
                blockInfo = new BlockTypeInfo();    // update later
            }

            for (int i = 0; i < length; i++)
            {
                byte c = data[offset + i];

                if (_recvLen == 0)
                {
                    if (c == EOT)
                    {
                        Trace("--> EOT");
                        FlushPendingBuffer(true);
                        Trace("<-- ACK");
                        Send(ACK);
                        Completed(false, true, XZModemPlugin.Instance.Strings.GetString("Message.XModem.ReceiveComplete"));
                        return;
                    }

                    if (c != SOH && c != STX)
                    {
                        continue;   // skip
                    }

                    // determine expected block type
                    blockInfo = GetBlockTypeInfo(c, Volatile.Read(ref _mode));
                }

                _recvBuff[_recvLen++] = c;

                if (_recvLen >= blockInfo.BlockSize)
                {
                    goto BlockReceived;
                }
            }

            return;

BlockReceived:
            // a block has been received
            Interlocked.Exchange(ref _lastBlockTimeUtcTicks, DateTime.UtcNow.Ticks);

            Trace("--> {0:X2} {1:X2} ...({2})", _recvBuff[0], _recvBuff[1], _recvLen);

            // check sequence number
            if (_recvBuff[1] != _nextSequenceNumber || _recvBuff[2] != (255 - _nextSequenceNumber))
            {
                Trace("<-- NAK (bad seq)");
                goto Error;
            }

            // check CRC or checksum
            if (blockInfo.HasCRC)
            {
                ushort crc      = Crc16.Update(Crc16.InitialValue, _recvBuff, blockInfo.DataOffset, blockInfo.DataLength);
                int    crcIndex = blockInfo.DataOffset + blockInfo.DataLength;
                if (_recvBuff[crcIndex] != (byte)(crc >> 8) || _recvBuff[crcIndex + 1] != (byte)crc)
                {
                    // CRC error
                    Trace("<-- NAK (CRC error)");
                    goto Error;
                }
            }
            else
            {
                byte checksum = 0;
                int  index    = blockInfo.DataOffset;
                for (int n = 0; n < blockInfo.DataLength; ++n)
                {
                    checksum += _recvBuff[index++];
                }
                if (_recvBuff[index] != checksum)
                {
                    // checksum error
                    Trace("<-- NAK (checksum error)");
                    goto Error;
                }
            }

            // ok
            _nextSequenceNumber++;

            FlushPendingBuffer(false);
            SaveToPendingBuffer(_recvBuff, blockInfo.DataOffset, blockInfo.DataLength);

            _errorCount = 0;
            _recvLen    = 0;
            Send(ACK);
            return;

Error:
            _recvLen = 0;
            _errorCount++;
            if (_errorCount > MAX_ERROR)
            {
                Abort(XZModemPlugin.Instance.Strings.GetString("Message.XModem.CouldNotReceiveCorrectData"), false);
            }
            else
            {
                Send(NAK);
            }
        }
Ejemplo n.º 6
0
        // ZDATA
        private void SendZDATA(CancellationToken cancelToken)
        {
Restart:
            uint filePos = Volatile.Read(ref _filePosReq);

            Volatile.Write(ref _filePosReqChanged, false);
            _fileStream.Seek(filePos, SeekOrigin.Begin);

            // Header
            Header hdr         = new Header(ZDATA, pos: filePos);
            int    pktOutCount = (_txCrcType == CRCType.CRC32) ?
                                 BuildBin32Header(_sndBuff, hdr) :
                                 BuildBin16Header(_sndBuff, hdr);

            SendPacket(_sndBuff, pktOutCount);

            // Sub frames
            while (!cancelToken.IsCancellationRequested)
            {
                if (Volatile.Read(ref _filePosReqChanged))
                {
                    goto Restart;
                }

                uint crc   = (_txCrcType == CRCType.CRC32) ? Crc32.InitialValue : Crc16.InitialValue;
                int  index = 0;
                int  len   = (int)Math.Min(_fileSize - filePos, (long)_frameSize);
                for (int i = 0; i < len; ++i)
                {
                    int c = _fileStream.ReadByte();
                    if (c < 0)
                    {
                        break;
                    }
                    filePos++;
                    byte b = (byte)c;
                    index = PutBin(_sndBuff, index, b);
                    crc   = (_txCrcType == CRCType.CRC32) ?
                            Crc32.Update(crc, b) :
                            Crc16.Update((ushort)crc, b);
                }

                byte frameType = (filePos >= _fileSize) ? ZCRCE : ZCRCG;
                _sndBuff[index++] = ZDLE;
                _sndBuff[index++] = frameType;
                crc = (_txCrcType == CRCType.CRC32) ?
                      Crc32.Update(crc, frameType) ^ Crc32.XorValue :
                      Crc16.Update((ushort)crc, frameType);

                if (_txCrcType == CRCType.CRC32)
                {
                    index = PutCRC32(_sndBuff, index, crc);
                }
                else
                {
                    index = PutCRC16(_sndBuff, index, (ushort)crc);
                }

                //Debug.WriteLine("frameType = {0:x2}", frameType);
                //Debug.WriteLine("CRC = {0:x8}", crc);
                SendPacket(_sndBuff, index);

                if (!_stopped)
                {
                    _parent.SetProgressValue(filePos);
                }

                if (frameType == ZCRCE)
                {
                    break;
                }

                Thread.Sleep(0);
            }

            // ZEOF
            int zeofCount = BuildHEXHeader(_sndBuff, new Header(ZEOF, pos: filePos));

            SendPacket(_sndBuff, zeofCount);
        }