//----------------------------------------------------------------------- // // Copyright © 2012 Nils Hammar. All rights reserved. // //----------------------------------------------------------------------- /* * Software to access vehicle information via the OBD-II connector. * * Copyright © 2012 Nils Hammar * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Alternative licensing is possible, see the licensing document. * * The above text may not be removed or modified. */ namespace DeviceApi { using global::SharedObjects.Api; using global::SharedObjects.Misc; using global::SharedObjects.Protocol; /// /// Envelope class for one message. /// This is much like the PASSTHRU_MSG struct /// but is 'pure' C# to avoid unsafe pointers. /// public class PassThruMsg : IPassThruMsg { /// /// Gets or sets the Protocol ID. /// public int ProtocolID { get; set; } /// /// Gets or sets the RX Status Flags. /// public int RxStatus { get; set; } /// /// Gets or sets the TX Flags. /// public int TxFlags { get; set; } /// /// Gets or sets the Message Timestamp. /// public int Timestamp { get; set; } /// /// Gets or sets the size of the data. /// public int DataSize { get; set; } /// /// Gets or sets the index of extra data. /// public int ExtraDataIndex { get; set; } /// /// Gets or sets the array of data. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Justification = "Intentional for use with DLL API")] public byte[] Data { get; set; } /// /// Gets a value indicating whether this is a message sent from the application, /// which is applicable when replaying raw data through the simulator. /// public bool isSentData { get; private set; } /// /// Initializes a new instance of the class. /// /// 'true' if this message is for data sent to the vehicle from the application. /// ID of protocol used. /// Receive status flags. /// Transmit flags /// Timestamp value /// Size of data (payload) /// Index of extra data. /// Payload data. public PassThruMsg( bool isSentData, int ProtocolID, int RxStatus, int TxFlags, int Timestamp, int DataSize, int ExtraDataIndex, byte[] Data) { this.isSentData = isSentData; this.ProtocolID = ProtocolID; this.RxStatus = RxStatus; this.TxFlags = TxFlags; this.Timestamp = Timestamp; this.DataSize = DataSize; this.ExtraDataIndex = ExtraDataIndex; this.Data = Data; } /// /// Get one empty message that can be populated. /// /// Protocol to set on message. /// Message instance. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "Reviewed, intentional.")] public static IPassThruMsg getMaskedMsg(Protocols protocol) { return getMaskedMsg((int)protocol.id); } /// /// Get one empty message that can be populated. /// /// ID of protocol to set on message. /// Message instance. public static IPassThruMsg getMaskedMsg(int protocolid) { IPassThruMsg txmsg = new PassThruMsg(false, protocolid, 0, 0, 0, 0, 0, new byte[PassThruConstants.MAX_DATA_SIZE]); // Set first four bytes to zero just in case. txmsg.Data[0] = (byte)0; txmsg.Data[1] = (byte)0; txmsg.Data[2] = (byte)0; txmsg.Data[3] = (byte)0; return txmsg; } /// /// Initializes a new instance of the class. /// /// Pointer to message struct containing data for the message. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "Provided data shall never be 'null'.")] public unsafe PassThruMsg(PASSTHRU_MSG* pMsg) { this.ProtocolID = pMsg->ProtocolID; this.RxStatus = pMsg->RxStatus; this.TxFlags = pMsg->TxFlags; this.Timestamp = pMsg->Timestamp; this.DataSize = pMsg->DataSize; this.ExtraDataIndex = pMsg->ExtraDataIndex; this.Data = new byte[this.DataSize]; for (int i = 0; i < this.DataSize && i < PassThruConstants.MAX_DATA_SIZE; i++) { this.Data[i] = pMsg->Data[i]; } } /// /// Calculate hash code for item. /// /// Calculated hash code. public override int GetHashCode() { int hash = 0; Utils.reHash(ref hash, this.ProtocolID.GetHashCode()); Utils.reHash(ref hash, this.RxStatus.GetHashCode()); Utils.reHash(ref hash, this.TxFlags.GetHashCode()); Utils.reHash(ref hash, this.Timestamp.GetHashCode()); Utils.reHash(ref hash, this.DataSize.GetHashCode()); Utils.reHash(ref hash, this.ExtraDataIndex.GetHashCode()); for (int i = 0; i < this.Data.Length; i++) { Utils.reHash(ref hash, this.Data[i].GetHashCode()); } return hash; } /// /// Equals compare. /// /// Object to compare with. /// 'true' if equals [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "Reviewed, intentional.")] public override bool Equals(object obj) { if (obj is PassThruMsg) { PassThruMsg passThruMsg = (PassThruMsg)obj; if (this.ProtocolID == passThruMsg.ProtocolID && this.RxStatus == passThruMsg.RxStatus && this.TxFlags == passThruMsg.TxFlags && this.Timestamp == passThruMsg.Timestamp && this.DataSize == passThruMsg.DataSize && this.ExtraDataIndex == passThruMsg.ExtraDataIndex) { int i = 0; while (i < this.Data.Length && this.Data[i] == passThruMsg.Data[i]) { i++; } if (i == this.Data.Length) { return true; } } } return false; } /// /// Set the values of the struct given as parameter to the values of this object. /// Notice that the data area in the struct MUST be allocated to at least /// the size of the data area. /// /// Pointer to struct to load. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "Provided data shall never be 'null'.")] public unsafe void toStruct(PASSTHRU_MSG* pMsg) { pMsg->ProtocolID = this.ProtocolID; pMsg->RxStatus = this.RxStatus; pMsg->TxFlags = this.TxFlags; pMsg->Timestamp = this.Timestamp; pMsg->DataSize = this.DataSize; pMsg->ExtraDataIndex = this.ExtraDataIndex; for (int i = 0; i < this.DataSize && i < PassThruConstants.MAX_DATA_SIZE; i++) { pMsg->Data[i] = this.Data[i]; } } } }