using System; using System.Diagnostics.CodeAnalysis; using System.Runtime.Serialization; using System.Security.Permissions; using Modbus.Message; namespace Modbus { /// /// Represents slave errors that occur during communication. /// [Serializable] public class SlaveException : Exception { private readonly SlaveExceptionResponse _slaveExceptionResponse; private const string SlaveAddressPropertyName = "SlaveAdress"; private const string FunctionCodePropertyName = "FunctionCode"; private const string SlaveExceptionCodePropertyName = "SlaveExceptionCode"; /// /// Initializes a new instance of the class. /// public SlaveException() { } /// /// Initializes a new instance of the class. /// /// The message. public SlaveException(string message) : base(message) { } /// /// Initializes a new instance of the class. /// /// The message. /// The inner exception. public SlaveException(string message, Exception innerException) : base(message, innerException) { } internal SlaveException(SlaveExceptionResponse slaveExceptionResponse) { _slaveExceptionResponse = slaveExceptionResponse; } [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Used by test code.")] internal SlaveException(string message, SlaveExceptionResponse slaveExceptionResponse) : base(message) { _slaveExceptionResponse = slaveExceptionResponse; } #if !WindowsCE /// /// Initializes a new instance of the class. /// /// The that holds the serialized object data about the exception being thrown. /// The that contains contextual information about the source or destination. /// The class name is null or is zero (0). /// The info parameter is null. protected SlaveException(SerializationInfo info, StreamingContext context) : base(info, context) { if (info != null) { _slaveExceptionResponse = new SlaveExceptionResponse(info.GetByte(SlaveAddressPropertyName), info.GetByte(FunctionCodePropertyName), info.GetByte(SlaveExceptionCodePropertyName)); } } #endif /// /// Gets a message that describes the current exception. /// /// /// The error message that explains the reason for the exception, or an empty string(""). public override string Message { get { return String.Concat(base.Message, _slaveExceptionResponse != null ? String.Concat(Environment.NewLine, _slaveExceptionResponse) : String.Empty); } } /// /// Gets the response function code that caused the exception to occur, or 0. /// /// The function code. public byte FunctionCode { get { return _slaveExceptionResponse != null ? _slaveExceptionResponse.FunctionCode : (byte) 0; } } /// /// Gets the slave exception code, or 0. /// /// The slave exception code. public byte SlaveExceptionCode { get { return _slaveExceptionResponse != null ? _slaveExceptionResponse.SlaveExceptionCode : (byte) 0; } } /// /// Gets the slave address, or 0. /// /// The slave address. public byte SlaveAddress { get { return _slaveExceptionResponse != null ? _slaveExceptionResponse.SlaveAddress : (byte) 0; } } #if !WindowsCE /// /// When overridden in a derived class, sets the with information about the exception. /// /// The that holds the serialized object data about the exception being thrown. /// The that contains contextual information about the source or destination. /// The info parameter is a null reference (Nothing in Visual Basic). /// [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)] [SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods", Justification="Argument info is validated, rule does not understand AND condition.")] public override void GetObjectData(SerializationInfo info, StreamingContext context) { base.GetObjectData(info, context); if (info != null && _slaveExceptionResponse != null) { info.AddValue(SlaveAddressPropertyName, _slaveExceptionResponse.SlaveAddress); info.AddValue(FunctionCodePropertyName, _slaveExceptionResponse.FunctionCode); info.AddValue(SlaveExceptionCodePropertyName, _slaveExceptionResponse.SlaveExceptionCode); } } #endif } }