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