Esempio n. 1
0
        /// <summary>
        /// Create a block message from the supplied arguments.
        /// </summary>
        public Message CreateBlockMessagemiles(byte[] Payload, int Offset, int Length, int Address, byte execute)
        {
            byte[] Buffer = new byte[10 + Length + 2];
            byte[] Header = new byte[10];

            byte Size1 = unchecked ((byte)(Length >> 8));
            byte Size2 = unchecked ((byte)(Length & 0xFF));
            byte Addr1 = unchecked ((byte)(Address >> 16));
            byte Addr2 = unchecked ((byte)(Address >> 8));
            byte Addr3 = unchecked ((byte)(Address & 0xFF));

            Header[0] = Priority.Block;
            Header[1] = DeviceId.Pcm;
            Header[2] = DeviceId.Tool;
            Header[3] = Mode.PCMUpload;
            Header[4] = execute;
            Header[5] = Size1;
            Header[6] = Size2;
            Header[7] = Addr1;
            Header[8] = Addr2;
            Header[9] = Addr3;

            System.Buffer.BlockCopy(Header, 0, Buffer, 0, Header.Length);
            System.Buffer.BlockCopy(Payload, Offset, Buffer, Header.Length, Length);

            return(new Message(VpwUtilities.AddBlockChecksum(Buffer)));
        }
Esempio n. 2
0
        /// <summary>
        /// Parse the payload of a read request.
        /// </summary>
        /// <remarks>
        /// It is the callers responsability to check the ResponseStatus for errors
        /// </remarks>
        public Response <byte[]> ParsePayload(Message message, int length, int expectedAddress)
        {
            ResponseStatus status;

            byte[] actual   = message.GetBytes();
            byte[] expected = new byte[] { 0x6D, 0xF0, 0x10, 0x36 };
            if (!TryVerifyInitialBytes(actual, expected, out status))
            {
                return(Response.Create(status, new byte[0]));
            }

            // Ensure that we can read the data length and start address from the message.
            if (actual.Length < 10)
            {
                return(Response.Create(ResponseStatus.Truncated, new byte[0]));
            }

            // Read the data length.
            int dataLength = (actual[5] << 8) + actual[6];

            // Read and validate the data start address.
            int actualAddress = ((actual[7] << 16) + (actual[8] << 8) + actual[9]);

            if (actualAddress != expectedAddress)
            {
                return(Response.Create(ResponseStatus.UnexpectedResponse, new byte[0]));
            }

            byte[] result = new byte[dataLength];

            // Normal block
            if (actual[4] == 1)
            {
                // With normal encoding, data length should be actual length minus header size
                if (actual.Length - 12 < dataLength)
                {
                    return(Response.Create(ResponseStatus.Truncated, new byte[0]));
                }

                // Verify block checksum
                UInt16 ValidSum   = VpwUtilities.CalcBlockChecksum(actual);
                int    PayloadSum = (actual[dataLength + 10] << 8) + actual[dataLength + 11];
                Buffer.BlockCopy(actual, 10, result, 0, dataLength);
                if (PayloadSum != ValidSum)
                {
                    return(Response.Create(ResponseStatus.Error, result));
                }

                return(Response.Create(ResponseStatus.Success, result));
            }
            // RLE block
            else if (actual[4] == 2)
            {
                // This isnt going to work with existing kernels... need to support variable length.
                byte value = actual[10];
                for (int index = 0; index < dataLength; index++)
                {
                    result[index] = value;
                }

                return(Response.Create(ResponseStatus.Error, result));
            }
            else
            {
                return(Response.Create(ResponseStatus.Error, result));
            }
        }