using System; using System.Collections.Generic; using NModbus.Device.MessageHandlers; using System.Linq; using System.Net.Sockets; using NModbus.Extensions; using NModbus.Data; using NModbus.Device; using NModbus.IO; using NModbus.Logging; namespace NModbus { public class ModbusFactory : IModbusFactory { /// /// The "built-in" message handlers. /// private static readonly IModbusFunctionService[] BuiltInFunctionServices = { new ReadCoilsService(), new ReadInputsService(), new ReadHoldingRegistersService(), new ReadInputRegistersService(), new DiagnosticsService(), new WriteSingleCoilService(), new WriteSingleRegisterService(), new WriteMultipleCoilsService(), new WriteMultipleRegistersService(), new WriteFileRecordService(), new ReadWriteMultipleRegistersService(), }; private readonly IDictionary _functionServices; /// /// Create a factory which uses the built in standard slave function handlers. /// public ModbusFactory() { _functionServices = BuiltInFunctionServices.ToDictionary(s => s.FunctionCode, s => s); Logger = NullModbusLogger.Instance; } /// /// Create a factory which optionally uses the built in function services and allows custom services to be added. /// /// User provided function services. /// If true, the built in function services are included. Otherwise, all function services will come from the functionService parameter. /// Logger public ModbusFactory( IEnumerable functionServices = null, bool includeBuiltIn = true, IModbusLogger logger = null) { Logger = logger ?? NullModbusLogger.Instance; //Determine if we're including the built in services if (includeBuiltIn) { //Make a dictionary out of the built in services _functionServices = BuiltInFunctionServices .ToDictionary(s => s.FunctionCode, s => s); } else { //Create an empty dictionary _functionServices = new Dictionary(); } if (functionServices != null) { //Add and replace the provided function services as necessary. foreach (IModbusFunctionService service in functionServices) { //This will add or replace the service. _functionServices[service.FunctionCode] = service; } } } public IModbusSlave CreateSlave(byte unitId, ISlaveDataStore dataStore = null) { if (dataStore == null) dataStore = new DefaultSlaveDataStore(); return new ModbusSlave(unitId, dataStore, GetAllFunctionServices()); } public IModbusSlaveNetwork CreateSlaveNetwork(IModbusRtuTransport transport) { return new ModbusSerialSlaveNetwork(transport, this, Logger); } public IModbusSlaveNetwork CreateSlaveNetwork(IModbusAsciiTransport transport) { return new ModbusSerialSlaveNetwork(transport, this, Logger); } public IModbusTcpSlaveNetwork CreateSlaveNetwork(TcpListener tcpListener) { return new ModbusTcpSlaveNetwork(tcpListener, this, Logger); } public IModbusSlaveNetwork CreateSlaveNetwork(UdpClient client) { return new ModbusUdpSlaveNetwork(client, this, Logger); } public IModbusRtuTransport CreateRtuTransport(IStreamResource streamResource) { return new ModbusRtuTransport(streamResource, this, Logger); } public IModbusAsciiTransport CreateAsciiTransport(IStreamResource streamResource) { return new ModbusAsciiTransport(streamResource, this, Logger); } public IModbusTransport CreateIpTransport(IStreamResource streamResource) { return new ModbusIpTransport(streamResource, this, Logger); } public IModbusLogger Logger { get; } public IModbusFunctionService[] GetAllFunctionServices() { return _functionServices .Values .ToArray(); } public IModbusSerialMaster CreateMaster(IModbusSerialTransport transport) { return new ModbusSerialMaster(transport); } public IModbusMaster CreateMaster(UdpClient client) { var adapter = new UdpClientAdapter(client); var transport = new ModbusIpTransport(adapter, this, Logger); return new ModbusIpMaster(transport); } public IModbusMaster CreateMaster(TcpClient client) { var adapter = new TcpClientAdapter(client); var transport = new ModbusIpTransport(adapter, this, Logger); return new ModbusIpMaster(transport); } public IModbusMaster CreateMaster(Socket client) { var adapter = new SocketAdapter(client); var transport = new ModbusRtuTransport(adapter, this, Logger); return new ModbusSerialMaster(transport); } public IModbusFunctionService GetFunctionService(byte functionCode) { return _functionServices.GetValueOrDefault(functionCode); } } }