using System;
using System.Diagnostics.CodeAnalysis;
using System.IO.Ports;
using System.Net.Sockets;
using Modbus.Data;
using Modbus.IO;
using Modbus.Message;
namespace Modbus.Device
{
///
/// Modbus serial master device.
///
public class ModbusSerialMaster : ModbusMaster, IModbusSerialMaster
{
private ModbusSerialMaster(ModbusTransport transport)
: base(transport)
{
}
[SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
ModbusSerialTransport IModbusSerialMaster.Transport
{
get
{
return (ModbusSerialTransport) Transport;
}
}
///
/// Modbus ASCII master factory method.
///
public static ModbusSerialMaster CreateAscii(SerialPort serialPort)
{
if (serialPort == null)
throw new ArgumentNullException("serialPort");
return CreateAscii(new SerialPortAdapter(serialPort));
}
///
/// Modbus ASCII master factory method.
///
public static ModbusSerialMaster CreateAscii(TcpClient tcpClient)
{
if (tcpClient == null)
throw new ArgumentNullException("tcpClient");
return CreateAscii(new TcpClientAdapter(tcpClient));
}
///
/// Modbus ASCII master factory method.
///
public static ModbusSerialMaster CreateAscii(UdpClient udpClient)
{
if (udpClient == null)
throw new ArgumentNullException("udpClient");
if (!udpClient.Client.Connected)
throw new InvalidOperationException(Resources.UdpClientNotConnected);
return CreateAscii(new UdpClientAdapter(udpClient));
}
///
/// Modbus ASCII master factory method.
///
public static ModbusSerialMaster CreateAscii(IStreamResource streamResource)
{
if (streamResource == null)
throw new ArgumentNullException("streamResource");
return new ModbusSerialMaster(new ModbusAsciiTransport(streamResource));
}
///
/// Modbus RTU master factory method.
///
public static ModbusSerialMaster CreateRtu(SerialPort serialPort)
{
if (serialPort == null)
throw new ArgumentNullException("serialPort");
return CreateRtu(new SerialPortAdapter(serialPort));
}
///
/// Modbus RTU master factory method.
///
public static ModbusSerialMaster CreateRtu(TcpClient tcpClient)
{
if (tcpClient == null)
throw new ArgumentNullException("tcpClient");
return CreateRtu(new TcpClientAdapter(tcpClient));
}
///
/// Modbus RTU master factory method.
///
public static ModbusSerialMaster CreateRtu(UdpClient udpClient)
{
if (udpClient == null)
throw new ArgumentNullException("udpClient");
if (!udpClient.Client.Connected)
throw new InvalidOperationException(Resources.UdpClientNotConnected);
return CreateRtu(new UdpClientAdapter(udpClient));
}
///
/// Modbus RTU master factory method.
///
public static ModbusSerialMaster CreateRtu(IStreamResource streamResource)
{
if (streamResource == null)
throw new ArgumentNullException("streamResource");
return new ModbusSerialMaster(new ModbusRtuTransport(streamResource));
}
///
/// Serial Line only.
/// Diagnostic function which loops back the original data.
/// NModbus only supports looping back one ushort value, this is a limitation of the "Best Effort" implementation of the RTU protocol.
///
/// Address of device to test.
/// Data to return.
/// Return true if slave device echoed data.
public bool ReturnQueryData(byte slaveAddress, ushort data)
{
DiagnosticsRequestResponse request = new DiagnosticsRequestResponse(Modbus.DiagnosticsReturnQueryData, slaveAddress, new RegisterCollection(data));
DiagnosticsRequestResponse response = Transport.UnicastMessage(request);
return response.Data[0] == data;
}
}
}