Ejemplo n.º 1
0
        private (SequencePosition consumed, SequencePosition examined) ReadFrames(ref ReadOnlySequence <byte> buffer)
        {
            buffer.Debug($"BUFFER len: {buffer.Length}, start: {buffer.Start.GetInteger()}, end: {buffer.End.GetInteger()}");

            const int MinPossibleFrameLength = 6;

            if (buffer.Length < MinPossibleFrameLength)
            {
                Debug.WriteLine($"SMALL_BUFFER {buffer.Length}");
                return(buffer.Start, buffer.End);
            }

            var  seq        = new SequenceReader <byte>(buffer);
            byte apduLength = 0;
            var  foundStart = seq.TryAdvanceTo(0x68, advancePastDelimiter: true) && seq.TryRead(out apduLength);

            if (!foundStart)
            {
                seq.Debug("NO_START_BYTE");
                return(seq.Position, seq.Position);
            }

            var validApduLength = apduLength == 4 || (apduLength >= Constants.NoPrefix.MinFrameILength && apduLength <= Constants.MaxApduLength);

            if (!validApduLength)
            {
                seq.Debug("INVALID_APDU", apduLength);
                OnError(ErrorCode.InvalidApduLength, null);
                return(seq.Position, seq.Position);
            }

            var isThereEnoughData = seq.Remaining >= apduLength;

            if (!isThereEnoughData)
            {
                seq.Debug("NOT_ENOUGH_DATA", apduLength);
                return(buffer.Start, seq.Position);
            }

            var success = TryCreateFrameSpan(in seq, apduLength, out var frameSpan);

            if (!success)
            {
                seq.Debug("FAILED_FRAME_SPAN");
                OnError(ErrorCode.FailedToCreateFrameSpan, null);
                return(seq.Position, seq.Position);
            }

            seq.Debug("FRAME_READ", apduLength);
            frameSpan.Debug("FRAME");

            var(error, frame) = Bytes.ReadFrame(frameSpan);
            if (error == ErrorCode.None)
            {
                OnFrameRead(frame);
            }
            else
            {
                Stats.IncrementFrameReadErrors();
                OnError(error, null);
            }

            var at = buffer.GetPosition(apduLength, seq.Position);

            return(at, at);
        }