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