コード例 #1
0
ファイル: Uploader.cs プロジェクト: ZQHstudy/AstmLib
 public void ResetAndUpload(string message)
 {
     _timersManager.StopAllTimers();
     _frameCounter          = -1;
     _exceptionOccured      = null;
     _errorCounterNAK       = 0;
     _errorCounterENQ       = 0;
     _errorCounterDefective = 0;
     _currentFrame          = null;
     _uploadCompleted       = false;
     _state   = States.EstablishmentPhaseBegin;
     _message = message;
     _frames  = FrameUtils.SplitToFrames(message, _lowLevelSettings);
 }
コード例 #2
0
ファイル: Uploader.cs プロジェクト: ZQHstudy/AstmLib
        /// <summary>
        /// Закачивает максимум один фрейм и возвращает управление. При этом сохраняет свое состояние и ждет повторного вызова,
        /// для того что бы закончить upload.
        /// </summary>
        /// <exception cref="UploadException">Выгрузка прервана из-за ошибок</exception>
        /// <exception cref="InvalidOperationException">Выгрузка уже закончена</exception>
        public void ExecuteUploadStep()
        {
            byte[] buf = null;

            if (Completed)
            {
                throw new InvalidOperationException("Upload has been completed already");
            }

            if (!_timersManager.CheckTimerTimeout(WAIT_DELAY_TIMER_NAME))
            {
                return;
            }

            switch (_state)
            {
            case States.EstablishmentPhaseBegin:
                _stream.WriteByte((byte)DataLinkControlCodes.ENQ);
                _log.LogInformation("[send]{0}", ControlCodesUtility.ToControlCode((byte)DataLinkControlCodes.ENQ));
                _timersManager.StartTimer(WAIT_ANSWER_TIMER_NAME, _lowLevelSettings.EnqWaitTimeout);
                _state = States.EstablishmentPhaseWaitAnswer;
                break;

            case States.EstablishmentPhaseWaitAnswer:
                try
                {
                    _stream.ReadTimeout = 100;
                    var b = (byte)_stream.ReadByte();
                    _timersManager.StopTimer(WAIT_ANSWER_TIMER_NAME);
                    _log.LogInformation("[receive]{0}", ControlCodesUtility.ToControlCode(b));
                    if (b == (byte)DataLinkControlCodes.ACK)
                    {
                        _state = States.TransferPhaseSendFrame;
                    }
                    else if (b == (byte)DataLinkControlCodes.ENQ)
                    {
                        if (_havePriority)
                        {
                            _errorCounterENQ++;
                            if (_errorCounterENQ >= 2)
                            {
                                throw new DataLinkLayerException(new UnexpectedENQException(), "Remote system is stupid cow");
                            }

                            _timersManager.StartTimer(WAIT_DELAY_TIMER_NAME, 1000);
                            _state = States.EstablishmentPhaseBegin;
                        }
                        else
                        {
                            throw new DataLinkLayerException(new ContentionErrorException(), "Contention error occured");
                        }
                    }
                    else if (b == (byte)DataLinkControlCodes.NAK)
                    {
                        _errorCounterNAK++;
                        if (_errorCounterNAK >= 6)
                        {
                            _exceptionOccured = new DataLinkLayerException(new BusyException(), "Remote system busy while Establishment Phase");
                            _state            = States.TerminationPhase;
                        }
                        else
                        {
                            _state = States.EstablishmentPhaseBegin;
                            _timersManager.StartTimer(WAIT_DELAY_TIMER_NAME, 1000);
                        }
                    }
                    else
                    {
                        _exceptionOccured = new DataLinkLayerException(new DefectiveResponseException(), "Defective response error occured while Establishment Phase");
                        _state            = States.TerminationPhase;
                    }
                }
                catch (TimeoutException timeoutException)
                {
                    if (_timersManager.CheckTimerTimeout(WAIT_ANSWER_TIMER_NAME))
                    {
                        _exceptionOccured = new DataLinkLayerException(timeoutException, "Remote device doesn't response while Establishment Phase");
                        _state            = States.TerminationPhase;
                    }
                }

                break;

            case States.TransferPhaseSendFrame:
                _errorCounterDefective = 0;
                _errorCounterNAK       = 0;
                _frameCounter++;
                if (_frameCounter >= _frames.Length)
                {
                    _state = States.TerminationPhase;
                    break;
                }

                _currentFrame = _frames[_frameCounter];
                buf           = Encoding.ASCII.GetBytes(_currentFrame.ToString());
                _stream.Write(buf, 0, buf.Length);
                _log.LogInformation("[send]{0}", ControlCodesUtility.ReplaceControlCodesToLoggingCodes(_currentFrame.ToString()));
                _timersManager.StartTimer(WAIT_ANSWER_TIMER_NAME, 15000);
                _state = States.TransferPhaseWaitAnswer;
                break;

            case States.TransferPhaseResendFrame:
                buf = Encoding.ASCII.GetBytes(_currentFrame.ToString());
                _stream.Write(buf, 0, buf.Length);
                _log.LogInformation("[send]{0}", ControlCodesUtility.ReplaceControlCodesToLoggingCodes(_currentFrame.ToString()));
                _timersManager.StartTimer(WAIT_ANSWER_TIMER_NAME, 15000);
                _state = States.TransferPhaseWaitAnswer;
                break;

            case States.TransferPhaseWaitAnswer:
                try
                {
                    _stream.ReadTimeout = 100;
                    var b = (byte)_stream.ReadByte();
                    _timersManager.StopTimer(WAIT_ANSWER_TIMER_NAME);
                    _log.LogInformation("[receive]{0}", ControlCodesUtility.ToControlCode(b));
                    if (b == (byte)DataLinkControlCodes.ACK)
                    {
                        _state = States.TransferPhaseSendFrame;
                    }
                    else if (b == (byte)DataLinkControlCodes.NAK || b == (byte)DataLinkControlCodes.EOT)
                    {
                        _errorCounterNAK++;
                        if (_errorCounterNAK >= 6)
                        {
                            _state            = States.TerminationPhase;
                            _exceptionOccured = new DataLinkLayerException(new BusyException(), "Remote system busy while Transfer Phase");
                        }
                        else
                        {
                            _state = States.TransferPhaseResendFrame;
                            _timersManager.StartTimer(WAIT_DELAY_TIMER_NAME, 10000);
                        }
                    }
                    else
                    {
                        _errorCounterDefective++;
                        if (_errorCounterDefective >= 6)
                        {
                            _state            = States.TerminationPhase;
                            _exceptionOccured = new DataLinkLayerException(new DefectiveResponseException(), "Remote system response defective while Transfer Phase");
                        }
                        else
                        {
                            _state = States.TransferPhaseResendFrame;
                        }
                    }
                }
                catch (TimeoutException timeoutException)
                {
                    if (_timersManager.CheckTimerTimeout(WAIT_ANSWER_TIMER_NAME))
                    {
                        _state            = States.TerminationPhase;
                        _exceptionOccured = new DataLinkLayerException(timeoutException, "Remote device doesn't response while Transfer Phase");
                    }
                }

                break;

            case States.TerminationPhase:
                _stream.WriteByte((byte)DataLinkControlCodes.EOT);
                _log.LogInformation("[send]{0}", ControlCodesUtility.ToControlCode((byte)DataLinkControlCodes.EOT));
                if (_exceptionOccured != null)
                {
                    throw _exceptionOccured;
                }
                else
                {
                    _uploadCompleted = true;
                }

                break;
            }
        }