| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- using ModbusSimulationProtocol.Data;
- using ModbusSimulationProtocol.Interface;
- using NModbus;
- using System.Net;
- using System.Net.Sockets;
- namespace ModbusSimulationProtocol.Services;
- public class ModbusSlaveService : IModbusSlaveService, IDisposable
- {
- private readonly IModbusLogger? _logger;
- private readonly ModbusFactory _factory;
- private IModbusTcpSlaveNetwork? _network = null;
- private bool disposedValue;
- public ModbusSlaveService(IModbusLogger? logger)
- {
- _logger = logger;
- _factory = new ModbusFactory(logger: _logger);
- }
- public void Initialize(string ip, ushort port)
- {
- ArgumentNullException.ThrowIfNullOrWhiteSpace(ip);
- if (_network is not null)
- {
- WriteLog(LoggingLevel.Information, "The slave network has been created.");
- return;
- }
- try
- {
- TcpListener listener = new TcpListener(IPAddress.Parse(ip), (int)port);
- _network = _factory.CreateSlaveNetwork(listener);
- }
- catch (Exception ex)
- {
- WriteLog(LoggingLevel.Error, ex.ToString());
- }
- }
- public void ActivateNetwork()
- {
- if (_network is null)
- {
- WriteLog(LoggingLevel.Warning, "Performs initializing before activating network.");
- return;
- }
- Task.Run(async () =>
- {
- try
- {
- WriteLog(LoggingLevel.Information, $"Starts async listening.");
- await _network.ListenAsync();
- }
- catch (Exception ex)
- {
- WriteLog(LoggingLevel.Error, ex.ToString());
- }
- });
- }
- public void AddSlave(byte slaveId,
- int coilCount, int discreteInputCount, int holdingRegisterCount, int inputRegisterCount)
- {
- if (_network is null)
- {
- WriteLog(LoggingLevel.Warning, "Performs initializing before adding any slave.");
- return;
- }
- try
- {
- var slave = _factory.CreateSlave(slaveId, new SlaveDataStore(coilCount, discreteInputCount, holdingRegisterCount, inputRegisterCount));
- _network.AddSlave(slave);
- }
- catch (Exception ex)
- {
- WriteLog(LoggingLevel.Error, ex.ToString());
- }
- }
- public void RemoveSlave(byte slaveId)
- {
- if (_network is null)
- {
- WriteLog(LoggingLevel.Warning, "The slave network do not exist even.");
- return;
- }
- if (_network.GetSlave(slaveId) is null)
- {
- WriteLog(LoggingLevel.Warning, "The specified slave do not exist. Failed to remove.");
- return;
- }
- try
- {
- _network.RemoveSlave(slaveId);
- WriteLog(LoggingLevel.Information, $"The slave {slaveId} has been removed.");
- }
- catch (Exception ex)
- {
- WriteLog(LoggingLevel.Error, ex.ToString());
- }
- }
- public int GetConnectedMasterCount()
- {
- if (_network is null)
- {
- WriteLog(LoggingLevel.Warning, "The slave network do not exist even.");
- return 0;
- }
- return _network.Masters.Count;
- }
- 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();
- _network = null;
- }
- // 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);
- }
- }
|