Пример #1
0
 /// <summary>
 /// Processes a received complex ack
 /// </summary>
 /// <param name="source">The address of the device that sent the ack</param>
 /// <param name="message">The complex ack header</param>
 /// <param name="segment">The buffer segment containing the ack content</param>
 public void ProcessComplexAck(Address source, ComplexAckMessage message, BufferSegment segment)
 {
     ClientTransaction tx = null;
     lock (_lock)
     {
         tx = _getClientTransaction(source, message.InvokeId);
     }
     if(tx != null)
         tx.OnComplexAck(message, segment);
 }
Пример #2
0
 /// <summary>
 /// Notifies the handle that a new response segment
 /// is available
 /// </summary>
 /// <param name="message">The complex ack message</param>
 /// <param name="segment">The response segment</param>
 public abstract void FeedComplexAck(ComplexAckMessage message, BufferSegment segment);
Пример #3
0
 /// <summary>
 /// Notifies the handle that a new response segment
 /// is available
 /// </summary>
 /// <param name="message">The complex ack message</param>
 /// <param name="segment">The response segment</param>
 public override void FeedComplexAck(ComplexAckMessage message, BufferSegment segment)
 {
     _source.SetException(new AbortException(AbortReason.InvalidApduInThisState));
 }
Пример #4
0
        /// <summary>
        /// Called whenever a complex ack is received
        /// for this transaction
        /// </summary>
        /// <param name="message">The received message</param>
        /// <param name="segment">The segment</param>
        public void OnComplexAck(ComplexAckMessage message, BufferSegment segment)
        {
            lock(_lock)
            {
                bool dispose = false;

                if (_state == ClientState.AwaitConfirmation)
                {
                    if(!message.Segmented)
                    {
                        _handle.FeedComplexAck(message, segment);
                        dispose = true;
                    }
                    else if(message.SequenceNumber == 0)
                    {
                        _sequenceNumber = 1;
                        _windowSize = message.ProposedWindowSize;
                        _sendSegmentAck();
                        _handle.FeedComplexAck(message, segment);
                        _transitionTo(ClientState.SegmentedConfirmation);
                    }
                    else
                    {
                        _sendAbort(AbortReason.InvalidApduInThisState);
                        _handle.FeedAbort(AbortReason.InvalidApduInThisState);
                        dispose = true;
                    }
                }
                else if(_state == ClientState.SegmentedConfirmation)
                {
                    int sequenceNumber;

                    if ((sequenceNumber = _inWindow(message.SequenceNumber)) != -1
                        && sequenceNumber == _sequenceNumber)
                    {
                        _handle.FeedComplexAck(message, segment);
                        _windowSize = message.ProposedWindowSize;
                        _sequenceNumber++;

                        dispose = !message.MoreFollows;
                        if (dispose || _sequenceNumber == _windowStart + _windowSize)
                            _sendSegmentAck();
                        else if (!dispose)
                            _transitionTo(ClientState.SegmentedConfirmation);
                    }
                    else
                    {
                        _sendSegmentAck(nack:true);
                        _transitionTo(ClientState.SegmentedConfirmation);
                    }
                }

                if(dispose)
                    _transitionTo(ClientState.Disposed);
            }
        }