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);
}
}