123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- using ModbusSimulationProtocol.Interface;
- using NModbus;
- using System.Net;
- using System.Net.Sockets;
- using SlaveDataStore = ModbusSimulationProtocol.Data.SlaveDataStore;
- namespace ModbusSimulationProtocol.Services;
- public class ModbusSlaveService : IModbusSlaveService
- {
- private readonly IModbusLogger? _logger;
- private readonly ModbusFactory _factory;
- private readonly ISlaveDataStore _slaveDataStore;
- private IModbusTcpSlaveNetwork? _network;
- private bool disposedValue;
- public ModbusSlaveService(IModbusLogger? logger)
- {
- _logger = logger;
- _factory = new ModbusFactory(logger: _logger);
- _slaveDataStore = new SlaveDataStore();
- }
- public ISlaveDataStore SlaveDataStore => _slaveDataStore;
- public bool Initialize(string ip, ushort port, byte slaveId = 1)
- {
- if (string.IsNullOrWhiteSpace(ip))
- {
- WriteLog(LoggingLevel.Error, "Incorrect ip address.");
- return false;
- }
- if (_network is not null)
- {
- WriteLog(LoggingLevel.Warning, "The slave network has been created.");
- return false;
- }
- try
- {
- TcpListener listener = new(IPAddress.Parse(ip), (int)port);
- _network = _factory.CreateSlaveNetwork(listener);
- var slave = _factory.CreateSlave(slaveId, _slaveDataStore);
- _network.AddSlave(slave);
- WriteLog(LoggingLevel.Information, "Completed initailization.");
- return true;
- }
- catch (Exception ex)
- {
- WriteLog(LoggingLevel.Error, ex.ToString());
- return false;
- }
- }
- public bool Open()
- {
- if (_network is null)
- {
- WriteLog(LoggingLevel.Error, "Performs initializing before doing any operation.");
- return false;
- }
- Task.Run(async () =>
- {
- try
- {
- WriteLog(LoggingLevel.Information, "Starts Tcp Listening");
- await _network.ListenAsync();
- }
- catch (Exception ex)
- {
- WriteLog(LoggingLevel.Error, ex.ToString());
- }
- });
- return true;
- }
- public bool TryWriteValues<TPoint>(IPointSource<TPoint> source, ushort address, TPoint[] points)
- {
- if (_network is null)
- {
- WriteLog(LoggingLevel.Error, "Performs initializing before doing any operation.");
- return false;
- }
- try
- {
- source.WritePoints(address, points);
- return true;
- }
- catch (Exception ex)
- {
- WriteLog(LoggingLevel.Error, ex.ToString());
- return false;
- }
- }
- public bool TryReadValues<TPoint>(IPointSource<TPoint> source, ushort address, ushort count, out TPoint[]? outPoints)
- {
- if (_network is null)
- {
- WriteLog(LoggingLevel.Error, "Performs initializing before doing any operation.");
- outPoints = null;
- return false;
- }
- try
- {
- outPoints = source.ReadPoints(address, count);
- return true;
- }
- catch (Exception ex)
- {
- WriteLog(LoggingLevel.Error, ex.ToString());
- outPoints = null;
- return false;
- }
- }
- private void WriteLog(LoggingLevel loggingLevel, string log)
- {
- _logger?.Log(loggingLevel, $"[{nameof(ModbusSlaveService)}]:{log}");
- }
- protected virtual void Dispose(bool disposing)
- {
- if (!disposedValue)
- {
- if (disposing)
- {
- // TODO: dispose managed state (managed objects)
- _network?.Dispose();
- }
- // TODO: free unmanaged resources (unmanaged objects) and override finalizer
- // TODO: set large fields to null
- disposedValue = true;
- }
- }
- // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
- // ~ModbusSlaveService()
- // {
- // // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
- // Dispose(disposing: false);
- // }
- public void Dispose()
- {
- // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
- Dispose(disposing: true);
- GC.SuppressFinalize(this);
- }
- }
|