예제 #1
0
        private async Task HandleRequestAsync()
        {
            while (true)
            {
                Logger.Debug($"Begin reading header from Master at IP: {EndPoint}");

                int readBytes = await Stream.ReadAsync(_mbapHeader, 0, 6).ConfigureAwait(false);

                if (readBytes == 0)
                {
                    Logger.Debug($"0 bytes read, Master at {EndPoint} has closed Socket connection.");
                    ModbusMasterTcpConnectionClosed?.Invoke(this, new TcpConnectionEventArgs(EndPoint));
                    return;
                }

                ushort frameLength = (ushort)IPAddress.HostToNetworkOrder(BitConverter.ToInt16(_mbapHeader, 4));
                Logger.Debug($"Master at {EndPoint} sent header: \"{string.Join(", ", _mbapHeader)}\" with {frameLength} bytes in PDU");

                _messageFrame = new byte[frameLength];
                readBytes     = await Stream.ReadAsync(_messageFrame, 0, frameLength).ConfigureAwait(false);

                if (readBytes == 0)
                {
                    Logger.Debug($"0 bytes read, Master at {EndPoint} has closed Socket connection.");
                    ModbusMasterTcpConnectionClosed?.Invoke(this, new TcpConnectionEventArgs(EndPoint));
                    return;
                }

                Logger.Debug($"Read frame from Master at {EndPoint} completed {readBytes} bytes");
                byte[] frame = _mbapHeader.Concat(_messageFrame).ToArray();
                Logger.Trace($"RX from Master at {EndPoint}: {string.Join(", ", frame)}");

                var request = _modbusFactory.CreateModbusRequest(_messageFrame);
                request.TransactionId = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(frame, 0));

                IModbusSlave slave = _slaveNetwork.GetSlave(request.SlaveAddress);

                if (slave != null)
                {
                    //TODO: Determine if this is appropriate

                    // perform action and build response
                    IModbusMessage response = slave.ApplyRequest(request);
                    response.TransactionId = request.TransactionId;

                    // write response
                    byte[] responseFrame = Transport.BuildMessageFrame(response);
                    Logger.Information($"TX to Master at {EndPoint}: {string.Join(", ", responseFrame)}");
                    await Stream.WriteAsync(responseFrame, 0, responseFrame.Length).ConfigureAwait(false);
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Apply the request.
        /// </summary>
        /// <param name="request"></param>
        protected IModbusMessage ApplyRequest(IModbusMessage request)
        {
            //Check for broadcast requests
            if (request.SlaveAddress == 0)
            {
                //Grab each slave
                foreach (var slave in _slaves.Values)
                {
                    try
                    {
                        //Apply the request
                        slave.ApplyRequest(request);
                    }
                    catch (Exception /*ex*/)
                    {
                        //Logger.Error($"Error applying request to slave {slave.UnitId}: {ex.Message}");
                    }
                }
            }
            else
            {
                //Attempt to find a slave for this address
                IModbusSlave slave = GetSlave(request.SlaveAddress);

                // only service requests addressed to our slaves
                if (slave == null)
                {
                    Console.WriteLine($"NModbus Slave Network ignoring request intended for NModbus Slave {request.SlaveAddress}");
                }
                else
                {
                    // perform action
                    return(slave.ApplyRequest(request));
                }
            }

            return(null);
        }