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