Esempio n. 1
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)
        {
            _buffers.Add(segment);

            if (!message.MoreFollows)
            {
                try
                {
                    // TODO: Is this the best place to do this? Decoding
                    // large requests could potentially be more time than
                    // we want to spent in the transaction's lock

                    using (var stream = new MultiBufferStream(_buffers))
                    {
                        var tagReader       = new TagReader(stream);
                        var tagReaderStream = new TagReaderStream(tagReader, Value <TAck> .Schema);
                        var ack             = Value <TAck> .Load(tagReaderStream);

                        _source.SetResult(ack);
                    }
                }
                catch (Exception e)
                {
                    _source.SetException(new RejectException(RejectReason.InvalidTag));
                }
            }
        }
Esempio n. 2
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);
            }
        }
 /// <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);
Esempio n. 4
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));
 }
Esempio n. 5
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);
                }
            }
        }