namespace Modbus.Device { using System; using System.Diagnostics.CodeAnalysis; #if SERIAL using System.IO.Ports; #endif using System.Net.Sockets; using Data; using IO; using Message; /// /// Modbus serial master device. /// public class ModbusSerialMaster : ModbusMaster, IModbusSerialMaster { private ModbusSerialMaster(ModbusTransport transport) : base(transport) { } /// /// Gets the Modbus Transport. /// [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")] ModbusSerialTransport IModbusSerialMaster.Transport { get { return (ModbusSerialTransport)Transport; } } #if SERIAL /// /// Modbus ASCII master factory method. /// public static ModbusSerialMaster CreateAscii(SerialPort serialPort) { if (serialPort == null) { throw new ArgumentNullException(nameof(serialPort)); } return CreateAscii(new SerialPortAdapter(serialPort)); } #endif /// /// Modbus ASCII master factory method. /// public static ModbusSerialMaster CreateAscii(TcpClient tcpClient) { if (tcpClient == null) { throw new ArgumentNullException(nameof(tcpClient)); } return CreateAscii(new TcpClientAdapter(tcpClient)); } /// /// Modbus ASCII master factory method. /// public static ModbusSerialMaster CreateAscii(UdpClient udpClient) { if (udpClient == null) { throw new ArgumentNullException(nameof(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(nameof(streamResource)); } return new ModbusSerialMaster(new ModbusAsciiTransport(streamResource)); } #if SERIAL /// /// Modbus RTU master factory method. /// public static ModbusSerialMaster CreateRtu(SerialPort serialPort) { if (serialPort == null) { throw new ArgumentNullException(nameof(serialPort)); } return CreateRtu(new SerialPortAdapter(serialPort)); } #endif /// /// Modbus RTU master factory method. /// public static ModbusSerialMaster CreateRtu(TcpClient tcpClient) { if (tcpClient == null) { throw new ArgumentNullException(nameof(tcpClient)); } return CreateRtu(new TcpClientAdapter(tcpClient)); } /// /// Modbus RTU master factory method. /// public static ModbusSerialMaster CreateRtu(UdpClient udpClient) { if (udpClient == null) { throw new ArgumentNullException(nameof(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(nameof(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; DiagnosticsRequestResponse response; request = new DiagnosticsRequestResponse( Modbus.DiagnosticsReturnQueryData, slaveAddress, new RegisterCollection(data)); response = Transport.UnicastMessage(request); return response.Data[0] == data; } } }