/// <summary>
        /// Returns the number of bytes to read from the stream.
        /// </summary>
        /// <param name="state">Instance of <see cref="T:NavtelecomProtocol.SessionState" />.</param>
        /// <param name="reader"><see cref="T:SharpStructures.BinaryListReader" /> linked to a FLEX message body.</param>
        /// <param name="writer"><see cref="T:SharpStructures.MemoryBufferWriter" /> with data to be sent to the client.</param>
        /// <param name="token">The token to monitor for cancellation requests.</param>
        /// <returns>A task that represents the asynchronous operation. Contains the total number of bytes to read from the socket. Zero bytes to stop reading and send the response.</returns>
        public Task <int> GetPendingBytesAsync(SessionState state, BinaryListReader reader, MemoryBufferWriter writer,
                                               CancellationToken token)
        {
            switch (reader.ByteList.Count)
            {
            case 2:
                return(Task.FromResult(1));

            case 3:
                var messageSize  = FlexMessageTable.GetFlexMessageSize(state);
                var messageCount = reader.ByteList[2];

                writer.Write(Response);
                writer.Write(messageCount);
                writer.Write(BinaryUtilities.GetCrc8(writer.Buffer));

                return(Task.FromResult(messageSize * messageCount + 1));

            default:
                if (reader.ByteList.Last() != BinaryUtilities.GetCrc8(reader.ByteList.Take(reader.ByteList.Count - 1)))
                {
                    throw new ArgumentException("Invalid FLEX message CRC.");
                }

                return(Task.FromResult(0));
            }
        }
        /// <summary>
        /// Returns the number of bytes to read from the stream.
        /// </summary>
        /// <param name="state">Instance of <see cref="T:NavtelecomProtocol.SessionState" />.</param>
        /// <param name="reader"><see cref="T:SharpStructures.BinaryListReader" /> linked to a FLEX message body.</param>
        /// <param name="writer"><see cref="T:SharpStructures.MemoryBufferWriter" /> with data to be sent to the client.</param>
        /// <param name="token">The token to monitor for cancellation requests.</param>
        /// <returns>A task that represents the asynchronous operation. Contains the total number of bytes to read from the socket. Zero bytes to stop reading and send the response.</returns>
        public async Task <int> GetPendingBytesAsync(SessionState state, BinaryListReader reader, MemoryBufferWriter writer, CancellationToken token)
        {
            switch (reader.ByteList.Count)
            {
            case 2:
                return(13);

            case 15:
                reader.SetPosition(13);

                return(reader.ReadUInt16() + 1);

            default:
                if (reader.ByteList.Last() != BinaryUtilities.GetCrc8(reader.ByteList.Take(reader.ByteList.Count - 1)))
                {
                    throw new ArgumentException("Invalid FLEX message CRC.");
                }

                reader.SetPosition(4);

                var result    = reader.ReadByte();
                var crashTime = reader.ReadUInt32();
                var offset    = reader.ReadUInt32();
                var sizeRead  = reader.ReadUInt16();

                if (state.CrashInfo != null && result == 0x00 && state.CrashInfo.Timestamp == crashTime)
                {
                    for (var i = 0; i < sizeRead; ++i)
                    {
                        state.CrashInfo.Data[offset + i] = reader.ByteList[15 + i];
                    }

                    state.CrashInfo.Offset = offset + sizeRead;

                    var bytesLeft = state.CrashInfo.Data.Length - state.CrashInfo.Offset;

                    writer.Write(CrashInformation.CrashDataQuery);
                    writer.Write(crashTime);
                    writer.Write(state.CrashInfo.Offset);
                    writer.Write(bytesLeft > ushort.MaxValue ? ushort.MaxValue : (ushort)bytesLeft);
                    writer.Write(BinaryUtilities.GetCrc8(writer.Buffer));

                    if (bytesLeft == 0)
                    {
                        if (_onReadyCrash != null)
                        {
                            await _onReadyCrash(state, token).ConfigureAwait(false);
                        }

                        state.CrashInfo = null;
                    }
                }

                return(0);
            }
        }
示例#3
0
        /// <summary>
        /// Returns the number of bytes to read from the stream.
        /// </summary>
        /// <param name="state">Instance of <see cref="T:NavtelecomProtocol.SessionState" />.</param>
        /// <param name="reader"><see cref="T:SharpStructures.BinaryListReader" /> linked to a FLEX message body.</param>
        /// <param name="writer"><see cref="T:SharpStructures.MemoryBufferWriter" /> with data to be sent to the client.</param>
        /// <param name="token">The token to monitor for cancellation requests.</param>
        /// <returns>A task that represents the asynchronous operation. Contains the total number of bytes to read from the socket. Zero bytes to stop reading and send the response.</returns>
        public Task <int> GetPendingBytesAsync(SessionState state, BinaryListReader reader, MemoryBufferWriter writer,
                                               CancellationToken token)
        {
            switch (reader.ByteList.Count)
            {
            case 2:
                return(Task.FromResult(12));

            case 14:
                return(Task.FromResult(reader.ByteList[13] + 1));

            default:
                if (reader.ByteList.Last() != BinaryUtilities.GetCrc8(reader.ByteList.Take(reader.ByteList.Count - 1)))
                {
                    throw new ArgumentException("Invalid FLEX message CRC.");
                }

                reader.SetPosition(2);

                reader.ReadByte();
                reader.ReadByte();

                var crashTime   = reader.ReadUInt32();
                var crashLength = reader.ReadUInt32();

                var flags = reader.ReadByte();

                var nameLength = reader.ReadByte();
                var crashName  = new string(reader.ReadBytes(nameLength).Select(x => (char)x).ToArray());

                if (crashTime > 0 && crashLength > 0 && flags == 0xFF)
                {
                    state.CrashInfo = new CrashInformation
                    {
                        Data      = new byte[crashLength],
                        Name      = crashName,
                        Timestamp = crashTime
                    };

                    writer.Write(CrashInformation.CrashDataQuery);
                    writer.Write(crashTime);
                    writer.Write(0U);
                    writer.Write(crashLength > ushort.MaxValue ? ushort.MaxValue : (ushort)crashLength);
                    writer.Write(BinaryUtilities.GetCrc8(writer.Buffer));
                }

                return(Task.FromResult(0));
            }
        }